php 洗牌

标签 php string random permutation shuffle

我想用 php 创建随机桥牌的集合。我认为我可以将一副有序的纸牌编码为下面的字符串 $deal(考虑到大写和小写时,我喜欢它有 52 个字母)。我发现了 php 函数 str_shuffle。所以我想我可以做到以下几点:

$pack = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$shuffledPack = str_shuffle($pack);

这给了我想要的输出。

我的问题是:str_shuffle 是否为每个可能的排列提供遵循均匀分布的输出?

最佳答案

在内部,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);
    // ...
}

关于php 洗牌,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24533869/

相关文章:

Python 在字符串开头匹配 '.\'

python - 当均值已知时,Python 中的随机数生成器

matlab - 如何在没有统计工具箱的情况下从 Gamma 分布中绘制随机数?

php - 在显示之前通过 preg_match 删除图像扩展

php - cURL 请求 URL 中包含空格的 URL .. 怎么办

php - 将字符串转换为 float PHP

java - 找到一个人的推文中最流行的词

Python:为什么 `random.randint(a, b)` 返回一个包含 `b` 的范围?

PHP-curl 比 file_get_content 慢得多

php - PHP 中的 Xor 加密