PHP:rand()伪生成的数字对于提供的给定种子总是相同的吗?

时间:2015-12-05 14:50:13

标签: php random number-sequence

我正在使用以下代码生成一系列伪随机数:

$seed = 1;
srand( $seed );
for($i=0; $i<10; $i++)
{
    echo rand(0,100) . "\n";
}
exit(0);

以下代码始终(在我的机器上)输出

84
39
79
[....]
77
28
55

我可以依赖上述代码的输出总是相同的事实吗?

如果没有,有什么可以改变它?

例如,不同版本的PHP会给出不同的结果吗?

或者PHP在不同的操作系统上运行?

2 个答案:

答案 0 :(得分:3)

如果我在Windows上运行此代码,我会获得99,38,79,21,75,91,42,36,47,67的序列。它与所有版本(32位或32位)一致我的Windows框上有64位。

然而,如果我在Linux机器上运行它,无论什么版本的PHP,我都会得到84,39,79,80,92,19,33,77,28,55的序列

因此,操作系统

之间并不一致

但是,如果我使用mt_srand()mt_rand()而不是srand()rand(),那么我确实在Windows / Linux和不同版本的PHP之间建立了从5.2到7.0的一致性

$seed = 1;
mt_srand( $seed );
for($i=0; $i<10; $i++)
{
    echo mt_rand(0,100) . "\n";
}
exit(0);

始终给出58,0,72,94,100,87,70,100,86,76

答案 1 :(得分:1)

在OS或PHP版本之间,随机数之间不能保证相同。因此,最好的选择是创建自己的伪随机数生成器,如本blog post

中所指出的那样

代码如下:

<?php

class Random {

    // random seed
    private static $RSeed = 0;

    // set seed
    public static function seed($s = 0) {
        self::$RSeed = abs(intval($s)) % 9999999 + 1;
        self::num();
    }

    // generate random number
    public static function num($min = 0, $max = 9999999) {
        if (self::$RSeed == 0) self::seed(mt_rand());
        self::$RSeed = (self::$RSeed * 125) % 2796203;
        return self::$RSeed % ($max - $min + 1) + $min;
    }

}

// set seed
Random::seed(42);

// echo 10 numbers between 1 and 100
for ($i = 0; $i < 10; $i++) {
    echo Random::num(1, 100) . ',';
}
echo "\n";

for ($i = 0; $i < 10; $i++) {
    echo Random::num() . ',';
}
echo "\n";

这将导致:

76,86,14,79,73,2,87,43,62,7,
393758,1684299,822150,2105442,337168,202955,203548,277673,1154689,1729772,

显然,您将在不同的PHP版本之间获得一致的结果。请注意,您必须提供一个种子,否则此功能将退回到mt_rand上,然后您再次受操作系统的约束!