在 php 中是 rand() 时间相关的


Is rand() time-dependent in php?

让我们解释一下我的意思。

前段时间,在用 c# 编写程序时,我犯了以下错误:

int Randomize()
{
    Random r=new Random();
    return  r.Next(0,10);
}

在 C# 中,这是一个错误,因为连续调用多次,此函数将返回相同的值。这是因为随机构造函数使用时间种子,并且调用之间的时间差太低(我花了一小时才找到那个:))。

现在我在 php 中使用 rand(...),即使同时执行 2 个脚本,我也需要输出始终不同。

我是否必须做点什么才能获得此结果,或者它是否设计为以这种方式工作?

rand()mt_rand()调用srand()mt_srand()以产生始终随机的结果。但这里有一篇关于 php.net 的有趣帖子:

请注意,自动种子设定似乎是用当前的 秒数,这意味着您可以在多个时间内获得相同的结果 在快速服务器上运行。 要么自己调用 srand() 与 更多 经常更换种子或使用似乎没有的 mt_rand() 遭受问题。

因此,只需更频繁地拨打srandmt_rand

关于mt_rand()函数...

从 http://php.net/manual/en/function.mt-srand.php

从 PHP 4.2.0 开始,不需要用 srand() 或 mt_srand() 为随机数生成器播种,因为这现在是自动完成的。

(对于 PHP 5.2.1)PHP 中的 Mersenne Twister 实现现在使用了 Richard Wagner 的新种子算法。相同的种子不再产生与以前版本中相同的值序列。预计此行为不会再次更改,但仍然认为依赖它是不安全的。

这是链接,描述了"Mersenne Twister(MT)"伪随机数生成算法(以及 C、C++、C# 中的实现)

在这里,您可以在 PHP 5 中找到此函数的实现

php_rand.h中,我发现了这个:

#ifdef PHP_WIN32
#define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#else
#define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#endif

所以现在你可以看到,PHP 中的随机函数依赖于time函数......