PHP SourceCode随机

时间:2017-05-13 19:57:13

标签: php random

rand()的功能应该类似于(SEED * A + C) mod M

如何找到ACM的值?如果我找到这些值,我可以预测序列中的下一个数字吗?

我知道我可以在PHP源代码中找到这些变量的值。但环顾四周之后,我真的找不到它们......

有人知道它会是什么文件吗?或者我可以联系的其他人(我已经尝试过电子邮件 internals@lists.php.net 但是没有得到回复)

此外,我在7之前的PHP版本中完成了所有这些操作,其中rand()mt_rand()成为同义词。

编辑:我看过有可能在PHP中预测rand(0,10)吗?但这些答案并不是关于PHP的rand()值中的常量值。

谢谢!

1 个答案:

答案 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生成器。