更好的随机生成PHP

时间:2008-08-08 03:18:56

标签: php security random

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

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

我用它做了一点测试:

$i = 0;

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

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

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

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

6 个答案:

答案 0 :(得分:21)

添加,增加或截断不良随机源会给您带来糟糕的随机结果。有关说明,请参阅Introduction to Randomness and Random Numbers

你对PHP rand()函数是正确的。请参阅Statistical Analysis上的第二个图,以获得引人注目的插图。 (第一个数字很引人注目,但它是由斯科特·亚当斯绘制的,而不是用兰德()绘制的。)

一种解决方案是使用真正的随机生成器,例如random.org。另一个,如果你在Linux / BSD /等。是使用/dev/random。如果随机性是关键任务,则必须使用hardware random generator

答案 1 :(得分:5)

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

  

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

答案 2 :(得分:4)

我会对随机性的印象持谨慎态度:已经有很多实验,人们会选择较少的随机分布。看起来心灵并不擅长产生或估计随机性。

Fourmilab上有关于随机性的好文章,包括另一个true random generator。也许你可以从这两个站点获得随机数据,所以如果一个人失败了你还有另一个。

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

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

无论如何,您需要的随机性取决于您的应用程序。 rand()对于在线游戏来说没问题,但对于加密技术来说还不行(任何未经统计程序彻底测试的东西都不适合加密)。你是法官!

答案 3 :(得分:2)

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

答案 4 :(得分:2)

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

PHP 5.3及以上版本

openssl_random_pseudo_bytes(...)

或者您可以使用RFC4122

尝试以下library

答案 5 :(得分:1)

新的PHP7有一个功能可以完全满足您的需求:它会生成cryptographically secure pseudo-random integers.

int random_int ( int $min , int $max )
  

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

有关PRNG和CSPRNG的更详细解释(及其差异)以及为什么您的原始方法实际上是一个坏主意,请阅读我的another highly similar answer