22

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

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

我用它做了一个小测试:

$i = 0;

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

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

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

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

4

6 回答 6

22

添加、相乘或截断较差的随机源会给您带来较差的随机结果。有关解释,请参阅随机性和随机数简介

你对 PHP rand() 函数是正确的。请参阅统计分析中的第二张图以获取醒目的说明。(第一个数字很引人注目,但它是由 Scott Adams 绘制的,不是用 rand() 绘制的)。

一种解决方案是使用真正的随机生成器,例如random.org。另一个,如果你在 Linux/BSD/etc 上。是使用/dev/random。如果随机性是关键任务,您将不得不使用硬件随机生成器

于 2008-08-08T11:48:42.400 回答
5

random.org有一个可以通过 HTTP 访问的 API。

RANDOM.ORG 是一个真正的随机数服务,它通过大气噪​​声产生随机性。

于 2008-08-08T12:27:05.817 回答
4

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

Fourmilab有关于随机性的好文章,包括另一个真正的随机生成器。也许您可以从两个站点获取随机数据,因此如果一个站点出现故障,您仍然拥有另一个站点。

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

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

无论如何,您需要的随机性取决于您的应用程序。rand() 可以用于在线游戏,但不能用于密码学(任何未经统计程序彻底测试的东西都不适用于密码学)。你当法官!

于 2008-08-08T20:09:42.217 回答
2

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

于 2008-08-08T04:48:14.203 回答
2

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

PHP 5.3 及以上版本

openssl_random_pseudo_bytes(...)

或者您可以使用 RFC4122尝试以下

于 2013-09-18T08:59:40.600 回答
1

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

int random_int ( int $min , int $max )

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

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

于 2015-07-16T03:27:28.700 回答