如何查询 random.random() 使用的种子?

发布于 2024-10-17 14:28:00 字数 211 浏览 4 评论 0原文

有没有办法找出Python使用什么种子来为其随机数生成器提供种子?

我知道我可以指定自己的种子,但我对 Python 管理它感到非常满意。但是,我确实想知道它使用了什么种子,这样如果我喜欢在特定运行中获得的结果,我可以稍后重现该运行。如果我有使用过的种子,那么我就可以。

如果答案是我不能,那么自己生成种子的最佳方法是什么?我希望它们在每次运行时始终不同——我只想知道使用了什么。

Is there any way to find out what seed Python used to seed its random number generator?

I know I can specify my own seed, but I'm quite happy with Python managing it. But, I do want to know what seed it used, so that if I like the results I'm getting in a particular run, I could reproduce that run later. If I had the seed that was used then I could.

If the answer is I can't, then what's the best way to generate a seed myself? I want them to always be different from run to run---I just want to know what was used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

南薇 2024-10-24 14:28:00

无法将自动种子从生成器中取出。我通常会像这样生成种子:

seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)

这种方式是基于时间的,因此每次(手动)运行脚本时都会有所不同,但如果您使用多个生成器,它们将不会仅仅因为创建它们而具有相同的种子几乎同时。

It is not possible to get the automatic seed back out from the generator. I normally generate seeds like this:

seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)

This way it is time-based, so each time you run the script (manually) it will be different, but if you are using multiple generators they won't have the same seed simply because they were created almost simultaneously.

断肠人 2024-10-24 14:28:00

随机数生成器的状态并不总是简单的种子。例如,安全 PRNG 通常具有熵缓冲区,它是更大的数据块。

但是,您可以保存和恢复随机数生成器的整个状态,以便稍后可以重现其结果:

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坚持不懈。

http://docs.python.org/library/random.html#random.getstate

The state of the random number generator isn't always simply a seed. For example, a secure PRNG typically has an entropy buffer, which is a larger block of data.

You can, however, save and restore the entire state of the randon number generator, so you can reproduce its results later on:

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()

The results of getstate can, of course, be pickled if you want to save it persistently.

http://docs.python.org/library/random.html#random.getstate

李白 2024-10-24 14:28:00

您可以子类化 random.Random,以与 python 相同的方式重写 seed() 方法(本例中为 v3.5),但在调用 super() 之前将种子值存储在变量中:

    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

如果您存储/复制巨大的种子值并尝试在另一个会话中使用它,则生成的值将完全相同相同的。

You can subclass the random.Random, rewrite the seed() method the same way python does (v3.5 in this example) but storing seed value in a variable before calling super():

    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

If you test it, a first random value generated with a new seed and a second value generated using the same seed (with the get_seed() method we created) will be equal:

    >>> rnd1 = Random()
    >>> seed = rnd1.get_seed()
    >>> v1 = rnd1.randint(1, 0x260)
    >>> rnd2 = Random(seed)
    >>> v2 = rnd2.randint(1, 0x260)
    >>> v1 == v2
    True

If you store/copy the huge seed value and try using it in another session the value generated will be exactly the same.

那伤。 2024-10-24 14:28:00

由于没有人提到通常您可以用任何编程语言获得的最佳随机样本是通过操作系统生成的,因此我必须提供以下代码:

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 大约相同数量的数字。对我来说最大尺寸。

>>> int.from_bytes(os.urandom(8), byteorder="big")
17520563261454622261
>>> sys.maxsize
9223372036854775807
>>>

Since no one mentioned that usually the best random sample you could get in any programming language is generated through the operating system I have to provide the following code:

random_data = os.urandom(8)
seed = int.from_bytes(random_data, byteorder="big")

this is cryptographically secure.

Source: https://www.quora.com/What-is-the-best-way-to-generate-random-seeds-in-python


with a value 8 it seems to produce around the same number of digits as sys.maxsize for me.

>>> int.from_bytes(os.urandom(8), byteorder="big")
17520563261454622261
>>> sys.maxsize
9223372036854775807
>>>
自在安然 2024-10-24 14:28:00

如果您使用random.seed(None)“设置”种子,则随机发生器将自动作为系统时间的函数进行播种。但是,正如您所观察到的,您无法访问该值。当我想要随机化但仍然知道种子时,我会做什么:

tim = datetime.datetime.now()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)

注意:我更喜欢使用 @Abdallah 提议的 time.time() 的原因是因为这样randseed 是人类的-可读且易于理解,这通常有很大的好处。还可以根据需要添加日期组件甚至微分段。

If you "set" the seed using random.seed(None), the randomizer is automatically seeded as a function the system time. However, you can't access this value, as you observed. What I do when I want to randomize but still know the seed is this:

tim = datetime.datetime.now()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)

note: the reason I prefer this to using time.time() as proposed by @Abdallah is because this way the randseed is human-readable and immediately understandable, which often has big benefits. Date components and even microsegments could also be added as needed.

神经大条 2024-10-24 14:28:00

我想做同样的事情,但我无法获得种子。所以,我想既然种子是由时间产生的。我使用系统时间创建了种子并将其用作种子,所以现在我知道使用了哪个种子。

SEED = int(time.time())
random.seed(SEED)

I wanted to do the same thing but I could not get the seed. So, I thought since the seed is generated from time. I created my seed using the system time and used it as a seed so now I know which seed was used.

SEED = int(time.time())
random.seed(SEED)
梦境 2024-10-24 14:28:00

种子是随机包中的内部变量,用于创建下一个随机数。当请求新号码时,种子也会更新。

如果您想确保每次都有相同的随机数,或者使 i 可配置,我会简单地使用 0 作为种子。

CorelDraw 曾经有一个随机图案生成器,它是用种子初始化的。不同种子的模式差异很大,因此种子是模式的重要配置信息。它应该是您运行的配置选项的一部分。

编辑:正如 ephemient 所指出的,随机数生成器的内部状态可能比种子更复杂,具体取决于其实现。

The seed is an internal variable in the random package which is used to create the next random number. When a new number is requested, the seed is updated, too.

I would simple use 0 as a seed if you want to be sure to have the same random numbers every time, or make i configurable.

CorelDraw once had a random pattern generator, which was initialized with a seed. Patterns varied drastically for different seeds, so the seed was important configuration information of the pattern. It should be part of the config options for your runs.

EDIT: As noted by ephemient, the internal state of a random number generator may be more complex than the seed, depending on its implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文