有没有办法找出Python用来生成随机数的种子?
我知道我可以指定自己的种子,但我很满意Python管理它。但是,我想知道它使用了什么种子,这样如果我喜欢在特定运行中得到的结果,我可以在以后再次重现该运行。如果我有当时使用的种子,那就好了。
如果答案是否定的,那么生成种子的最佳方法是什么?我希望它们在每次运行时都不同——我只想知道使用了什么种子。
无法从生成器中恢复自动生成的种子。我通常会像这样生成种子:
seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)
这样它是基于时间的,因此每次您手动运行脚本时都会有所不同,但如果您使用多个生成器,则它们不会具有相同的种子,只是因为它们几乎同时创建。
os.urandom
)自动进行种子生成,因此几乎总是不需要手动设置种子。 - Glenn Maynardmaxsize
。之前它使用的是 maxint
。 - Zooba随机数生成器的状态并不总是简单的种子。例如,安全的伪随机数生成器通常具有熵缓冲区,它是一个较大的数据块。
然而,您可以保存和恢复整个随机数生成器的状态,以便以后可以再现其结果:
import random
old_state = random.getstate()
print random.random()
random.setstate(old_state)
print random.random()
# You can also restore the state into your own instance of the PRNG, to avoid
# thread-safety issues from using the default, global instance.
prng = random.Random()
prng.setstate(old_state)
print prng.random()
如果您想永久保存它,那么当然可以将getstate
的结果序列化(pickled)。
import random
class Random(random.Random):
def seed(self, a=None, version=2):
from os import urandom as _urandom
from hashlib import sha512 as _sha512
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')
self._current_seed = a
super().seed(a)
def get_seed(self):
return self._current_seed
如果您进行测试,使用新种子生成的第一个随机值和使用相同种子(使用我们创建的get_seed()方法)生成的第二个值将相等: >>> rnd1 = Random()
>>> seed = rnd1.get_seed()
>>> v1 = rnd1.randint(1, 0x260)
>>> rnd2 = Random(seed)
>>> v2 = rnd2.randint(1, 0x260)
>>> v1 == v2
True
如果您存储/复制了庞大的种子值,并尝试在另一个会话中使用它,则生成的值将完全相同。由于没有人提到,通常在任何编程语言中获得的最佳随机样本是通过操作系统生成的,因此我必须提供以下代码:
random_data = os.urandom(8)
seed = int.from_bytes(random_data, byteorder="big")
这是加密安全的。
来源:https://www.quora.com/What-is-the-best-way-to-generate-random-seeds-in-python
对于我而言,当值为8时,它似乎会产生与sys.maxsize
差不多数量的数字。
>>> int.from_bytes(os.urandom(8), byteorder="big")
17520563261454622261
>>> sys.maxsize
9223372036854775807
>>>
random.seed(None)
来"设置"种子,随机生成器会自动作为系统时间的一个函数进行播种。但是,正如您所观察到的,您无法访问此值。当我想要随机化但仍然知道种子时,我通常会这样做:tim = datetime.datetime.now()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)
注意: 我之所以更喜欢这种方法而不是使用@Abdallah提出的time.time()
,是因为这种方法生成的随机种子是人类可读的,并且可以立即理解,这通常有很大的好处。日期组件甚至微秒级别的组件也可以根据需要添加。
我也想做同样的事情,但我无法得到种子。所以,我想既然种子是从时间生成的,我就使用系统时间创建了我的种子,并将其用作种子,这样我就知道使用了哪个种子。
SEED = int(time.time())
random.seed(SEED)
math.random()
是什么?你是指random.random()
吗? - ephemientseed = int.from_bytes(os.urandom(8), byteorder="big")
。 - Charlie Parker