tags:

views:

101

answers:

8

Hi,

For an ecommerce site I want to generate a random coupon code that looks better than a randomly generated value. It should be a readable coupon-code, all in uppercase with no special characters, only letters (A-Z) and numbers (0-9).

Since people might be reading this out / printing it elsewhere, we need to make this a simple-to-communicate value as well, perhaps 8-10 characters long.

Something like perhaps,

AHS3DJ6BW 
B83JS1HSK

(I typed that, so its not really that random)

A: 

http://webarto.com/35/php-random-string-generator

Here you go.

function randr($j = 8){
$string = "";
    for($i=0;$i < $j;$i++){
        srand((double)microtime()*1234567);
        $x = mt_rand(0,2);
        switch($x){
            case 0:$string.= chr(mt_rand(97,122));break;
            case 1:$string.= chr(mt_rand(65,90));break;
            case 2:$string.= chr(mt_rand(48,57));break;
        }
    }
return strtoupper($string); //to uppercase
}
Webarto
Changed it a bit: switch($x){ case 0:$string.= chr(mt_rand(65,90));break; case 1:$string.= chr(mt_rand(48,57));break; }Time taken for 10000, 1.667200088501 seconds
QAQuest
$x = mt_rand(0,2); > $x = mt_rand(0,1);Because case 2 doesn't exist, I added strtoupper to avoid modifying upper code, in case he wanted to use lowercase :)
Webarto
+6  A: 
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$res = "";
for ($i = 0; $i < 10; $i++) {
    $res .= $chars[mt_rand(0, strlen($chars)-1)];
}

You can optimize this by preallocating the $res string and caching the result of strlen($chars)-1. This is left as an exercise to the reader, since probably you won't be generating thousands of coupons per second.

Artefacto
Now make sure that it never adds more than 4 digits :)
Powertieke
@Power Not a requirement in the question :p
Artefacto
This gives a performance of 0.4421501159668 seconds for 10000
QAQuest
@QAQ I got 0.652 for the unoptimized version and 0.475 for the optimized version for 100 000 (not 10 000). Your computer doesn't seem to be very fast.
Artefacto
Crunching performance in php is terrible... If you want speed, look elsewere...
Powertieke
@Arty - I know, but I was implying that this was the fastest of 'em all! :)
QAQuest
Using a slightly modified version of this - with O 0, I 1 removed.
QAQuest
+2  A: 

Try this:

substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10)
Gumbo
Hi - do I need to do something special to mkae this work?
QAQuest
@QAQuest: No, this code will return a string of ten random alphanumeric characters. If you want it in uppercase, use `strtoupper`.
Gumbo
A: 
function generateCouponCode($length = 8) {
  $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $ret = '';
  for($i = 0; $i < $length; ++$i) {
    $random = str_shuffle($chars);
    $ret .= $random[0];
  }
  return $ret;
}
Yorirou
Does this need something special as well? I can't seem to run it as it is...
QAQuest
And it doesnt seem to do numbers...
QAQuest
You shuffle an entire string just to get the first element?
Artefacto
A: 

you can find a lot of function in php rand manual
http://php.net/manual/en/function.rand.php

i like this one

   <?php
//To Pull 8 Unique Random Values Out Of AlphaNumeric

//removed number 0, capital o, number 1 and small L
//Total: keys = 32, elements = 33
$characters = array(
"A","B","C","D","E","F","G","H","J","K","L","M",
"N","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9");

//make an "empty container" or array for our keys
$keys = array();

//first count of $keys is empty so "1", remaining count is 1-7 = total 8 times
while(count($keys) < 8) {
    //"0" because we use this to FIND ARRAY KEYS which has a 0 value
    //"-1" because were only concerned of number of keys which is 32 not 33
    //count($characters) = 33
    $x = mt_rand(0, count($characters)-1);
    if(!in_array($x, $keys)) {
       $keys[] = $x;
    }
}

foreach($keys as $key){
   $random_chars .= $characters[$key];
}
echo $random_chars;
?>
Haim Evgi
A: 
$length = 9;
$code   = (strtoupper(substr(md5(time()), 0, $length)));
palmic
A: 

Why don't keep it simple?

<?php
    echo strtoupper(uniqid());
?>

Always returns 13 character long uppercased random code.

Otar
This is good... 0.18964600563049 seconds for 10000 . However it doesnt seem to be too random...first 6-8 characters are the same on my machine..
QAQuest
You can extend uniqid() function by adding a prefix parameter: strtoupper(uniqid(substr(sha1(time()), 0, 2)));
Otar
Hmm... not too random actually...
QAQuest
+1  A: 

If there are no security requirements for these, then you don't really need randomly generated codes. I would just use incremental IDs, such as those generated by whatever RDBMS you use. Optionally, if you have different types of coupons, you could prefix the codes with something, e.g.:

CX00019 QZ0001C
CX0001A QZ0001D
CX0001B QZ0001E

Alternately, you could even use dictionary words in the coupon, as such coupon codes are easier to remember and faster for users to type. Companies like Dreamhost use these for their promo codes, e.g.:

Promo60
NoSetupFee
YELLOWGORILLA82

Some of these are obviously human-created (which you might want to have the option of), but they can also be generated using a dictionary list. But even if they are randomly-generated nonsense phrases, the fact that the characters follow a logical pattern still makes it much more user-friendly than something like R7QZ8A92F1. So I would strongly advise against using the latter type of coupon codes just on the basis that they "look cool". Your customers will thank you.

Lèse majesté