生成唯一6位代码(Generating unique 6 digit code)

2019-09-02 10:07发布

我生成从以下字符的6位代码。 这些将被用来盖章的贴纸。
他们将在(打印前)的10K以下批次中产生,我不预期会有永远不会超过1-2万总(可能要少得多)。
之后,我生成代码的批次,我会检查的现有代码的MySQL数据库,以确保没有重复。

// exclude problem chars: B8G6I1l0OQDS5Z2

$characters = 'ACEFHJKMNPRTUVWXY4937';

$string = '';

for ($i = 0; $i < 6; $i++) {
    $string .= $characters[rand(0, strlen($characters) - 1)];
}   

return $string;
  1. 这是一个坚实的方法来生成代码?
  2. 将有多少种可能的排列是什么? (从21个字符池6位数字代码)。 对不起数学不是我的强项

Answer 1:

21 ^ 6 = 85766121点的可能性。

使用DB和存储使用的值是坏的。 如果你要假的随机性,你可以使用以下命令:

降低到19个可能的数字和利用的事实,即p阶^ k的群体,其中p为奇素数总是循环。

采取订单7 ^ 19组,使用生成互质数,7 ^ 19(我来接13 ^ 11,你可以选择任何不想7整除)。

然后以下工作:

$previous = 0;

function generator($previous)
{

  $generator = pow(13,11);
  $modulus = pow(7,19); //int might be too small
  $possibleChars = "ACEFHJKMNPRTUVWXY49";

  $previous = ($previous + $generator) % $modulus;
  $output='';
  $temp = $previous;

  for($i = 0; $i < 6; $i++) {
    $output += $possibleChars[$temp % 19];
    $temp = $temp / 19;
  }

  return $output;
}

它会通过所有可能的值周期,看起来有点乱,除非他们去挖掘。 一个更安全的替代办法是乘组,但我已经忘记了我的数学:(



Answer 2:

  • There is a lot of possible combination with or without repetition so your logic would be sufficient
  • Collision would be frequent because you are using rand see str_shuffle and randomness.
  • Change rand to mt_rand
  • Use fast storage like memcached or redis not MySQL when checking

Total Possibility

21 ^ 6 = 85,766,121

85,766,121 should be ok , To add database to this generation try:

Example

$prifix = "stamp.";

$cache = new Memcache();
$cache->addserver("127.0.0.1");

$stamp = myRand(6);
while($cache->get($prifix . $stamp)) {
    $stamp = myRand(6);
}
echo $stamp;

Function Used

function myRand($no, $str = "", $chr = 'ACEFHJKMNPRTUVWXY4937') {
    $length = strlen($chr);
    while($no --) {
        $str .= $chr{mt_rand(0, $length- 1)};
    }
    return $str;
}


Answer 3:

巴巴说,产生上飞的字符串将导致吨碰撞。 越接近你会去已经生成的那些80个百万就越难将成为得到一个可用的字符串

另一个解决方案可以是一次产生所有可能的组合,并且它们中的每存储在数据库中已经与如果行/令牌已经被使用或不标志着一些布尔列字段

然后让他们中的一个

SELECT * FROM tokens WHERE tokenIsUsed = 0 ORDER BY RAND() LIMIT 0,1

然后将其标记为已使用

UPDATE tokens SET tokenIsUsed = 1 WHERE token = ...


Answer 4:

您将有21 ^ 6码= 85个766 121〜8580万码!

要生成所有这些(这将需要一些时间),看看选择回答这个问题: 算法,将采取数字或单词,并找到所有可能的组合 。



Answer 5:

我有同样的问题,我发现非常令人印象深刻的开源解决方案:

http://www.hashids.org/php/

您可以使用它,也很值得看它的源代码,以了解发生了什么引擎盖下发生。



Answer 6:

或者......你可以在MD5编码的用户名+日期时间,并保存到数据库中,这肯定会产生一个唯一的代码;)



文章来源: Generating unique 6 digit code