我发现这段PHP代码用于生成随机字符串(字母,字母数字,数字和十六进制)。
<?php
function random($length = 8, $seeds = 'alpha') {
// Possible seeds
$seedings['alpha'] = 'abcdefghijklmnopqrstuvwqyz';
$seedings['numeric'] = '0123456789';
$seedings['alphanum'] = 'abcdefghijklmnopqrstuvwqyz0123456789';
$seedings['hexidec'] = '0123456789abcdef';
// Choose seed
if (isset($seedings[$seeds])) {
$seeds = $seedings[$seeds];
}
// Seed generator
list($usec, $sec) = explode(' ', microtime());
$seed = (float) $sec + ((float) $usec * 100000);
mt_srand($seed);
// Generate
$str = '';
$seeds_count = strlen($seeds);
for ($i = 0; $length > $i; $i++) {
$str .= $seeds{mt_rand(0, $seeds_count - 1)};
}
return $str;
}
?>
如果我使用默认参数运行此函数(因此它生成8个字符串,仅按字母顺序排列)并生成1,000,000个字符串,我认为我的碰撞率会很低:
26^8 = 208,827,064,576
1,000,000 / 208,827,064,576 ~= 0.0004%
实际上,当我在我的机器上运行时,我得到90%的碰撞率!我生成的字符串中只有10%是唯一的。
实际上,它接近10%。生成多组1,000,000个随机字符串,我发现每个集合都生成......
那是什么给出的?显然它与我如何播种mt_srand
,或php如何实现mt_rand
或其他东西有关。
因此...
答案 0 :(得分:3)
除非您知道自己在做什么,否则请不要设置种子:
注意:无需为随机数生成器播种 srand()或mt_srand(),因为这是自动完成的。
以下代码几乎可以获得一组100%的唯一字符串
<?php
function random($length = 8, $charset = 'alpha'){
$list = [
'alpha' => 'abcdefghijklmnopqrstuvwqyz',
'numeric' => '0123456789',
'alphanum' => 'abcdefghijklmnopqrstuvwqyz0123456789',
'hexidec' => '0123456789abcdef'
];
if(!isset($list[$charset])){
trigger_error("Invalid charset '$charset', allowed sets: '".implode(', ', array_keys($list))."'", E_USER_NOTICE);
$charset = 'alpha';
}
$str = '';
$max = strlen($list[$charset]) - 1;
for ($i = 0; $length > $i; $i++) {
$str .= $list[$charset][mt_rand(0, $max)];
}
return $str;
}
$loop = 1000000;
for($i=0;$i<$loop;$i++){
$arr[random()] = true;
}
echo $loop - count($arr), " dupes found in list.";
?>