I would like to use php to create a collection of random bridge hands. I thought that I could encode an ordered pack of cards as the string $deal
below (I like it that there are 52 letters when considering both upper and lower case). I discovered the php function str_shuffle
. So I thought that I could do the following:
$pack = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$shuffledPack = str_shuffle($pack);
This gives me the desired output.
My question is: does str_shuffle
give output that follows a uniform distribution for each and every possible permutation?
Internally, str_shuffle()
uses rand()
which doesn't produce good quality random numbers as you can see in this answer; if you want a better distribution, you may wish to implement Fisher-Yates yourself and pick a random source of your choice, e.g. 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;
}
See also my earlier answer on finding a suitable 0/1 randomiser.
Using openssl_random_pseudo_bytes()
as your random source:
assert($n_left <= 255);
$random = openssl_random_pseudo_bytes($n_left);
while (--$n_left) {
$rnd_index = round($random[$n_left] / 255 * $n_left);
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With