Я делаю проект на python, и я хотел бы создать случайное число, которое криптографически безопасно. Как я могу это сделать? Я читал в Интернете, что числа, генерируемые обычным рандомизатором, не являются криптографически безопасными и что функция os.urandom(n)
возвращает мне строку, а не число.
Как создать случайное число, криптографически безопасное в python?
Ответ 1
Вы можете получить список случайных чисел, просто применив функцию ord
по байтам, возвращенным os.urandom
, вот так
>>> import os
>>> os.urandom(10)
'm\xd4\x94\x00x7\xbe\x04\xa2R'
>>> type(os.urandom(10))
<type 'str'>
>>> map(ord, os.urandom(10))
[65, 120, 218, 135, 66, 134, 141, 140, 178, 25]
Цитата os.urandom
документация,
Возвращает строку
n
случайных байтов , подходящих для использования в криптографии.Эта функция возвращает случайные байты из источника случайности, специфичного для ОС. Возвращенные данные должны быть непредсказуемыми для криптографических приложений, хотя его точное качество зависит от реализации ОС. В UNIX-подобной системе это запросит
/dev/urandom
, а в Windows он будет использоватьCryptGenRandom()
.
Ответ 2
Поскольку вы хотите генерировать целые числа в определенном диапазоне, гораздо проще использовать класс random.SystemRandom
. Создание экземпляра этого класса предоставляет объект, поддерживающий все методы модуля random
, но используя os.urandom()
под обложками. Примеры:
>>> from random import SystemRandom
>>> cryptogen = SystemRandom()
>>> [cryptogen.randrange(3) for i in range(20)] # random ints in range(3)
[2, 2, 2, 2, 1, 2, 1, 2, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0]
>>> [cryptogen.random() for i in range(3)] # random floats in [0., 1.)
[0.2710009745425236, 0.016722063038868695, 0.8207742461236148]
Etc. Используя urandom()
напрямую, вы должны изобрести свои собственные алгоритмы для преобразования произвольных байтов, которые он производит, к желаемым результатам. Не делайте этого;-) SystemRandom
делает это за вас.
Обратите внимание на эту часть документов:
class random.SystemRandom([seed])
Класс, который использует функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой. Не доступен для всех систем. Не полагается на состояние программного обеспечения, и последовательности не воспроизводятся. Соответственно, методы seed() и jumpahead() не действуют и игнорируются. Методы getstate() и setstate() поднимают NotImplementedError, если вызваны.
Ответ 3
Python 3.6 представляет новый модуль секретов, который обеспечивает доступ к наиболее безопасному источнику случайности, который операционной системы ". Чтобы создать некоторые криптографически защищенные номера, вы можете вызвать secrets.randbelow()
.
secrets.randbelow(n)
который вернет число между 0 и n
.
Ответ 4
Если вы хотите n
-битное случайное число, в Python 2.4+, самый простой способ, который я нашел, -
import random
random.SystemRandom().getrandbits(n)
Обратите внимание, что SystemRandom
использует os.urandom()
, поэтому результат этого метода не хуже, чем реализация вашей системы urandom()
.
Ответ 5
Чтобы создать криптографически безопасное псевдослучайное целое число, вы можете использовать следующий код:
int(binascii.hexlify(os.urandom(n)),16)
Где n
- целое число, и чем больше n
, тем больше генерируется целое число.
Сначала вам нужно импортировать os
и binascii
.
Результат этого кода может варьироваться в зависимости от платформы.