我有一个小型的内部项目,可以将偶尔的条目插入到MySQL数据库中。我有一个名为“idChar”的列,我将它的值设置为使用62个长度为31的可能字符随机生成的字符串。
今天我发现一个新条目碰巧与几个月前的条目具有相同的idChar。我现在正在检查重复的条目,然后保存它们,但这让我想到了这种情况发生的可能性,我很想知道生成这些随机密钥的实现是否有缺陷。获得重复应该大约是62 ^ 31中的1?
function getCode($len)
{
//$len = 10;
$base='ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz123456789';
$max=strlen($base)-1;
$linkCode='';
mt_srand((double)microtime()*1000000);
while (strlen($linkCode)<$len+1)
$linkCode.=$base{mt_rand(0,$max)};
return $linkCode;
}
$idChar=getCode(30);
//code to insert into MySQL here
答案 0 :(得分:1)
获得重复的几率将根据birthday problem计算,因为这就是calculate the chance of collisions对于从离散codomain产生随机选择的输出的函数输出的方式。实际上,您想要计算随机选择池中任意两个选项相同的机会。
你也应该完全放弃mt_srand
调用,因为它没有必要,并且它可能提供比PHP自动执行的更糟糕的种子。考虑microtime
的输出(至少在我的系统中)就像
0.29574400 1348356024
这意味着你只有100万个不同的种子可用,因为float的最后两位数字总是为零而(double)microtime()
强制转换完全忽略了秒部分(无论如何它都是一个糟糕的种子)。
假设随机数生成器生成相同的随机数序列,只要它用相同的种子播种,那么实际你只有100万个可能的随机数而不是62 ^ 31 - 相当减少!幸运的是,在PHP 5.2.1之后记录了this does not happen。