Puzzled about random initialisation

Tim Peters tim.peters at gmail.com
Thu Jul 8 23:00:12 CEST 2004


[Robin Becker]
> We've been queried about the randomness of some filenames we're producing.
> I worked through and seemed to satisfy myself that random is being initialised
> from the system time in C
>        time(&now)
>        init_genrand(self, (unsigned long)now);
> 
> where now is a time expressed in integral seconds since the eopoch.

If you were calling the C code directly, that would be relevant.  But
you're not, Instead you're using the default instance of the Random
class Python creates for you, with the initialization *it* uses.  That
code is in random.py:

    def seed(self, a=None):
        ...
        if a is None:
            import time
            a = long(time.time() * 256) # use fractional seconds
        super(Random, self).seed(a)

time.time() typically changes value only 18.2 times per second on
Windows, so the multiplication by 256 isn't as effective as it looks
on Windows.  But you'll still get a different seed on Windows if start
times are more than about 0.055 seconds apart.

All the start times in the example you gave later were at least 0.06
seconds apart, so the different outcomes are expected.  Your machine
is fast enough that you might start to see duplicates on Windows if
you ran your Python instances with the -S switch (which skips a bunch
of expensive initialization).

Or, more directly,

import time, random
rd = {}
td = {}
ntries = 0
finish = time.time() + 10
while 1:
    t = time.time()
    if t > finish:
        break
    td[t] = 1
    rd[random.Random().random()] = 1
    ntries += 1
print len(rd), "unique random() values in", ntries, "attempts"
print len(td), "unique time.time() values"

On my WinXP box, that printed

641 unique random() values in 165923 attempts
641 unique time.time() values

Since it ran for 10 seconds, I'm seeing time.time() change about 64
times per second.  I believe that's because this is a hyper-threaded
box,  Whatever, if I had been able to start ~166000 instance of Python
in that time, I would have seen only ~640 different seedings across
them.



More information about the Python-list mailing list