import math, os from functools import reduce log256 = math.log(256) class LongRandom: def getint(self, bytes): value = list(os.urandom(bytes)) return reduce(lambda x,y: (x<<8)|y, value) def get(self, modulus): # Find the largest power-of-2 that modulus fits into bytes = int(math.ceil(math.log(modulus) / log256)) maxval = 256 ** bytes # maxmod is the largest multiple of modulus not greater than maxval maxmult = maxval - maxval % modulus while True: value = self.getint(bytes) # Stop generating when the value would not cause bias if value <= maxmult: break return value % modulus