SHA-based subclass for random module

Raymond Hettinger python at rcn.com
Wed Mar 17 10:01:32 CET 2004


[Paul Rubin] 
> This is intended to be less predicable/have fewer correlations than
> the default Mersenne Twister or Wichmann-Hill generators.  Comments
> are appreciated.

Because SHA-1 is a digest function, additional input can be tacked on
without impacting invertibility.  That gives you an opportunity to
incorporate the Mersenne Twister to take advantage of its provably
long period.

Here is a rough cut that extracts a 53 bit float on every pass and
leaves the remaining 107 bits of state hidden:

import struct
import sha
import random

def srandom(seed):
    gen = sha.new(seed)
    digest = gen.digest
    update = gen.update
    random.seed(seed)
    mt = random.random
    unpack = struct.unpack
    tofloat = 1.0 / 2 ** 53
    while 1:
        state = digest()
        randint = unpack('Q', state[:8])[0] >> 11  # grab 53 bits
        yield randint * tofloat
        update(state)
        update(str(mt()))  # twister never hurts, but can help period

r = srandom('the quick brown fox jumped')
for i in xrange(10):
    print r.next() 


Raymond Hettinger



More information about the Python-list mailing list