how to query seed used by random.random()?

Question:

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.

UPDATE: yes, I mean random.random()! mistake… [title updated]

Asked By: mix

||

Answers:

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.

Answered By: Zooba

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.

Answered By: Daniel

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

Answered By: Glenn Maynard

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)
Answered By: Abdallah Sobehy

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.

Answered By: Lucas Siqueira

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.

Answered By: Dr. Andrew

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
>>>
Answered By: Charlie Parker
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.