# Copyright (c) 2002-2006 Bryce "Zooko" Wilcox-O'Hearn # mailto:zooko@zooko.com # http://zooko.com/repos/pyutil # Permission is hereby granted, free of charge, to any person obtaining a copy # of this work to deal in this work without restriction (including the rights # to use, modify, distribute, sublicense, and/or sell copies). import os, random try: import hashexpand class SHA256Random(hashexpand.SHA256Expander, random.Random): def __init__(self, seed=None, deterministic=True): if not deterministic: raise NotImplementedError, "SHA256Expander is always deterministic. For non-deterministic, try urandomRandom." hashexpand.SHA256Expander.__init__(self) random.Random.__init__(self, seed) self.seed(seed) def seed(self, seed=None): if seed is None: import increasing_timer seed = repr(increasing_timer.time()) hashexpand.SHA256Expander.seed(self, seed) class SHA256Random(hashexpand.SHA256Expander, random.Random): def __init__(self, seed=""): hashexpand.SHA256Expander.__init__(self) self.seed(seed) def seed(self, seed=None): if seed is None: seed = os.urandom(32) hashexpand.SHA256Expander.seed(self, seed) except ImportError, le: class InsecureSHA256Random: def __init__(self, seed=None): raise ImportError, le class SHA256Random: def __init__(self, seed=""): raise ImportError, le class devrandomRandom(random.Random): """ The problem with using this one, of course, is that it blocks. This is, of course, a security flaw. (On Linux and probably on other systems.) --Zooko 2005-03-04 Not repeatable. """ def __init__(self): self.dr = open("/dev/random", "r") def get(self, bytes): return self.dr.read(bytes) class devurandomRandom(random.Random): """ The problem with using this one is that it gives answers even when it has never been properly seeded, e.g. when you are booting from CD and have just started up and haven't yet gathered enough entropy to actually be unguessable. (On Linux and probably on other systems.) --Zooko 2005-03-04 Not repeatable. """ def get(self, bytes): return os.urandom(bytes) randobj = devurandomRandom() get = randobj.get random = randobj.random randrange = randobj.randrange shuffle = randobj.shuffle choice = randobj.choice def randstr(n): return ''.join(map(chr, map(randrange, [0]*n, [256]*n))) import random as insecurerandom def insecurerandstr(n): return ''.join(map(chr, map(insecurerandom.randrange, [0]*n, [256]*n)))