Python种子数

时间:2016-06-20 16:34:36

标签: python random

在用于从种子初始化随机数的文档(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位,几乎肯定会有重复。虽然这不适用于加密,但它仍然是不受欢迎的。

1 个答案:

答案 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 == 2str / bytes,则需要a的SHA512,附加它,然后使用int.from_bytes,生成一个非常大的int并保证至少一个512位种子,即使是非常小的自定义输入。

如下所述,最终结果是种子保证长度至少为624位。