python - MT19937RNG如何生成小于32位的随机数?

标签 python random cryptography

我们知道python中的random模块使用MT19937来生成32位随机数,例如:

>>> import random
>>> random.seed(123)
>>> random.getrandbits(32)
224899942L
>>> random.getrandbits(32)
1149664691L
>>> random.getrandbits(32)
374463918L
>>> random.getrandbits(32)
3302642556L

当我设置相同的种子时,输出与 MT19937 的输出相同。

但是,如果我想生成一个小于32位的随机数,比如我想用random.getrandbits(1)生成一个1位的随机数,一开始我以为结果只是random.getrandbits(32)&1,但是当我付诸实践时,发现并非如此:

>>> import random
>>> random.seed(123)
>>> random.getrandbits(1)
0L
>>> random.getrandbits(1)
0L
>>> random.getrandbits(1)
0L
>>> random.getrandbits(1)
1L

现在我不知道为什么输出会变成0,0,0,1...,这些数字是从哪里来的?

众所周知,如果我们得到 MT19937RNG 生成的 624 个连续 32 位随机数,我们可以轻松恢复种子并计算任意随机数,但如果我们只能得到小于 32 位的连续随机数,例如1位,我们还能破解MT19937RNG吗?

最佳答案

the output of random.getrandbits(1) become 0,0,0,1..., Where do these numbers come from?

这些是random.getrandbits(32)结果的高位。只要看看source在文件 Modules/_randommodule.c

if (k <= 32)  /* Fast path */
    return PyLong_FromUnsignedLong(genrand_int32(self) >> (32 - k));

if we can only get consecutive random numbers less than 32-bit like 1-bit, can we still break the MT19937RNG?

是的。当然,我们需要 32 倍以上的值。基本上,我们将状态的 19937 位作为未知数,为我们已知的每一位写出这些变量的线性方程,然后求解。

关于python - MT19937RNG如何生成小于32位的随机数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60241612/

相关文章:

python - 在 pandas groupby 对象上重新运行 agg 会修改原始数据帧

PHP 随机字符串生成器比预期更随机

linux - 尽早阅读/dev/urandom

python - 获取长十六进制哈希值

c - 修改 Ext4 文件系统写入磁盘的数据

Python RSA 暴力破解

python - 情感分析管道,使用特征选择时获取正确特征名称的问题

python - 在 Docker 中执行 python 脚本

python - 当我按下空格键时在我的鼠标位置画一个圆圈(Pygame)

javascript随机数使获得某些值的机会更大