22 lines
618 B
Python
22 lines
618 B
Python
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
|