Всіх вітаю! У цій статті ми вивчимо яким чином можна генерувати правдиві випадкові числа за допомогою вбудованого модуля secrects та класу SystemRandom() у модулі random. Також ми трішки поговоримо про алгоритм, на якому ґрунтується модуль random та чому він не є безпечним у криптографії.
Що таке вихор Мерсенна?
Вихор Мерсенна — це алгоритм генерації псевдовипадкових чисел, на якому й ґрунтується модуль random. Тобто, варто одразу зауважити, що він генерує саме псевдовипадкові числа, а не по-справжньому випадкові. Саме в цьому і полягає його небезпечність для застосування у криптографії. Насправді даний алгоритм є передбачуваним, тому його зазвичай застосовують для симуляцій, математичних розріхунків тощо.
Модуль secrects
Призначення
Модуль secrect призначений для генерації справді випадкових чисел, які є криптографічно безпечними навідміну від модуля random, який генерує так звані псевдо випадкові числа. Тому, якщо нам треба створити програму, акцентуючи на її безпеці, то краще використовувати саме модуль secrets.
Функція choice()
Імпортуємо secrects:
import secretsФункція choice() має той самий сенс, що й однойменна функція у модулі random, але вона обирає справді випадкові значення із послідовності, на відміну від тієї ж функції у random.
Ось приклад цієї функції у коді:
import secrets
numbers = [10, 56, 101, 77, 2, 0, 81]
truly_random_choice = secrets.choice(numbers)
print(truly_random_choice)2Функція randbelow()
Функція randbelow() генерує випадкові числа, причому вона потрібує лише один параметр, а не два як у randint() з random. Ще одна відмінність randbelow() від randint() у тому, що перша генерує числа від 0 до вказаного числа.
Ось приклад:
truly_random_num = secrets.randbelow(100)
print(f"Random number is {truly_random_num}")Random number is 14Функція randbits()
Функція randbits() генерує випадкове число на основі вказаній кількості бітів.
Ось приклад:
truly_random_bits = secrets.randbits(10)
print(truly_random_bits)710Але як саме це працює? Коли ми вказуємо число бітів, то ми підносимо його до 2 і отримуємо діапазон, у якому будуть згенеровані наші числа.
Наприклад, якщо ми вкажемо у якості параметра 2 біти, то ми підносимо нашу кількість бітів (2) до двійки. Так як 2 у степені 2 дорівнює 4, то наші числа будуть генеруватися у діапазоні від 0 до 4.
Приклад у коді:
truly_random_bits = secrets.randbits(2)
print(truly_random_bits)1Як бачимо, отримане число задовільняє діапазон.
Функція token_bytes()
Функція token_bytes() генерує випадковий байт рядок (токен) на основі кількості байтів, яку ми вказуємо у якості параметра.
Приклад:
byte_string = secrets.token_bytes(10)
print(byte_string)b'i\xc7:\x06\xdftz4}o'Функція token_hex()
Функція token_hex() генерує випадковий шістнадцятковий рядок (токен) за вказаною кількістю байтів у якості параметра.
Ось приклад роботи даної функції:
hex_string = secrets.token_hex(22)
print(hex_string)41207bfb298567d97a4b69dfa0b86eb125e909856038Функція token_urlsafe()
Функція token_urlsafe() генерує випадковий рядок (токен) конкретно для URL адрес. Дана функція відрізняється тим, що згенерований нею рядок можна використовувати у посиланнях, тобто рядок виключає несприятливі для посилань символи. Він так само приймає кількість байтів як параметр.
Приклад:
url_token = secrets.token_urlsafe(15)
print(url_token)6Wy9juVuk5R_j3erzaBPКлас SystemRandom() у модулі random
Також у самому модулі random є клас SystemRandom(), де є функції, які безпосередньо створені для генерації правдивих випадковостей, а не псевдовипадкових чисел як раніше.
Функція choice()
Ось, наприклад, функція choice() тепер справді обирає випадковий елемент із списку:
numbers = [10, 56, 101, 77, 2, 0, 81]
truly_random = random.SystemRandom()
rand_choice = truly_random.choice(numbers)
print(rand_choice)77Функція randint()
Тепер randint() також є криптографічно безпечною і може генерувати правдиві випадкові числа.
Приклад:
truly_random = random.SystemRandom()
rand_integer = truly_random.randint(10, 50)
print(rand_integer)14Функція randbytes()
Функція randbytes() робить те саме, що й функція token_bytes() у secrects.
Приклад:
truly_random = random.SystemRandom()
token = truly_random.randbytes(50)
print(token)b'%\xcbQ]\xa6\x96\xab\xd3P\x06\xcd\xe4L\xab\xca\t-;\xb5t@\xfc\x01;r\x8d\xe1\x9a\x05\x95[\x8aCB)>\xb5\xae\x11\x17\n\xad\x9bZ\x82\x0e\x90|\x0e\xad'Висновок
У висновку ми можемо зазначити, що за допомогою даної статті ми змогли дізнатися про особливіть вихору Мерсенна, функціонал модуля secrects та клас SystemRandom() у модулі random, який дозволяє нам працювати із справжніми випадковостями. Всім дякую за увагу!