生成优惠券代码的PHP代码(包含字母和数字的组合)

16
为了在电子商务网站上生成一个好看的随机优惠码,我希望它能比通常的随机码更好看。它应该是可读的优惠码,全部由大写字母和数字(A-Z、0-9)组成,不含任何特殊字符。由于人们可能需要在其他地方将其阅读或打印出来,因此我们需要将其设计为易于传达的值,长度可能为8-10个字符。例如:
AHS3DJ6BW 
B83JS1HSK

(这是我打的,所以它并不是完全随机的)


(相关) http://seancoates.com/blogs/arbitrary-incrementer-in-php - Gordon
4
回答问题的同时,确保记录已使用的密钥,以避免创建重复项! - Stephen
哇 - 谢谢大家!我们能否得到一些关于这些函数的速度估计(或真实数据)?我在Windows机器上尝试了其中一个,它花了大约一秒钟才弹出5! - QAQuest
2
由于您可能需要跟踪结果,以避免创建重复项(如Stephen所建议的),因此您可以预先计算一堆代码并将它们存储在数据库中。然后,您可以获取下一个代码,并将其标记为已使用。这也有助于克服任何速度问题。 - Mike
3
如果这是给人阅读和交流的,你可能希望排除 I1O0 - Joey
谢谢您的评论Johannes Rössel - 那是一个很好的观点! - QAQuest
11个回答

51
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$res = "";
for ($i = 0; $i < 10; $i++) {
    $res .= $chars[mt_rand(0, strlen($chars)-1)];
}
你可以通过预先分配$res字符串和缓存strlen($chars)-1的结果来进行优化。由于你可能不会每秒生成成千上万个礼券,因此这留给读者作为练习。

1
@Power 在这个问题中不是必需的 :p - Artefacto
这个程序在10000次运行中的表现是0.4421501159668秒。 - QAQuest
1
@QAQuest - “去掉 O 0,I 1。” 什么意思? - Pherrymason
这不会导致推荐代码冲突的概率吗? - Abhishek
提议的解决方案提供了36^10 = 3656158440062976个独特的代码。即使您生成数十亿个代码,出现相同代码的机会也非常小 ;) - blackarcanis
显示剩余4条评论

26

试试这个:

substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10)

@QAQuest:不,这段代码将返回一个由十个随机字母数字字符组成的字符串。如果你想要大写,可以使用 strtoupper 函数。 - Gumbo

4
为什么不保持简单?
<?php
    echo strtoupper(uniqid());
?>

始终返回13个字符长的大写随机代码。

这很好...10000次只需要0.18964600563049秒。然而它似乎不太随机...在我的机器上前6-8个字符都是相同的。 - QAQuest
你可以通过添加前缀参数来扩展uniqid()函数:strtoupper(uniqid(substr(sha1(time()), 0, 2))); - Otar

4

您可以使用优惠券代码生成器PHP类文件来生成N个优惠券,它是可定制的,并且具有添加自己的前缀和后缀的各种选项。 简单的 PHP 优惠券代码生成器

例如:coupon::generate(8); // J5BST6NQ


1

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

给你。

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
}

稍作修改: switch($x){ case 0:$string.= chr(mt_rand(65,90));break; case 1:$string.= chr(mt_rand(48,57));break; } 10000次所需时间为1.667200088501秒。 - QAQuest
$x = mt_rand(0,2); > $x = mt_rand(0,1);因为第二种情况不存在,我添加了strtoupper以避免修改上面的代码,以防他想使用小写字母 :) - Dejan Marjanović

1
如果这些内容没有安全要求,那么您实际上不需要随机生成的代码。我会使用增量ID,例如由您使用的任何RDBMS生成的ID。可选地,如果您有不同类型的优惠券,您可以在代码前缀中加入一些内容,例如:
CX00019 QZ0001C
CX0001A QZ0001D
CX0001B QZ0001E

或者,您甚至可以在优惠券中使用字典单词,因为这样的优惠码更容易记忆,用户输入速度更快。像Dreamhost这样的公司就会使用这些促销代码,例如:

Promo60
NoSetupFee
YELLOWGORILLA82

有些明显是人类创建的(你可能想要这个选项),但也可以使用字典列表生成。但即使它们是随机生成的无意义短语,字符遵循逻辑模式的事实仍然使其比如R7QZ8A92F1之类的东西更加用户友好。因此,我强烈建议不要基于“看起来酷”的理由使用后一种类型的优惠码。你的客户会感激你的。

1
$size = 12;

$string = strtoupper(substr(md5(time().rand(10000,99999)), 0, $size));

0

只要写就好了

 $voucher_no =  date('ymd') . rand(1000, 9999);
 while(SapItem::where('voucher_no', $voucher_no)->exists()){
  $voucher_no = date('ymd') . rand(1000, 9999);
 }

输出:2204171447


0
function generateCouponCode($length = 8) {
  $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $ret = '';
  for($i = 0; $i < $length; ++$i) {
    $random = str_shuffle($chars);
    $ret .= $random[0];
  }
  return $ret;
}

1
你打乱整个字符串只是为了获取第一个元素吗? - Artefacto

0

在 PHP 的 rand 手册中,你可以找到很多函数。
http://php.net/manual/en/function.rand.php

我喜欢这个。

   <?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;
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接