【问题标题】:How does MT19937RNG generate a random number less than 32 bit?MT19937RNG如何生成小于32位的随机数?
【发布时间】:2020-02-15 15:51:17
【问题描述】:

我们知道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...,这些数字是从哪里来的?

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

【问题讨论】:

    标签: python random cryptography


    【解决方案1】:

    random.getrandbits(1)的输出变成0,0,0,1...,这些数字是从哪里来的?

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

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

    如果我们只能像1位那样得到小于32位的连续随机数,我们还能破解MT19937RNG吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      相关资源
      最近更新 更多