Python 如何查询random.random()使用的种子?
有没有办法找到Python用来为随机数生成器设置种子的种子 我知道我可以指定自己的种子,但我很高兴Python能够管理它。但是,我确实想知道它使用了什么种子,这样,如果我喜欢在某个特定的运行中得到的结果,我可以在以后复制该运行。如果我有被使用的种子,那么我可以 如果答案是我做不到,那我自己创造种子的最佳方式是什么?我希望他们总是不同于跑步——我只想知道他们用了什么Python 如何查询random.random()使用的种子?,python,random,seed,Python,Random,Seed,有没有办法找到Python用来为随机数生成器设置种子的种子 我知道我可以指定自己的种子,但我很高兴Python能够管理它。但是,我确实想知道它使用了什么种子,这样,如果我喜欢在某个特定的运行中得到的结果,我可以在以后复制该运行。如果我有被使用的种子,那么我可以 如果答案是我做不到,那我自己创造种子的最佳方式是什么?我希望他们总是不同于跑步——我只想知道他们用了什么 SEED = int(time.time()) random.seed(SEED) 更新:是的,我是说random.random(
SEED = int(time.time())
random.seed(SEED)
更新:是的,我是说random.random()!错误[标题更新]无法从生成器中取出自动种子。我通常会生成这样的种子:
seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)
这种方式是基于时间的,因此每次运行脚本(手动)时都会有所不同,但如果使用多个生成器,它们不会有相同的种子,因为它们几乎是同时创建的。种子是随机包中的一个内部变量,用于创建下一个随机数。当请求新号码时,种子也会更新 如果您希望确保每次都有相同的随机数,或者使I可配置,我将简单地使用0作为种子 CorelDraw曾经有一个随机模式生成器,它是用种子初始化的。不同种子的模式差异很大,因此种子是模式的重要配置信息。它应该是跑步配置选项的一部分
编辑:正如ephemient所指出的,随机数生成器的内部状态可能比种子更复杂,这取决于它的实现 随机数生成器的状态并不总是简单的种子。例如,安全PRNG通常具有熵缓冲区,这是一个较大的数据块 但是,您可以保存并恢复randon number generator的整个状态,以便以后可以重现其结果:
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
的结果可以被pickle
我也想做同样的事情,但我没能得到种子。所以,我想既然种子是从时间中产生的。我使用系统时间创建了我的种子,并将其用作种子,因此现在我知道使用了哪个种子
SEED = int(time.time())
random.seed(SEED)
您可以将random.random子类化,像python那样重写seed()方法(本例中为v3.5),但在调用super()之前将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.seed(None)
来“设置”种子,则随机化器将自动作为系统时间的函数进行种子设定。但是,正如您所观察到的,您无法访问此值。当我想随机化,但仍然知道种子时,我会这样做:
tim = datetime.datetime.now()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)
注意:我之所以喜欢使用@Abdallah建议的
time.time()
,是因为这样randseed就可以让人可读,并且可以立即理解,这通常有很大的好处。还可以根据需要添加日期组件甚至微段。因为没有人提到任何编程语言中的最佳随机样本通常是通过操作系统生成的,所以我必须提供以下代码:
random_data = os.urandom(8)
seed = int.from_bytes(random_data, byteorder="big")
这是加密安全的
资料来源:
值为8时,它产生的位数似乎与我的sys.maxsize差不多
>>> int.from_bytes(os.urandom(8), byteorder="big")
17520563261454622261
>>> sys.maxsize
9223372036854775807
>>>
什么是
math.random()
?你的意思是?因为取回原始种子并不容易,我只需要自己从操作系统中生成一个,例如,seed=int.from_bytes(os.uradom(8),byteorder=“big”)
种子实际上用于创建生成器的内部状态。碰巧有许多状态是通过调用random()
实现的,但不能直接作为种子设定的结果。所以说种子是一个内部变量是不准确的-它只是种子的初始状态。哦,我认为种子的长度意味着可能的内部状态的长度。感谢您的更正。默认情况下,PRNG是从操作系统的PRNG自动播种的(通过OS.urandom
),因此这几乎总是不必要的。@Glenn Maynard,除非您想知道种子是什么,以便以后可以复制生成的序列。Python缺少random.getseed()
,但这比Python3+中使用sys.maxsize的痛苦要小得多removed@CharlieParker在看到Brendan的评论后,我更新了我的答案,这就是为什么答案中写着maxsize
。以前它使用的maxint
不会复制序列,它只允许您从上次停止的地方继续。如果要从头开始复制整个序列,需要知道种子值。@Zooba:这些值是等效的。要从tart复制整个序列,只需在该点存储PRNG的状态。鉴于问题的上下文(每次运行种子设定可选),存储相对较大的状态元组远远不是最优的。单个种子值更容易嵌入到配置数据中,如果您需要安全的PRNG,您不应该保存种子(或状态)。这在技术上是正确的,但Zooba的方法对于OP来说更为用户友好。@smci:他的方法毫无必要地不安全,大量减少可用的随机性。(不应该存储安全PRNG的状态的想法是胡说八道——你也可以说不应该为HTTPS服务器存储私钥。)没有多少人欣赏这种方法。这一解释令人震惊。