rand()
的功能应该类似于(SEED * A + C) mod M
。
如何找到A
,C
和M
的值?如果我找到这些值,我可以预测序列中的下一个数字吗?
我知道我可以在PHP源代码中找到这些变量的值。但环顾四周之后,我真的找不到它们......
有人知道它会是什么文件吗?或者我可以联系的其他人(我已经尝试过电子邮件 internals@lists.php.net 但是没有得到回复)
此外,我在7之前的PHP版本中完成了所有这些操作,其中rand()
和mt_rand()
成为同义词。
谢谢!
答案 0 :(得分:0)
我认为旧学校rand()
功能使用了linear congruential generator。
这generator is system dependent。 glibc采用的一种算法是:
next = next * 1103515245 + 12345;
return next & 0x7fffffff;
所以你有你的常数。当然,状态是'next'的初始值,除非srand()
设置不同,否则为零。
有攻击线性同余的方法;一种可能性 - 最慢,但最容易解释 - 是暴力它。假设您有四个连续值:来自rand()实现的a0,a1,a2,a3。您可以检查将产生相同序列的种子的所有值。
请注意,如果您的a0值是由rand()%7172生成的,那么您的初始种子必须遵守“种子%7172 === a0”的规则。这样可以立即减少蛮力所需的空间,从而按比例加快操作速度。此外,您无需检查所有四个数字。
这将是运行(在PHP中)
的有效效果for ($seed = 0; $seed < MAX_SEED; $seed++) {
srand($seed);
if ($a0 !== [RAND() FORMULA]) return false;
if ($a1 !== [RAND() FORMULA]) return false;
if ($a2 !== [RAND() FORMULA]) return false;
if ($a3 !== [RAND() FORMULA]) return false;
return true;
}
通过检查参考琐碎的C源代码
#include <stdio.h>
int main() {
srand(1);
printf("%ld\n", rand());
}
我确定PHP和C确实共享相同的底层函数(我为srand()列出了不同的值)。
我还发现srand(0)和srand(1)产生相同的结果,这与我的线性模型不一致。
那是因为glibc rand()不是所以是一个简单的线性同余生成器。更多信息here。实际上它是用SO answer引用的,我的代码是旧的TYPE_0生成器。