在用于从种子初始化随机数的文档(python 3.5)中:
random.seed(a =无,版本= 2)
初始化随机数生成器。
如果省略a或None,则使用当前系统时间。如果 随机源由操作系统提供,它们被使用 而不是系统时间(有关详细信息,请参阅os.urandom()函数 可用性)。
如果a是int,则直接使用。
使用版本2(默认值),str,bytes或bytearray对象获取 转换为int并使用其所有位。随着版本1, 而是使用a的hash()。
它没有说明有多少种子。 int通常只有40亿个不同的值,但是pythons包含任意精度:
x = 1
type(x) # <class 'int'>
y = 123456789123456789123456789123456789123456789123456789123456789123456789
type(y) # <class 'int'>
z = x+y
z-y # 1 (no rounding error for a 71 digit number)
他们说所有位都被使用,但这可能意味着这些位用于生成一个正常的32位int的摘要。为什么这很重要?我需要从种子中制作随机图案。反过来,我需要制作随机的模式序列(序列依次有种子)。随机数生成器流将受到“生日攻击”,其中在10万左右之后,如果它只有32位,几乎肯定会有重复。虽然这不适用于加密,但它仍然是不受欢迎的。
答案 0 :(得分:3)
开源的优点是能够简单地用问题查看代码。这是source of random.seed
:
if a is None:
try:
# Seed with enough bytes to span the 19937 bit
# state space for the Mersenne Twister
a = int.from_bytes(_urandom(2500), 'big')
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
if version == 2:
if isinstance(a, (str, bytes, bytearray)):
if isinstance(a, str):
a = a.encode()
a += _sha512(a).digest()
a = int.from_bytes(a, 'big')
super().seed(a)
self.gauss_next = None
您可以看到,如果提供了version == 2
和str
/ bytes
,则需要a
的SHA512,附加它,然后使用int.from_bytes
,生成一个非常大的int并保证至少一个512位种子,即使是非常小的自定义输入。
如下所述,最终结果是种子保证长度至少为624位。