PHP:对于提供的给定种子,rand() 伪生成的数字是否始终相同?
PHP: are rand() pseudo generated numbers always the same for a given seed supplied?
我正在使用以下代码生成伪随机数序列:
$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 运行 在不同的操作系统上?
如果我 运行 在 Windows 上使用此代码,我会得到一个序列 99、38、79、21、75、91、42、36、47、67。它与所有序列一致我的 Windows 盒子上的版本,32 位或 64 位。
而如果我 运行 它放在 Linux 盒子上,我始终得到 84、39、79、80、92、19、33、77、28、55 的序列,无论如何PHP
的版本
因此操作系统之间不一致
但是,如果我使用 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
无法保证 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
然后您将再次受到 OS 的摆布!
我正在使用以下代码生成伪随机数序列:
$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 运行 在不同的操作系统上?
如果我 运行 在 Windows 上使用此代码,我会得到一个序列 99、38、79、21、75、91、42、36、47、67。它与所有序列一致我的 Windows 盒子上的版本,32 位或 64 位。
而如果我 运行 它放在 Linux 盒子上,我始终得到 84、39、79、80、92、19、33、77、28、55 的序列,无论如何PHP
的版本因此操作系统之间不一致
但是,如果我使用 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
无法保证 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
然后您将再次受到 OS 的摆布!