0

我有一个小型内部项目,可以将偶尔的条目插入 MySQL 数据库。我有一个名为“idChar”的列,如果我将它的值设置为使用 62 个可能的长度为 31 的字符的随机生成的字符串。

今天我发现一个新条目恰好与几个月前的条目具有相同的 idChar。我现在在保存之前检查重复条目,但这让我想到了发生这种情况的可能性,我很想知道我生成这些随机密钥的实现是否有缺陷。得到一个副本应该大约是 1 in 62^31 对吧?

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
4

1 回答 1

1

获得重复的几率将根据生日问题计算,因为这就是计算从离散余域产生随机选择的输出的函数的输出的冲突机会的方式。实际上,您想计算在随机选择的选择池中任何两个选择相同的机会。

您还应该完全放弃mt_srand调用,因为它不是必需的,并且它可能提供比 PHP 自动执行的更糟糕的种子。考虑到microtime(至少在我的系统中)的输出就像

0.29574400 1348356024

这意味着您只有 100 万个不同的种子可用,因为浮点数的最后两位数字始终为零,并且(double)microtime()演员完全忽略了秒部分(无论如何这将是一个糟糕的种子)。

假设随机数生成器在使用相同种子播种时产生相同的随机数序列,那么实际上您只有 100 万个可能的随机码而不是 62^31 - 相当减少!幸运的是,据记录,这在 PHP 5.2.1 及以后的版本中不会发生。

于 2012-09-22T23:21:07.693 回答