1

我必须生成大量唯一键。一把钥匙应由 16 位数字组成。我想出了以下代码:

function make_seed()
{
    list($usec, $sec) = explode(' ', microtime());
    return (float) $sec + ((float) $usec * 100000);
}
function generate_4_digits(){
    $randval = rand(100, 9999);
    if($randval < 1000){
        $randval = '0'.$randval;
    }
    return (string)$randval;
}
function generate_cdkey(){
    return generate_4_digits() . '-' . generate_4_digits() . '-' . generate_4_digits() . '-' . generate_4_digits();
}


srand(make_seed());
echo generate_cdkey();

结果非常有希望,6114-0461-7825-1604. 然后我决定生成 10 000 个密钥,看看我得到了多少重复项:

srand(make_seed());
$keys = array();
$duplicates = array();
for($i = 0; $i < 10000; $i++){
    $new_key = generate_cdkey();
    if(in_array($new_key, $keys)){
        $duplicates[] = $new_key;
    }
    $keys[] = $new_key;
}
$keys_length = count($keys);
var_dump($duplicates);
echo '<pre>';
for($i = 0; $i < $keys_length; $i++){
    echo $keys[$i] . "\n";
}
echo '</pre>';

在第一次运行时,我得到了1807重复,这非常令人失望。但是对于接下来的每次运行,我都感到非常惊讶,我得到了相同数量的重复项!?当我仔细查看生成的密钥时,我意识到最后一个密钥与第一个1807密钥完全相同。所以我可以在8193没有一个重复的情况下生成?!如此接近 2^13?!我们可以得出结论rand()是否适合生成 maz 2^13 唯一数字?但为什么?

我更改了要使用的代码,mt_rand()即使生成 50 000 个密钥也没有重复。

4

3 回答 3

1

在那里扔一些 uniquid() 。

http://www.php.net/manual/en/function.uniqid.php

于 2012-09-13T22:04:01.813 回答
1

这可能是您正在寻找的更多内容。openssl_random_pseudo_bytes ( int $length [, bool &$crypto_strong ] )

于 2012-09-13T22:06:13.323 回答
0

这可能与 srand 的行为有关。检查重复项时,您只对所有 10000 个键运行一次 srand 。也许 srand 只产生足够的 ~2^13 个键?您使用的是什么 PHP 版本?由于 4.2.0 srand 不再需要,但也许如果你调用它,它会自动停止脚本的其余部分。

于 2012-09-13T21:58:12.193 回答