Я хотел бы использовать php для создания коллекции случайных мостов. Я думал, что могу кодировать упорядоченный пакет карточек в виде строки $deal
ниже (мне нравится, что при рассмотрении как верхнего, так и нижнего регистра есть 52 буквы). Я обнаружил функцию php str_shuffle
. Поэтому я подумал, что могу сделать следующее:
$pack = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $shuffledPack = str_shuffle($pack);
Это дает мне желаемый результат.
Мой вопрос: str_shuffle
дает результат, который следует за равномерным распределением для каждой возможной перестановки?
Внутри str_shuffle()
использует rand()
который не производит качественные случайные числа, как вы можете видеть в этом ответе ; если вы хотите улучшить распространение, вы можете сами реализовать 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; }
См. Также мой более ранний ответ на поиск подходящего рандомизатора 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); // ... }