SHA-based subclass for random module
Josiah Carlson
jcarlson at nospam.uci.edu
Tue Mar 23 23:28:45 EST 2004
> This would be easy to implement with Mersenne Twister too. Though it
> would involve some rewriting.
>
> Do you think this is worthwhile?
I don't know, but I'm leaning towards not really.
def getrandstring(self, n):
out = [struct.pack('>L', self.getrandbits(32)) \
for i in xrange(0, n, 4)]
out.extend([chr(self.getrandbits(4)) for i in xrange(n%4)])
return ''.join(out)
You have your getrandstring for any class that provides getrandbits, and
is relatively optimized to deal with very long output strings.
def getrandbits(self, n):
out = 0
for i in xrange(0, n+16, 16):
out = out << 16 + struct.unpack('>H', self.getrandstring(2))
return out >> (16-(n%16))
Now you have getrandbits for any method that provides getrandstring, and
it is optimized to deal with a Python long internal representation.
- Josiah
On a relatively unrelated note, I'm leaning toward trying to get the
benefits of both SHA and MT with the following, though I lack the heavy
mathematical background to prove whether it is better than either.
class SHARandom(Random):
def random(self, tofloat = 1.0 / 2 ** 53, divint = 2**64):
grb = self.getrandbits
plaintxt = struct.pack("<QQL", grb(64), grb(64), grb(32))
ciphertext = sha.new(plaintxt+self.sha_state).digest()
randint = unpack('<Q', ciphertxt[:8])[0] >> 11 # grab 53 bits
self.sha_state = ciphertext[7:] #keep hidden state
return randint * tofloat
#deal with state initialization and seeding
def __init__(self, x=None, y=None):
self.seed(x,y)
def seed(self, x=None, y=None):
Random.seed(x)
self.sha_state = sha.new(str(y)).digest()[7:]
#deal with state persistency
def getstate(self):
return (Random.getstate(self), self.sha_state)
def setstate(self, state):
Random.setstate(state[0])
self.sha_state = state[1]
More information about the Python-list
mailing list