我必须生成大量唯一键。一个密钥应由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
。
然后我决定生成10000个密钥,看看我得到了多少重复:
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个密钥也没有重复。
答案 0 :(得分:1)
在那里扔一些uniquid()。
答案 1 :(得分:1)
答案 2 :(得分:0)
这可能与srand的行为有关。检查重复项时,您只对所有10000个键运行一次srand。也许srand只产生足够的~2 ^ 13键?您使用的是什么PHP版本?因为不再需要4.2.0 srand,但是如果你无论如何都要调用它,它会自动停止为脚本的其余部分执行它。