2016-06-20 5 views
2

В Документах (Python 3.5) для инициализации случайного числа из семени:Python количество RNG семян

random.seed (а = нет, версия = 2)

Инициализировать случайное число генератор.

Если a опущено или None, используется текущее системное время. Если источников случайности предоставлены операционной системой, они используются вместо вместо системного времени (см. Функцию os.urandom() для получения информации о наличии).

Если a является int, он используется напрямую.

С версией 2 (по умолчанию) объект str, bytes или bytearray получает , преобразованный в int, и все его биты используются. С версией 1 вместо этого используется хеш() a .

Это не дает понять, сколько семян есть. INT имеет как правило, только 4000000000 различных значений, но питоны включают произвольную точность:

x = 1 
type(x) # <class 'int'> 
y = 123456789123456789123456789123456789123456789123456789123456789123456789 
type(y) # <class 'int'> 
z = x+y 
z-y # 1 (no rounding error for a 71 digit number) 

Они говорят все его биты используются, но это может означать, что биты используются для создания дайджеста, что является нормальным 32 бит int. Почему это имеет значение? Мне нужно сделать случайные шаблоны из семян. В свою очередь, мне нужно создавать случайные последовательности шаблонов (последовательность, в свою очередь, имеет семя). Поток генераторов случайных чисел будет подвергаться «атаке на день рождения», в которой после 100 тысяч или около того почти наверняка будет дубликат, если это всего лишь 32 бита. Хотя это не криптография, она по-прежнему нежелательна.

ответ

3

Что нового в open source - это возможность просто просмотреть код с вопросом. Это source of random.seed:

if a is None: 
    try: 
     # Seed with enough bytes to span the 19937 bit 
     # state space for the Mersenne Twister 
     a = int.from_bytes(_urandom(2500), 'big') 
    except NotImplementedError: 
     import time 
     a = int(time.time() * 256) # use fractional seconds 

if version == 2: 
    if isinstance(a, (str, bytes, bytearray)): 
     if isinstance(a, str): 
      a = a.encode() 
     a += _sha512(a).digest() 
     a = int.from_bytes(a, 'big') 

super().seed(a) 
self.gauss_next = None 

Вы можете видеть, что если version == 2 и str/bytes предусмотрены, она принимает SHA512 из a, присоединяет его и использует int.from_bytes, создавая очень большой ИНТ и гарантируя при наименьших 512-битное семя, даже с очень маленькими пользовательскими входами.

Как отмечено ниже, конечным результатом является то, что семя гарантировано имеет длину не менее 624 бит.

+0

«super(). Seed (a)» - это супер-переваривание этого хэш-памяти в 512 бит или это подлинное 512-битное семя? –

+0

Я думаю, что также важно, что происходит с 'a' после' super(). Seed (a) '. Источником является https://github.com/python/cpython/blob/488376e0204bcea4ef4e07490a839bef9729e7ed/Modules/_randommodule.c ... 'random_seed()' .. Я все еще перевариваю его. – rrauenza

+0

Этот комментарий * «Этот алгоритм полагается на число без знака. Итак: если arg является PyLong, используйте его абсолютное значение. В противном случае используйте его значение хэша, отличное от беззнакового.» * , по-видимому, подразумевает, что семя в конечном итоге просто «PyLong». Ах .. но ['Pylong' может быть произвольного размера] (https://docs.python.org/3.2/c-api/long.html). – rrauenza

Смежные вопросы