Python 中的随机函数预测

Random function prediction in Python

根据Random库的文档,假设开发者没有提供任何seed(None)函数使用系统当前时间作为seed(time.time())。

不幸的是,输出似乎没有反映文档

print(random.randrange(1,10))
a=time.time()
.
.
.
.
random.seed(a)
print(random.randrange(1,10))

上面的代码产生了 2 个不同的输出,所以假设我使用 windows 10(对于那些可能会想到 urandom 供应商方向的人)和 Python 3 我的问题是:

1.Why 上面的代码不会产生相同的输出

2.How我能不能让它产生相同的输出

3.When 我试图在 Random.py 中找到种子分配部分 我在任何地方都找不到 time.time() 分配给 Random.seed 所以如果有人可以参考那部分我将不胜感激

这其实是一个有趣的问题。

首先,连续调用 time.time() 可能会得到相同的结果,但这主要是由于精度。

In [36]: a=time.time(); b=time.time()

In [37]: b-a
Out[37]: 0.0

现在让我们进入问题:

  1. 由于初始种子的生成方式不同,它不会产生相同的输出。如果您查看 seed()random.py 源代码,您会看到它指定
def seed(self, a=None, version=2):
   """Initialize internal state from a seed.
   The only supported seed types are None, int, float,
   str, bytes, and bytearray.
   None or no argument seeds from current time or from an operating
   system specific randomness source if available.

因为没有对 time.time() 的引用,您不能假设它使用它。事实上,您可以查看 the CPython 实现的源代码(如果您了解 C)。如有必要,它有助于保证随机种子的方法之一是:

static void
random_seed_time_pid(RandomObject *self)
{
    _PyTime_t now;
    uint32_t key[5];

    now = _PyTime_GetSystemClock();
    key[0] = (uint32_t)(now & 0xffffffffU);
    key[1] = (uint32_t)(now >> 32);

    key[2] = (uint32_t)getpid();

    now = _PyTime_GetMonotonicClock();
    key[3] = (uint32_t)(now & 0xffffffffU);
    key[4] = (uint32_t)(now >> 32);

    init_by_array(self, key, Py_ARRAY_LENGTH(key));
}

对不同的时钟和进程 ID 进行了多次调用。与 time.time() 无关。而且由于那里的种子生成方式,两个连续的种子几乎不可能相同。

  1. 如果您希望某些东西产生相同的输出,则需要对其进行相同的播种。
In [42]: import random

In [43]: a = time.time()

In [44]: random.seed(a)

In [45]: random.randrange(100)
Out[45]: 98

In [46]: random.randrange(100)
Out[46]: 94

In [47]: random.seed(a)  # Reset

In [48]: random.randrange(100)
Out[48]: 98

但不一定是数字。您可以使用多种不同的选项进行播种。

  1. 希望上面提供的源代码解决了这个问题。