Вступление
Даже для того, кто не интересуется компьютерным программированием, полезность генерации случайных чисел в определенных обстоятельствах очевидна. В большинстве настольных игр мы бросаем кости, чтобы получить непредсказуемое число, определяющее следующий ход игрока. Кроме того, мы все можем согласиться с тем, что играть в любую карточную игру было бы бессмысленно без надлежащего перемешивания раундов.
Но случайные числа важны не только в относительно тривиальных областях, таких как развлечения или азартные игры. Они особенно важны в области криптографии. Чтобы обеспечить безопасную передачу данных, каждый раз, когда необходимо безопасное соединение, необходимо генерировать случайный ключ. Этот вид безопасности используется во многих различных видах электронной связи. Очень важно, чтобы ключ было трудно угадать - лучший способ гарантировать это - сделать его случайным, поскольку в тот момент, когда кто-то угадает ключ, он сможет расшифровать сообщение - и связь больше не является безопасной.
Истинная случайность против псевдослучайности
Случайные числа могут быть получены в результате применения методов, называемых генераторами случайных чисел (ГСЧ), которые можно разделить на две категории: генераторы истинных случайных чисел (ГСЧ, также называемые аппаратными генераторами случайных чисел) и генераторы псевдослучайных чисел. (PRNGS).
Генераторы истинных случайных чисел
Истинные генераторы случайных чисел - это методы, которые выводят случайность или непредсказуемость из непредсказуемых аспектов физических процессов. Эти методы не производят напрямую числа, а скорее состояния, которые затем можно интерпретировать как числа - поэтому их обычно называют генераторами случайных событий ( REG s). Некоторые из них, использующие макроскопические события, широко известны - это такие методы, как бросание кубиков, подбрасывание монет или тасование карт.
Эти истинные генераторы случайных чисел часто используют более сложные физические явления. Некоторые из них, такие как радиоактивный распад, тепловой шум или радиошум, получают свою непредсказуемость из особенностей квантовой механики. Другие методы используют непредсказуемость атмосферного шума или даже поведение лавовых ламп .
Генераторы псевдослучайных чисел
По правде говоря, очень часто генерация чисел, которые на самом деле действительно случайны, не требуется. Во многих случаях все, что нам нужно, - это наборы чисел, которые кажутся случайными. Такие данные могут быть получены с помощью генераторов псевдослучайных чисел . Это алгоритмы, которые используют крошечную часть информации (называемую начальным числом), а затем применяют сложные математические формулы для создания детерминированных наборов чисел, напоминающих действительно случайные наборы. Начальное значение может быть значением, полученным от истинного генератора случайных чисел или другого источника, такого как системные часы или текущее время.
Многократный запуск генератора с использованием одного и того же начального числа приведет каждый раз к одному и тому же результату. Результирующие числа в основном неузнаваемы из чисел, полученных от истинных генераторов случайных чисел, хотя на самом деле в их распределении есть некоторые скрытые закономерности. Тем не менее, для многих приложений такой детерминированной псевдослучайности вполне достаточно.
Случайный модуль Python
Python, очевидно, предлагает очень простой в использовании набор
инструментов для обработки случайных чисел. Модуль, по какой-то причине
названный random
, реализует генератор псевдослучайных чисел и
содержит методы, которые позволяют напрямую решать множество различных
программных проблем, в которых играет роль случайность.
Модуль random
основан на очень популярном алгоритме Marsenne
Twister , который по
умолчанию является генератором псевдослучайных чисел не только для
Python, но и для многих других популярных программных систем, таких как
Microsoft Excel, MATLAB, R или PHP. Его важные преимущества включают
разрешающее лицензирование, случайное сходство, подтвержденное многими
статистическими тестами, и относительно высокую скорость по сравнению с
другими ГПСЧ.
Метод random ()
Самый важный метод random
- это метод random()
От него зависит
большинство других функций. Метод random()
генерирует случайное число
с плавающей запятой в диапазоне (0,0, 1,0).
>>> import random
>>> random.random()
0.8474337369372327
Метод seed ()
Если мы не устанавливаем начальное число для генерации псевдослучайных
чисел, начальным значением по умолчанию будет текущее системное время.
Однако мы можем установить точное значение начального числа вручную, что
пригодится, особенно если мы хотим воспроизвести наши псевдослучайные
результаты в будущем. Для этого мы можем использовать метод
random.seed()
.
>>> random.seed(5)
>>> random.random()
0.6229016948897019
>>> random.random()
0.7417869892607294
>>> random.random()
0.7951935655656966
>>> random.seed(5)
>>> random.random()
0.6229016948897019
Метод random.seed()
влияет на все методы random
которые мы
используем после его вызова. В показанном выше примере мы устанавливаем
начальное значение 5
а затем выполняем random.random()
несколько
раз. Важно отметить, что определяемое пользователем начальное число
используется только при первом выполнении другого random
метода -
после этого начальные числа для следующих методов изменяются с
использованием ранее сгенерированных случайных значений.
Это позволяет Python каждый раз придумывать новые числа. Но все же,
после повторной установки начального числа с помощью random.seed()
,
мы можем воспроизвести ту же самую последовательность псевдослучайных
чисел в любое время. Это очень полезно для таких вещей, как запуск
тестов. Если вы задаете одно и то же начальное значение каждый раз,
когда запускаете тест, использующий один из random
вы все равно
сможете узнать, каким должен быть результат для тестов.
Другие примеры случайного модуля
Метод random.random()
, который дает нам случайное значение с
плавающей запятой из определенного диапазона, будет достаточным даже для
неопытного разработчика Python, чтобы спроектировать вокруг него любые
случайные манипуляции. Вы, вероятно, можете представить, что добавляете
if
или два, чтобы написать функцию, которая случайным образом
извлекает значение из списка или возвращает случайное целое число вместо
числа с плавающей точкой. Что ж, random
позволяет нам позаботиться об
этих задачах автоматически. Ниже я покажу пару интересных методов,
которые упрощают обычные рандомизированные операции. Вы можете узнать
весь потенциал модуля random
в официальной документации
Python .
>>> random.randint(1,10)
4
Метод random.randint()
принимает два аргумента, описывающих диапазон,
из которого метод извлекает случайное целое число.
>>> random.randrange(2,10,2)
2
>>> random.randrange(2,10,2)
4
>>> random.randrange(2,10,2)
8
>>> random.randrange(2,10,2)
6
В приведенном выше random.randrange()
похож на random.randint()
но
он также позволяет нам определить третий аргумент, который является
точкой шага определенного диапазона. В приведенном выше примере нам
нужны только четные числа из диапазона от 2 до 10.
>>> cards = ['ace_spades','10_hearts','3_diamonds','king_hearts']
>>> random.choice(cards)
'10_hearts'
В приведенном выше скрипте метод random.choice()
выбирает случайный
элемент из списка.
>>> cards = ['ace_spades','10_hearts','3_diamonds','king_hearts']
>>> random.shuffle(cards)
>>> print(cards)
['king_hearts', '3_diamonds', 'ace_spades', '10_hearts']
В предыдущем сценарии метод random.shuffle()
список элементов. Важно
отметить, что он изменяет список на месте - это означает, что он
возвращает None
и фактически изменяет нашу переменную cards
Выводы
Получение хороших случайных чисел для серьезных приложений, таких как криптография, - непростая задача. Но когда для нашего приложения достаточно твердого псевдослучайного числа, Python, как всегда, предлагает ряд супер простых способов быстро достичь нашей цели.