16

我有一个脚本,我在 PHP 中使用 rand 函数。现在我读了一些鬼故事,它们真的很容易预测这些结果。这可以从客户端进行吗?

例如,假设我们有一个rand(0,10). 是否可以预测下一个数字?

4

6 回答 6

36

rand()函数返回一个伪随机数。这并不意味着next可以预测数字。然而这张图片可以解释单词的概念pseudorandom

兰特

你可以阅读这篇文章

该图像是从一个简单的循环生成的,具有randWindows 系统上的功能。

header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512) or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y = 0; $y < 512; $y++) {
    for ($x = 0; $x < 512; $x++) {
        if (rand(0, 1)) {
            imagesetpixel($im, $x, $y, $white); 
        } 
    } 
} 
imagepng($im); imagedestroy($im);

这不是那么随机,真的吗?但是现在你知道了……你可以预测下一个数字吗?

真随机数生成器 (TRNG) 和伪随机数生成器 (PRNG) 的区别在于,TRNG 使用不可预测的物理方式生成数字(如大气噪声),而 PRNG 使用数学算法(完全由计算机生成)

[...]

没有多少 PRNG 会产生像这样明显的视觉模式,它恰好是语言 (PHP)、操作系统 (Windows) 和函数 (rand()) 的非常糟糕的组合。

于 2012-10-04T14:35:22.110 回答
7

您必须暴力破解 PRNG 的状态。http://crypto.di.uoa.gr/CRYPTO.SEC/Randomness_Attacks_files/paper.pdf

PHP 的 rand() 使用底层标准库实现,这因操作系统而异。

所以第一步,定义操作系统。

下一步,获取 Rand() 函数的源代码和种子代码。

为简单起见,我们假设 PRNG 的种子类似于服务器的毫秒时间。因此,HTTP 请求进来,PHP 播种 PRNG 并执行 rand(0,10)。如果你想预测你会...

  • 将客户端的时钟与服务器的时钟同步,从统计上推导出向服务器发送 HTTP 请求并读取带有时间戳的响应 HTTP 标头的确切时间。

  • 使用您将从服务器请求 rand(0,10) 的预测未来时间播种您的客户端 PRNG(与服务器的实现相同)。在客户端运行 rand(0,10),在确切的未来时间将请求发送到服务器,结果将是相同的。

  • Ping 时间、处理时间等使这成为一种相当蛮力的方法。

真的,通过互联网(不能直接访问服务器),你不会很幸运地预测 PHP 的 rand() 函数的结果。

于 2012-10-04T14:49:17.797 回答
1

兰德手册

介于 min(或 0)和 max(或 getrandmax(),包括)之间的伪随机值。

所以,随机不是随机的,而是伪随机的。如果您知道计算是如何完成的,并且知道初始值,则可以预测(计算)下一个值。

如果您需要真正的随机值,则需要其他算法。例如,基于白噪声

于 2012-10-04T14:28:12.873 回答
1

返回的值rand()只是一个伪随机值。

这意味着,如果您可以访问机器,也许可以计算出这个数字,但这仍然不太可能发生。只看到 PHP 的输出而无法访问机器的最终用户无法选择计算或预测下一个值。一个php脚本的一次执行中的多个rand()调用的输出可能*技术上*是可预测的,但这不能被使用,因为用户只看到一个整体执行的输出没有机会在PHP脚本执行时进行交互.

这是用于生成 PHP 种子的过程rand()

#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 开始4.2.0The random number generator is seeded automatically.

于 2012-10-04T14:37:10.637 回答
0

我认为您可能想要区分安全和足够安全。关于预测的问题的答案是“是的”,可以预测从伪随机数生成器生成的数字。但是,我认为更重要的问题是这种情况发生的可能性有多大。你想保护什么免受预测?如果您运行的是大型在线游戏网站,那么拥有真正的随机性可能比运行小型 MUD 服务器更重要。它更重要,因为用户破坏模式的后果更严重,并且用户更有可能有动机花时间攻击您的算法。

您可能还想查看 Random.org 的服务。他们提供了一个 API,允许您从他们的服务器中提取真正的随机数。它们从大气噪声中获取熵,至少就您的用户而言,这应该是不可预测的。

http://www.random.org/clients/http/

于 2012-10-04T15:00:50.510 回答
-3

不要相信这些鬼故事。对于 webapps,预测是不可能的,下一个数字不能从客户端确定。

为什么?

因为随机数生成器是在每个请求之前播种的,客户端看不到种子值!只有在同一请求中生成所有数字时,预测才有效。

  • 许多数字的行不会是真正随机的
  • 下一个数字(在以下 http 请求中)无法从客户端确定
于 2012-10-04T14:35:25.507 回答