我有一个脚本,我在PHP中使用rand函数。现在我读了一些鬼故事,它真的很容易预测那些结果。这可能来自客户端吗?
例如,假设我们有rand(0,10)
。是否可以预测下一个数字?
答案 0 :(得分:34)
rand()
函数返回伪随机数。
这并不意味着可以预测next
数字。
但是,此图像可以解释单词pseudorandom
您可以阅读此article
图像是从Windows系统上具有rand
功能的简单循环生成的。
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())的非常糟糕的组合。
答案 1 :(得分: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标头。
为您的客户端PRNG(与服务器的实现方式相同)播种,预测的未来时间将从服务器请求rand(0,10)。在客户端上运行rand(0,10),将请求在确切的将来时间发送到服务器,结果将是相同的。
Ping时间,处理时间等使这成为一种相当强力的方法。
真的,通过互联网(没有直接访问服务器),你不会有太多运气预测PHP的rand()函数的结果。
答案 2 :(得分:1)
来自rand manual:
min(或0)和max(或getrandmax()之间的伪随机值, 包括在内)。
因此,随机不是随机的,而是伪随机的。如果您知道如何完成计算,并且知道初始值,则可以预测(计算)下一个值。
如果您需要真随机值,则需要其他算法。例如,基于白噪声。
答案 3 :(得分:0)
rand()
返回的值只是伪随机值。
这意味着,如果您有权访问该计算机,则可以计算该数字,但这种情况仍然不太可能发生。只看到PHP输出且无法访问机器的最终用户无法计算或预测下一个值。在php脚本的 ONE 执行中,多个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.0
起,The random number generator is seeded automatically.
答案 4 :(得分:0)
我认为您可能希望区分安全性和安全性。关于预测的问题的答案是“是”,可以预测从伪随机数生成器生成的数字。但是,我认为更重要的问题是这种情况发生的可能性。你想要保护什么不受预测的影响?如果您正在运行一个庞大的在线游戏网站,那么拥有真正的随机性可能比运行小型MUD服务器更重要。更重要的是因为用户破坏模式的后果更严重,并且用户有更多的动机花时间攻击您的算法。
您可能还想查看Random.org的服务。它们提供了一个API,允许您从服务器中提取真正的随机数。他们从大气噪声中获取熵,至少就用户而言,这应该是不可预测的。
答案 5 :(得分:-3)
不要相信这些鬼故事。对于webapps,预测是不可能的,并且无法从客户端确定下一个数字。
为什么?
因为随机数生成器在每个请求之前播种,客户端无法看到种子值!仅当所有数字都在同一请求中生成时,预测才有效。