使用 python 随机数生成时是否值得定期更改种子?

Is it worth changing the seed periodically when using python random number generation?

假设我正在使用 random.randrange 生成 10,000 个随机数,与对所有 10,000 个随机数使用相同的种子相比,在生成循环中部分改变种子对生成的值的分布有任何有意义的差异?

import random 

epoch = int(0)

while True:
    if epoch%100 == 0: #every 100 epochs, generate a new seed
        random.seed()  
    random.randrange(1,1000,1)
    epoch += 1

我最初的想法是不会,因为即使我们知道 python 随机是确定性的,random.randrange(1,1000,1) 的每个连续的 运行 仍然具有相同的权重每个时期的 1000 个可能值。想法?

伪随机数生成器的输出取决于它从当前状态到下一个状态的转换。一个好的生成器将拥有比其种子中的位更多的状态位,因此定期重新播种实际上 增加 序列的可预测性。我知道在一个系统中有一个基于此的实际攻击,其中种子被不必要地限制为少量位。

在不为 a 传递任何值的情况下调用 random.seed,每次都可能导致 fetch state from os.urandom() every time. This might be wasteful as it requests a full 19968 bits, i.e. 624 uint32_ts。因此,如果每次重新播种时只生成 100 个随机变量,secrets.randbelow(999)+1 可能更好。

鉴于 MT19937 的输出可以在 624 variates 之后预测,那么,与 Mark 所说的相反,这确实会使它更难预测。当然,假设您的 OS 正在为 os.urandom 提供合理的 CSRNG,Linux、OSX、Windows 和大多数 BSD 的最新版本是一切顺利。

请注意,MT19937 在这方面尤其糟糕,尤其是考虑到它拥有的状态量,并且有许多发生器做得更好。