我想用php创建随机桥牌手的集合。我以为我可以将一个有序的卡片编码为下面的字符串$deal
(我喜欢在考虑大小写时有52个字母)。我发现了php函数str_shuffle
。所以我认为我可以做到以下几点:
$pack = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$shuffledPack = str_shuffle($pack);
这给了我想要的输出。
我的问题是:str_shuffle
是否为每个可能的排列提供了均匀分布的输出?
答案 0 :(得分:4)
在内部,str_shuffle()
使用的rand()
不会产生高质量的随机数,正如您在this answer中所看到的那样;如果您想要更好的分发,您可能希望自己实施Fisher-Yates并选择您选择的随机来源,例如mt_rand()
:
function my_str_shuffle($str)
{
if ($str == '') {
return $str;
}
$n_left = strlen($str);
while (--$n_left) {
$rnd_idx = mt_rand(0, $n_left);
if ($rnd_idx != $n_left) {
$tmp = $str[$n_left];
$str[$n_left] = $str[$rnd_idx];
$str[$rnd_idx] = $tmp;
}
}
return $str;
}
另见my earlier answer找到合适的0/1随机客户。
使用openssl_random_pseudo_bytes()
作为随机来源:
assert($n_left <= 255);
$random = openssl_random_pseudo_bytes($n_left);
while (--$n_left) {
$rnd_index = round($random[$n_left] / 255 * $n_left);
// ...
}