我知道只需使用 rand() 如果您知道自己在做什么并且可以访问服务器,那么这是可以预测的。

我有一个项目是 高度 取决于选择一个尽可能不可预测的随机数。所以我正在寻找建议,无论是其他内置函数还是用户函数,都可以生成 更好的 随机数。

我用它做了一个小测试:

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

我发现结果是均匀分布的,并且每个数字的生成次数有一个奇怪的模式。

有帮助吗?

解决方案

添加、相乘或截断较差的随机源将会得到较差的随机结果。看 随机性和随机数简介 以获得解释。

你对 PHP rand() 函数的看法是正确的。参见第二张图 统计分析 一个引人注目的例子。(第一个图很引人注目,但它是由 Scott Adams 绘制的,而不是用 rand() 绘制的)。

一种解决方案是使用真正的随机生成器,例如 随机组织. 。另一个,如果你使用的是 Linux/BSD/etc。是使用 /dev/随机. 。如果随机性对任务至关重要,则必须使用 硬件随机发生器.

其他提示

随机组织 有一个可以通过 HTTP 访问的 API。

Random.org是一种真正的随机数服务,可通过大气噪​​声产生随机性。

我会对随机性的印象保持警惕:已经有很多实验表明人们会选择随机性较小的分布。大脑似乎不太擅长产生或估计随机性。

有关于随机性的好文章 富米实验室, ,包括另一个 真随机发生器. 。也许您可以从两个站点获取随机数据,这样如果其中一个站点出现故障,您仍然可以使用另一个站点。

Fourmilab 还提供 测试程序 检查随机性。您可以使用它来检查各种 myRand() 程序。

至于你的最后一个程序,如果你生成10000个值,为什么不在这10000个值中选择最终值呢?你将自己限制在一个子集内。另外,如果您的 $min 和 $max 大于 10000,它将不起作用。

无论如何,您需要的随机性取决于您的应用程序。rand() 对于在线游戏来说是可以的,但对于密码学来说就不行了(任何没有经过统计程序彻底测试的东西无论如何都不适合密码学)。你来当法官吧!

@KG 的变化,使用自 EPOCH 以来的毫秒数作为兰特的种子?

另一种获取随机数的方法,概念上与获取 UUID 类似

PHP 5.3 及以上版本

openssl_random_pseudo_bytes(...)

或者您可以尝试以下操作 图书馆 使用 RFC4122

一个新的 PHP7 有一个函数可以完全满足您的需要:它产生 加密安全的伪随机整数。

int random_int ( int $min , int $max )

生成适用于无偏见结果至关重要的密码随机整数(即洗牌扑克牌)。

有关 PRNG 和 CSPRNG(及其区别)的更详细解释以及为什么您最初的方法实际上是一个坏主意,请阅读我的 另一个高度相似的答案.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top