pythonrandom设置种⼦_关于python:如何查询
random.random()。。。
有没有办法出python⽤来给随机数⽣成器种⼦的种⼦是什么?
我知道我可以指定我⾃⼰的种⼦,但是我很满意Python管理它。但是,我确实想知道它使⽤了什么种⼦,这样如果我喜欢在特定运⾏中得到的结果,我可以稍后复制该运⾏。如果我有使⽤过的种⼦,我可以。
如果答案是我做不到,那我⾃⼰种下种⼦的最好⽅法是什么?我想让他们从⼀个跑步到另⼀个跑步,我只想知道使⽤了什么。
更新:是的,我的意思是随机。随机()!错误…[更新标题]
什么是math.random()?你是说random.random()吗?
因为要把原始种⼦取回来并不容易,所以我只需要⾃⼰从操作系统中⽣成⼀个,例如seed = int.from_bytes(os.urandom(8),
byteorder="big")。
⽆法从发电机中取出⾃动种⼦。我通常会产⽣这样的种⼦:
seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)
这样,它是基于时间的,所以每次运⾏脚本(⼿动)时都会有所不同,但是如果使⽤多个⽣成器,它们将不会有相同的种⼦,因为它们⼏乎是同时创建的。
默认情况下,prng是从操作系统的prng中⾃动播种的(通过os.urandom),因此这⼏乎总是不必要的。
@格伦·梅纳德,除⾮你想知道种⼦是什么样的,这样你以后就能复制产⽣的序列。
Python缺乏EDOCX1,1,但这⽐在⽖哇相当痛苦。
在python3+中,使⽤sys.maxsize,因为已删除sys.maxint
你的播种⽅式与:seed = ord(os.urandom(1))相⽐如何?
@Brendanmaguire你在说什么,你可以使⽤sys.maxsize,据我在python中所说,Python 3.6.3 |Anaconda custom (64-bit)| (default, Nov 3 2017, 19:19:16)可以使⽤sys.maxsize 9223372036854775807。
@查理帕克,我在看到布兰登的评论后更新了我的答案,这就是为什么答案中说是maxsize。以前⽤过maxint。
随机数⽣成器的状态并不总是简单的种⼦。例如,安全prng通常有⼀个熵缓冲区,这是⼀个更⼤的数据块。
但是,您可以保存和恢复Randon数字⽣成器的整个状态,以便稍后可以复制其结果:
import random
old_state = state()
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的结果可以被腌制。
这不会重现⼀个序列,只会让你从上次停⽌的地⽅继续。如果您想从⼀开始就复制整个序列,您需要知道seed值。
@祖巴:这些是等效的。要从tart复制整个序列,只需在该点存储prng的状态。
考虑到问题的上下⽂(可选的每次运⾏种⼦设定),存储相对较⼤的状态元组远不是最佳的。单个种⼦值更容易嵌⼊到配置数据中,如果需要安全的prng,则⽆论如何都不应该保存种⼦(或状态)。
这在技术上是正确的,但Zooba的⽅法对于OP的⽬的来说更加⽤户友好。
@他的⽅法不必要地缺乏安全感,⼤⼤减少了随机性。(不应该存储安全prng的状态的想法是胡说⼋道的——你也可以说不应该存储https服务器的私钥。)
@格伦:哦,好的。当时我的评论是错误的。
您可以将random.random⼦类化,以与python相同的⽅式重写seed()⽅法(在本例中为v3.5),但在调⽤super()之前将seed值存储在变量中:
import random
random在python中的意思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 = _seed()
>>> v1 = rnd1.randint(1, 0x260)
>>> rnd2 = Random(seed)
>>> v2 = rnd2.randint(1, 0x260)
>>> v1 == v2
True
如果您存储/复制巨⼤的种⼦值并尝试在另⼀个会话中使⽤它,则⽣成的值将完全相同。
没有多少⼈欣赏这种⽅法。这个解释太离谱了。
如果使⽤random.seed(None)来"设置"种⼦,随机化器将⾃动作为系统时间的函数进⾏种⼦设定。但是,正如您观察到的,您不能访问这个值。当我想随机化但仍然知道种⼦是这样的时候,我要做的是:
tim = w()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)
注:我之所以喜欢使⽤@abdallah提出的time.time(),是因为通过这种⽅式,randseed具有⼈类可读性和可⽴即理解性,这通常有很⼤的好处。还可以根据需要添加⽇期组件甚⾄微段。
我也想做同样的事,但我得不到种⼦。所以,我想,因为种⼦是由时间产⽣的。我使⽤系统时间创建了我的种⼦,并将其⽤作种⼦,所以现在我知道使⽤了哪个种⼦。
SEED = int(time.time())
random.seed(SEED)
由于没有⼈提到,在任何编程语⾔中通常可以获得的最佳随机样本是通过操作系统⽣成的,因此我必须提供以下代码:
random_data = os.urandom(8)
seed = int.from_bytes(random_data, byteorder="big")
这在密码学上是安全的。