使用Python的随机模块是否有可预测的替代os.urandom?

时间:2016-05-20 21:47:36

标签: python-3.x random

我希望将 n 随机字节作为字节数组或字节,如os.urandom那样。

但是我需要能够设置一个随机种子,因此该值是可重现的。

def urandom_from_random(rng, length):
    return bytes([rng.randint(0, 255) for i in range(length)])

import random
rng = random.Random(42)
data = urandom_from_random(rng, 120)
print(data)

上面的脚本有效,但效率不高。

除了创建多个整数并将它们转换为字节之外,还有更直接的方法吗?

注意:

3 个答案:

答案 0 :(得分:3)

我认为random中最接近你想要的函数是getrandbits。它返回一个带有请求位数的整数。如果您想将其转换为bytes个实例,可以使用int.to_bytes

这是一个将这两者结合在一起的快速功能:

def urandom_from_random(rng, length):
    if length == 0:
        return b''
    integer = rng.getrandbits(length * 8)
    result = integer.to_bytes(length, sys.byteorder)
    return result

您指定给to_bytes的字节顺序无关紧要。我告诉它使用系统的本机字节顺序,但我实际上并不知道这是否使它比其它方式更快。<​​/ p>

答案 1 :(得分:0)

在代码开头使用种子:

import random
random.seed(7)
rng = random.Random(42)
data = urandom_from_random(rng, 120)

只要你在种子中使用7,就会有相同的随机选择。然后你可以把它改成任何值。

答案 2 :(得分:0)

这是@ Blckknght的答案的修改版本,其中考虑了INT_MAX中的内部getrandbits限制。

def urandom_from_random(rng, length):
    if length == 0:
        return b''

    import sys
    chunk_size = 65535
    chunks = []
    while length >= chunk_size:
        chunks.append(rng.getrandbits(
                chunk_size * 8).to_bytes(chunk_size, sys.byteorder))
        length -= chunk_size
    if length:
        chunks.append(rng.getrandbits(
                length * 8).to_bytes(length, sys.byteorder))
    result = b''.join(chunks)
    return result

使用示例:

import random 
rng = random.Random(42)
print(len(urandom_from_random(rng, 300000000)))