我正在从以下字符生成一个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;
这是生成代码的可靠方法吗?
有多少可能的排列?(来自21个字符的池中的6位数字代码).对不起数学不是我的强项
Jean-Bernard.. 12
21 ^ 6 = 85766121种可能性.
使用DB并存储使用的值很糟糕.如果您想伪造随机性,可以使用以下内容:
减少到19个可能的数字,并利用p为奇数素数的p ^ k组总是循环的事实.
取7 ^ 19的顺序组,使用生成器co-prime到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; }
它会循环遍历所有可能的值,看起来有点随机,除非他们去挖掘.一个更安全的替代方案是乘法组,但我已经忘记了我的数学:(
21 ^ 6 = 85766121种可能性.
使用DB并存储使用的值很糟糕.如果您想伪造随机性,可以使用以下内容:
减少到19个可能的数字,并利用p为奇数素数的p ^ k组总是循环的事实.
取7 ^ 19的顺序组,使用生成器co-prime到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; }
它会循环遍历所有可能的值,看起来有点随机,除非他们去挖掘.一个更安全的替代方案是乘法组,但我已经忘记了我的数学:(
有或没有重复有很多可能的组合,所以你的逻辑就足够了
碰撞会很频繁,因为你使用的是rand
看str_shuffle和随机性.
更改rand
到mt_rand
检查时使用快速存储,memcached
无论redis
是否使用MySQL
总可能性
21 ^ 6 = 85,766,121
85,766,121
应该没问题,要将数据库添加到这一代,请尝试:
例
$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 myRand($no, $str = "", $chr = 'ACEFHJKMNPRTUVWXY4937') { $length = strlen($chr); while($no --) { $str .= $chr{mt_rand(0, $length- 1)}; } return $str; }