код модуля random python
Модуль random: генерация псевдослучайных чисел в Python
Многим компьютерным приложениям необходимо генерировать случайные числа. Однако ни одно из них не генерирует действительно случайное число. Python, как и многие другие языки программирования, использует генератор псевдослучайных чисел. Генерация случайных чисел в Python основана на алгоритме Вихрь Мерсенна. Этот метод быстрый и потокобезопасный, но не подходит для криптографических целей.
random.getstate() — эта функция вместе с функцией setstate() помогает воспроизводить одни и те же случайные данные снова и снова. Функция getstate() возвращает внутреннее состояние генератора случайных чисел. Больше информации вы можете найти по ссылке.
random.setstate(state) — эта функция восстанавливает внутреннее состояние генератора.
Следующие функции предназначены для генерации случайных целых чисел:
random.randrange() − эта функция генерирует случайное целое число в пределах заданного диапазона чисел. Может принимать три параметра.
Параметры start и step являются необязательными. Их значения по умолчанию равны 0 и 1 соответственно. Шаг ( step ) определяет интервал между последовательными числами.
Примечание: помните, что выходные данные примеров в этой статье могут не совпадать, так как они генерируются случайным образом.
Следующие функции работают со случайными числами с плавающей запятой:
random.random() — эта функция генерирует случайное число с плавающей запятой в диапазоне от 0.0 до 1.0.
Следующие функции работают c последовательностями, а именно — со строками, списками или кортежами:
random.choices() − эта функция случайным образом выбирает несколько элементов из списка. Первый параметр этой функции — последовательность, а второй — количество элементов, которые нужно вернуть. Возвращает список, в котором может повторяться несколько раз один и тот же элемент.
random.shuffle() — эта функция переупорядочивает (перемешивает) элементы в изменяемой (mutable) последовательности и размещает их случайным образом.
random.sample(sequence, n) — эта функция возвращает список случайно выбранных элементов из последовательности. Результирующий список содержит только уникальные элементы.
Более подробную информацию о функциях модуля random вы можете найти в документации.
Python 3: Генерация случайных чисел (модуль random)¶
«Генерация случайных чисел слишком важна, чтобы оставлять её на волю случая»
Python порождает случайные числа на основе формулы, так что они не на самом деле случайные, а, как говорят, псевдослучайные [1]. Этот способ удобен для большинства приложений (кроме онлайновых казино) [2].
[1] | Википедия: Генератор псевдослучайных чисел |
[2] | Доусон М. Программируем на Python. — СПб.: Питер, 2014. — 416 с.: ил. — 3-е изд |
Модуль random позволяет генерировать случайные числа. Прежде чем использовать модуль, необходимо подключить его с помощью инструкции:
random.random¶
random.random() — возвращает псевдослучайное число от 0.0 до 1.0
random.seed¶
random.seed( ) — настраивает генератор случайных чисел на новую последовательность. По умолчанию используется системное время. Если значение параметра будет одиноким, то генерируется одинокое число:
random.uniform¶
random.randint¶
random.choince¶
random.choince( ) — возвращает случайный элемент из любой последовательности (строки, списка, кортежа):
random.randrange¶
random.shuffle¶
random.shuffle( ) — перемешивает последовательность (изменяется сама последовательность). Поэтому функция не работает для неизменяемых объектов.
Вероятностные распределения¶
random.expovariate(lambd) — экспоненциальное распределение. lambd равен 1/среднее желаемое. Lambd должен быть отличным от нуля. Возвращаемые значения от 0 до плюс бесконечности, если lambd положительно, и от минус бесконечности до 0, если lambd отрицательный.
random.gauss(значение, стандартное отклонение) — распределение Гаусса.
random.normalvariate(mu, sigma) — нормальное распределение. mu — среднее значение, sigma — стандартное отклонение.
random.vonmisesvariate(mu, kappa) — mu — средний угол, выраженный в радианах от 0 до 2π, и kappa — параметр концентрации, который должен быть больше или равен нулю. Если каппа равна нулю, это распределение сводится к случайному углу в диапазоне от 0 до 2π.
random.paretovariate(alpha) — распределение Парето.
random.weibullvariate(alpha, beta) — распределение Вейбулла.
Примеры¶
Генерация произвольного пароля¶
Хороший пароль должен быть произвольным и состоять минимум из 6 символов, в нём должны быть цифры, строчные и прописные буквы. Приготовить такой пароль можно по следующему рецепту:
Этот же скрипт можно записать всего в две строки:
Данная команда является краткой записью цикла for, вместо неё можно было написать так:
Данный цикл повторяется 12 раз и на каждом круге добавляет к строке psw произвольно выбранный элемент из списка.
Модуль random. Генерация случайных чисел
В процессе программирования на Python может понадобиться случайное число. О том, как создать собственный простейший генератор псевдослучайных чисел и пойдет разговор в этой статье. Будут рассмотрены некоторые популярные методы и функции, которые включены в модуль random для Python 3 и позволяют получать значения случайным образом (randomly).
В качестве лирического отступления следует сказать, что, согласно специфике внутреннего состояния генератора, модуль для Python под названием random позволяет сгенерировать не случайный, а псевдослучайный элемент, то есть значения и их последовательности формируются на основе формулы. Раз последовательность зависит от нескольких параметров, она не является случайной в полном смысле этого слова. Если нужна истинная случайность, генерация может основываться, к примеру, на принципах квантовой механики, однако на практике это слишком дорого и сложно, да и не всегда экономически целесообразно, ведь для многих задач программирования вполне подойдут и псевдослучайные генераторы (если речь идет не про онлайн-казино). Вдобавок к этому, случайность (randomness) — вещь капризная, поэтому, как тут не вспомнить прекрасное высказывание американского математика Роберта Кавью:
Также на ум приходит еще одно интересное высказывание, но уже от выдуманного персонажа и с некоторым уклоном в философию:
Применение random в Python
В языке программирования «Пайтон» модуль random позволяет реализовывать генератор псевдослучайных чисел для разных распределений, куда входят как целые (integers), так и вещественные числа, то есть числа с плавающей запятой.
Общий список методов, поддерживаемых модулем random, можно посмотреть в таблице ниже. Тут стоит обратить внимание, что возврат значений может осуществляться на основе разных распределений (распределение Парето, распределение Вейбулла и т. д.), выбор которых зависит от области применения генератора случайных чисел (статистика, теория вероятности).
Но мы не будем углубляться в распределения, а рассмотрим самые простые методы. А так как разглядывать их в таблице совершенно неинтересно, давайте попрактикуемся и выясним, как может быть использован тот или иной метод в деле.
random.random
У модуля random есть одноименный метод-тезка — функция random. Она возвращает случайное число в диапазоне 0 — 1.0:
print(«Выводим случайное число с помощью random.random():»)
Если вы скопируете этот простейший код себе (можно использовать любой онлайн-компилятор), вы получите другое число.
Также вывести можно не одно, а, к примеру, три (three) числа (используется for i in range), причем прекрасным решением будет ограничить вывод до двух знаков после запятой (за это отвечает ‘%.2f’):
print(«Выводим 3 случайных числа; не более 2 знаков после запятой:»)
print([‘%.2f’ % random.random() for i in range(3)])
random.seed
Метод seed может показаться более сложным для понимания. Фишка в том, что, как уже было сказано выше, используется генератор псевдослучайных чисел, то есть выдача этих чисел происходит в соответствии с алгоритмом. Алгоритм вычисляет значение на основе другого числа, но это число берется не с потолка — оно вычисляется на основании текущего системного времени. В результате, если вы будете пробовать на своем компьютере один из кодов, рассмотренных выше, вы будете получать каждый раз новые числа.
Если же задействовать seed с одним и тем же параметром, то вычисление будет производиться на основании этого параметра. Итог — на выходе будут получаться одинаковые «случайные» значения. Возьмем для примера параметр 5 и сделаем так, чтобы метод отработал дважды:
random.uniform
С uniform все проще: возвращается псевдослучайное вещественное число, находящееся в определенном диапазоне, который указывается разработчиком:
print(«Находим число с плавающей точкой в заданном диапазоне:»)
random.randint
Randint в Python тоже позволяет вернуть псевдослучайное число в определенном диапазоне, но тут уже речь идет о целом значении (int, integer):
print(«Используем randint для генерации целого числа int из диапазона:»)
random.randrange
Следующий метод, называемый randrange, похож на предыдущий randint, но тут, кроме диапазона целых значений int, можно добавить еще и шаг выборки (в качестве третьего параметра):
print(«Генерируем случайное целое число в заданном диапазоне с шагом»)
print(random.randrange(10, 100, 2))
Судя по результату ниже и в соответствии с выбранным диапазоном от 10 до 100, установив шаг 2, мы будем получать лишь четные значения:
random.choice
Применение choice позволяет вернуть элемент из какой-нибудь последовательности — это может быть список, строка, кортеж.
И это уже интереснее, т. к. напрашивается аналогия с броском игрального кубика:
print(«Выборка одного элемента из списка с помощью choice:»)
Проверьте, повезет ли так и вам. Но вообще, перечень может состоять из других цифр и даже слов.
Сыграйте в игру и попробуйте погадать, какой язык программирования вам лучше учить в Otus:
print(«Какой язык программирования будешь учить?»)
Sample и choices
Начиная с Python 3.6, появился метод choices. Его отличие в том, что он позволяет сделать выборку нескольких элементов из последовательности, а вот сколько именно будет значений, можно указать. В отличие от схожего метода sample, в choices возможно получение одинаковых цифр.
Вернемся к нашему виртуальному кубику. Вот работа sample:
print («Выборка двух случайных значений:»)
Все бы ничего, но этот метод будет постоянно выводить 2 разных значения. Если же мы захотим сымитировать бросок двух игральных кубиков, код придется менять, ведь в реальной жизни выкинуть дубль все-таки можно. Но зачем менять код, если есть choices? Он обеспечит вывод двух случайных значения из заданного диапазона, причем они могут повторяться. Это уже максимально приближено к реальному броску двух кубиков, причем профит достигается и за счет того, что объем кода не увеличивается. Ради интереса мы его даже уменьшили — оптимизировали (List превратился в l, да и лишний текст выкинули):
Кстати, вот и дубль — результат равен [6, 6], причем всего лишь с 5-й попытки (можете поверить на слово):
Правда, тут нюанс: пришлось сменить онлайн-компилятор, так как на предыдущем компиляторе Python версии 3.6 не поддерживался.
random.shuffle
Функция с интересным названием shuffle может перемешивать последовательность, меняя местами значения (она не подходит для неизменяемых объектов). Здесь важна именно последовательность выпадения определенных значений, как в лото.
print («Крутим барабан и достаем шары наугад: «, list)
Остается добавить, что английское слово shuffle означает «тасовать, перемешивать». Как тут не вспомнить картежного шулера или лопату-шуфлю для перемешивания бетонного раствора. Но это так, для общего развития.
Случайное число
Как и многие другие языки программирования, Python позволяет работать с генераторами случайных значений. С их помощью можно оперативно создавать последовательности из различных чисел или символов, предугадать которые невозможно. Для этой цели в Python применяется встроенная библиотека с множеством методов для управляемой генерации.
Что такое случайные числа?
Случайные числа представляют собой произвольные данные, которые были получены в результате автоматической генерации компьютерной программой. Подобная информация используется во многих видах программного обеспечения, где необходимо иметь дело с непредсказуемыми величинами. Ярким примером тому являются игровые автоматы либо казино, в которых каждый раз генерируется новая выигрышная комбинация чисел. Также данный подход применяется в криптографических целях для создания надежных паролей.
Стоит заметить, что стандартные средства Python не способны предоставлять в программе истинно случайные значения. Они предоставляют псевдо случайную последовательность. Инициализируется она от какого либо случайного числа. То есть если мы будем инициализировать последовательность одним и тем же числом, то она будет каждый раз выдавать одинаковые данные. Чтобы этого не было, для инициализации берется значение системных часов.
Так что обычно используется метод генерации псевдослучайных величин с иницилизацией от системных часов.
Реализации случайных чисел в Python
Язык программирования Python содержит в себе несколько разных модулей, применяемых для генерации псевдослучайных величин. Все они, как правило, используют в своих целях текущее системное время, которое установлено на компьютере. Это гарантирует получение разных последовательностей значений при каждом новом обращении к генератору. Среди инструментов, которые предназначены для работы с псевдослучайными числами, находится довольно обширная библиотека random, а также функции numpy.random и os.urandom.
Особенности их применения:
Наиболее широкое применение получила в Python библиотека random. Поэтому далее мы ее и рассмотрим подробно.
Модуль random
Ниже приведена таблица, где описаны самые главные методы из подключаемого модуля, входящего в состав стандартных библиотек Python. В таблице приведены названия функций, а также доступный перечень параметров с небольшой характеристикой.
Метод | Характеристика |
random() | возвращает число в диапазоне от 0 до 1 |
seed(a) | настаивает генератор на новую последовательность a |
randint(a, b) | возвращает целое число в диапазоне от a и b |
randrange(a, b, c) | возвращает целое число в диапазоне от a до b с шагом c |
uniform(a, b) | возвращает вещественное число в диапазоне от a и b |
shuffle(a) | перемешивает значения в списке a |
choice(a) | возвращает случайный элемент из списка a |
sample(a, b) | возвращает последовательность длиной b из набора a |
getstate() | возвращает внутреннее состояние генератора |
setstate(a) | восстанавливает внутреннее состояние генератора a |
getrandbits(a) | возвращает a случайно сгенерированных бит |
triangular(a, b, c) | возвращает вещественное число от a до b с распределением c |
Здесь хотелось бы описать функцию seed. Она как раз и применяется для задания инициализирующего числа псевдо случайной последовательности. При вызове seed без параметра, берется значение системного таймера. Эта функция вызывается в конструкторе класса Random.
В примерах мы рассмотрим, как применяются основные функции. А так же в конце рассмотрим как используется SystemRandom.
Примеры
Чтобы воспользоваться возможностями генерации случайных чисел в Python 3, следует произвести импорт библиотеки random, вынеся ее в начало исполняемого файла при помощи ключевого слова import.
Вещественные числа
В модуле есть одноименная функция random. В Python она используется чаще, чем другие функции этого модуля. Функция возвращает вещественное число в промежутке от 0 до 1. В следующем примере демонстрируется создание трех разных переменных a, b и c.
Целые числа
Для получения случайных целых чисел в определенном диапазоне используется функция randint, принимающая два аргумента: минимальное и максимальное значение. Программа, показанная ниже отображает генерацию трех разных значений в промежутке от 0 до 9.
Диапазоны целых
Метод randrange позволяет генерировать целочисленные значения, благодаря работе с тремя параметрами: минимальная и максимальная величина, а также длина шага. Вызвав функцию с одним аргументом, начальная граница получит значение 0, а интервал станет равен 1. Для двух аргументов автоматически инициализируется только длина шага. Работа данного метода с трема разными наборами параметров показана в следующем примере.
Диапазоны вещественных
Сгенерировать вещественное число поможет метод под названием uniform. Он принимает всего два аргумента, обозначающих минимальное и максимальное значения. Демонстрация его работы располагается в следующем примере кода, где создаются переменные a, b и c.
Использование в генераторах
Возможности генерации псевдослучайных чисел можно использовать и для создания последовательностей. В следующем фрагменте кода создается набор чисел при помощи генератора списка со случайным наполнением и длиной. Как можно заметить, в данном примере функция randint вызывается дважды: для каждого элемента и размера списка.
Перемешивание
Метод shuffle дает возможность перемешать содержимое уже созданного списка. Таким образом, все его элементы будут находиться в абсолютно случайном порядке. Пример, где отображается работа этой функции со списком a из 10 значений, располагается дальше.
Случайный элемент списка
При помощи функции choice можно извлечь случайный элемент из существующего набора данных. В следующем примере переменная b получает некое целое число из списка a.
Несколько элементов списка
Извлечь из последовательности данных можно не только один элемент, но и целый набор значений. Функция sample позволит получить абсолютно новый список чисел из случайных компонентов уже существующего списка. В качестве первого аргумента необходимо ввести исходную последовательность, а на месте второго указать желаемую длину нового массива.
Генерация букв
Возможности стандартной библиотеки позволяют генерировать не только числа, но и буквы. В следующем примере показывается инициализация трех разных переменных случайными символами латиницы. Для этого необходимо произвести импортирование модуля string, а затем воспользоваться списком letters, который включает все буквы английского алфавита.
Как можно заметить, отображаются буквы в разном регистре. Для того чтобы преобразовать их к общему виду, рекомендуется вызвать стандартные строковые методы upper или lower.
SystemRandom
Как уже говорилось ранее, SystemRandom основана на os.urandom. Она выдает так же псевдослучайные данные, но они зависят дополнительно и от операционной системы. Результаты используются в криптографии. Есть недостаток — то что функции SystemRandom отрабатывают в несколько раз дольше. Рассмотрим пример использования:
Заключение
Таким образом, язык программирования Python содержит массу встроенных методов для генерации и обработки случайных значений. Пользоваться ими можно при помощи разных библиотек, входящих в стандартный набор инструментов платформы. Благодаря данным функциям можно задавать различные условия, а также ограничения для своих генераторов.
Генерация случайных данных в Python (Руководство)
Насколько случайны случайности? Это странный вопрос, но желательно его задать, если речь идет об информационной безопасности. Когда вы генерируете случайные данные, числа или строки в Python, неплохо иметь хотя бы приблизительное представление о том, как именно генерируются эти данные.
Содержание:
Здесь мы рассмотрим несколько различных способов генерации данных в Python и перейдем к их сравнению в таких категориях, как безопасность, универсальность, предназначение и скорость.
Мы обещаем, что данное руководство не будет похоже на урок математики, или криптографии: математики здесь будет ровно столько, сколько необходимо!
Насколько случайны случайности?
Во первых, нужно сделать небольшое заявление. Большая часть случайных данных, сгенерированных в Python — не совсем “случайная” в научном понимании слова. Скорее, это псевдослучайность, сгенерированная генератором псевдослучайных чисел (PRNG), который по сути, является любым алгоритмом для генерации на первый взгляд случайных, но все еще воспроизводимых данных.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
“Настоящие” случайные числа могут быть сгенерированы при помощи (как вы, скорее всего, можете догадаться), настоящим генератором случайных чисел (true random number generator, TRNG). Пример: регулярно поднимать игральный кубик с пола, подбрасывать его в воздух и дать ему приземлиться.
Представим, что вы совершаете бросок произвольно и понятия не имеете, какое число выпадет на кубике. Бросок кубика — это грубая форма использования аппаратного обеспечения для генерации числа, которое не является детерминированным. TRNG выходит за рамки этой статьи, однако это стоит упомянуть в любом случае, хотя бы для сравнения.
PRNG, выполняемые обычно программным, а не аппаратным обеспечением, немного отличаются. Вот краткое описание:
Они начинают со случайного числа, также известного как зерно и затем используют алгоритм для генерации псевдослучайной последовательности битов, основанных на нём.
В какой-то момент вам могут посоветовать почитать документацию. И эти люди не то, что ошибутся. Вот интересный сниппет из документации модуля random, который вам не стоит упускать:
Внимание: псевдослучайные генераторы этого модуля не должны быть использованы в целях безопасности (источник).
Возможно, вы уже сталкивались с random.seed(999), random.seed(1234), или им подобным. Этот вызов функции проходит через генератор случайных чисел, который используется модулем random Python. Это то, что делает последующие вызовы генератора случайных чисел детерминированными: вход А производит выход Б. Это чудо может стать проклятием, если используется неправильно.
Возможно термины “случайный” и “детерминированный” выглядят так, будто не могут упоминаться в одном контексте. Чтобы прояснить этот момент, вот супер упрощенная версия random(), которая итеративно создает “случайное” число, используя x = (x * 3) % 19.
“Х” изначально определен как значение сид (cлучайное начальное значение), после чего превращается в детерминированную последовательность чисел, основанных на этом семени:
Не стоит воспринимать этот пример слишком буквально, так как он служит чисто для отображения концепции. Если вы используете значение сид 1234, дальнейшая последовательность вызовов random() всегда должна быть идентичной:
Мы рассмотрим более серьезную иллюстрацию данного примера в дальнейшем.
Что значит “криптографически безопасно”?
Если вам казалось, что в статье мало акронимов типа “RNG” — то добавим сюда еще один: CSPRNG — криптографически безопасный PRNG. CSPRNG подходят для генерации конфиденциальных данных, таких как пароли, аутентификаторы и токены. Благодаря заданной случайно строке, условный злодей не сможет определить, какая строка шла за или перед этой строкой в последовательности случайных строк.
Еще один термин, с которым вы можете столкнуться — энтропия. В двух словах, она ссылается на количество случайностей, желаемых или введенных. Например, один модуль Python, который мы рассмотрим в данной статье, определяет DEFAULT_ENTROPY = 32, количество возвращаемых байтов по умолчанию. Разработчики считают это количество байтов “достаточным”.
Обратите внимание: В данной статье я предполагаю, что байт ссылается на 8 битов, как в далеких 60-х, а не к какой-либо другой единице хранения. Можете называть его октетом, если хотите.
Главная суть CSPRNG — это то, что они все еще псевдослучайные. Они сконструированы таким образом, что являются внутренне детерминированными, но добавляют некие другие переменные, или имеют определенную собственность, которая делает их “достаточно случайными”, чтобы запретить поддержку любой функции, которая выполняет детерменизм.
Что вы из этого почерпнете?
Практически, это значит, что вам нужно использовать PRNG для статистического моделирования, симуляции и сделать случайные данные воспроизводимыми. PRNG также значительно быстрее, чем CSPRNG, что вы и увидите в дальнейшем. Используйте CSPRNG для безопасности и в криптографических приложениях, где конфиденциальные данные являются обязательным условием.
В дополнение к расширению использования вышеупомянутых примеров в этой статье, вы познакомитесь с инструментами Python для работы как с PRNG, так и с CSPRNG:
Мы рассмотрим все вышеперечисленное и подытожим детальным сравнением.
PRNG в Python
Модуль random
Возможно самый известный инструмент для генерации случайных данных в Python — это модуль random, который использует алгоритм PRNG под названием Mersenne Twister в качестве корневого генератора.
Ранее, мы затронули random.seed(), и теперь настало подходящее время, чтобы узнать, как он работает. Сначала, давайте создадим случайные данные без сидинга. Функция random.random() возвращает случайное десятичное число с интервалом [0.0, 1.0). В результате всегда будет меньше, чем правая конечная точка (1.0). Это также известно, как полуоткрытый диапазон:
Если вы запустите этот код лично, весьма вероятно, что полученные числа на вашем компьютере будут другими. По умолчанию, когда вы не используете сид генератор, вы используете текущее системное время, или “источник случайности” вашей операционной системы, если это доступно.
С random.seed() вы можете сделать результаты воспроизводимыми, и цепочка вызова, после random.seed(), будет генерировать один и тот же след данных:
Обратите внимание на повторение “случайных” чисел. Последовательность случайных чисел становится детерменированной, или полностью определенной значением сида, 444.
Давайте рассмотрим основы того, как функционирует модуль random. Ранее мы создали случайное десятичное число. Вы можете сгенерировать случайное целое число между двумя отметками в Python при помощи функции random.randint(). Таким образом охватывается целый интервал [x, y] и обе конечные точки могут быть включены:
С random.randrange(), вы можете исключить правую часть интервала, то есть сгенерированное число всегда остается внутри [x, y) и всегда будет меньше правой части:
Если вы хотите сгенерировать случайные десятичные числа, которые находятся в определенном интервале [x, y], вы можете использовать random.uniform(), который вырывается из непрерывного равномерного распределения:
Чтобы взять случайный элемент из последовательности, не являющейся пустой (такой как список или кортеж), вы можете использовать random.choice(). Также есть random.choices() для выборки нескольких элементов из последовательности с заменой (дубликаты возможны):
Вы можете сделать последовательность случайной прямо на месте, при помощи random.shuffle(). Таким образом удастся обновить объект последовательности и сделать порядок элементов случайным:
Если вы не хотите делать это с изначальным списком, сначала вам может понадобиться сделать копию, а потом уже перемешать её. Вы можете создавать копии списков Python при помощи модуля copy, или просто x[:], или x.copy(), где x является списком.
Перед тем, как перейти к генерированию случайных данных в NumPy, давайте рассмотрим еще одно приложение, которое частично включено в процесс: генерация последовательности уникальных случайных строк с одинаковой длиной.
В первую очередь, это может разобраться с устройством функции. Вам нужно выбрать из “пула” символов, таких как буквы, числа, и\или знаки препинания, совмести их в одну строку, и затем проверить, является ли эта строка сгенерированной. Python работает отлично для такого типа тестирования:
«».join() присоединяет буквы из random.choices() в простую строку, где «k» это длинна строки. Это токен добавлен в набор, который не может иметь дубликатов, и цикл while будет проходить, пока набор не будет содержать количество элементов, которое вы определили.
На заметку: Модуль string содержит ряд полезных констант: cii_lowercase, ascii_uppercase, string.punctuation, ascii_whitespace и еще много других.
Давайте проверим эту функцию:
Для хорошо настроенной версии этой функции, этот ответ Stack Overflow использует функции генератора, привязку имени и еще несколько продвинутых хитростей, чтобы создать более быструю, криптографически безопасную версию упомянутой ранее unique_strings().
PRNG для массивов: numpy.random
Одна вещь, которую вы могли заметить, заключается в том, что большинство функций из случайного числа возвращают скалярное значение (один int, float, или другой объект). Если вы хотели сгенерировать последовательность случайных чисел, один из способов достичь этого — охватить список Python:
Есть еще один вариант, который был разработан как раз для этого. Вы можете рассматривать пакет numpy.random от NumPy как стандартный модуль random библиотеки Python, но только для массивов NumPy. (Он также имеет возможность рисовать из гораздо большего количество статистических распределений).
Обратите внимание на то, что numpy.random использует собственные PRNG, которые отделены от обычных случайных чисел. Вы не будете создавать детерминестически случайные массивы NumPy с вызовом random.seed():
Без дальнейших церемоний, вот несколько примеров, удовлетворяющих ваш аппетит:
В синтаксе для randn(d0, d1, …, dn), параметры d0, d1, …, dn являются опциональными и указывают форму итогового объекта. Здесь, np.random.randn(3, 4) создает 2d массив с 3 строками и 4 столбцами. В качестве данных будут i.i.d., что означает, что каждая точка данных создается независимо от других.
Еще одна простая операция — это создание последовательности случайных логических значений: True или False. Один из способов сделать это — использовать np.random.choice([True, False]). Однако, будет практически в 4 раза быстрее выбрать (0, 1), а затем отобразить эти целые числа в соответствующие булевские значения:
КОД # randint является [inclusive, exclusive), в отличие от random.randint()
КОД
Что на счет генерации коррелированных данных? Скажем, вы хотите симулировать два корелированных временных ряда. Один из способов сделать — это использовать функцию multivariate_normal() нашего NumPy, которая учитывает матрицу ковариации. Другими словами, чтобы списать из одной нормальной распределенной случайной переменной, вам нужно определить ее среднее значение и дисперсию (или стандартное отклонение).
Для выборки из многомерного нормального распределения, вы определяете матрицу ковариации и средние значения, в итоге вы получите несколько взаимосвязанных рядов данных, которые разделены приблизительно нормально.
Однако, в отличие от ковариации, корреляция — это более знакомая для большинства мера, к тому же более интуитивная. Это ковариация, нормализованная продуктом стандартных отклонений, так что вы можете определить ковариацию с точки зрения корреляции и стандартного отклонения:
Итак, можете ли вы списать случайные выборки из многомерного нормального распределения, определив матрицу корреляции и стандартные отклонения? Да, но вам нужно будет получить приведенную выше формулу матрицы. Здесь, S — это вектор стандартных отклонений, P — это их корреляционная матрица, и С — это результирующая (квадратная) ковариационная матрица:
Это может быть выражено в NumPy следующим образом:
Теперь, вы можете сгенерировать два временных ряда, которые коррелируют, но все еще являются случайными:
Вы можете рассматривать данные как 500 пар обратно-коррелированных точек данных. Вот проверка правильности, так что вы можете вернуться к изначальному вводу, который приблизительно соответствует corr, stdev, и mean из примера выше:
Перед тем как мы перейдем к CSPRNG, может быть полезно обобщить некоторые случайные функции и копии numpy.random:
Модуль random | Аналог NumPy | Использование |
random() | rand() | Случайное десятичное [0.0, 1.0) |
randint(a, b) | random_integers() | Случайное целое число [a, b] |
randrange(a, b[, step]) | randint() | Случайное целое число [a, b) |
uniform(a, b) | uniform() | Случайное десятичное [a, b] |
choice(seq) | choice() | Случайный элемент из seq |
choices(seq, k=1) | choice() | Случайные k элементы из seq с заменой |
sample(population, k) | choice() с параметром replace=False | Случайные k элементы из seq без замены |
shuffle(x[, random]) | shuffle() | Перемешка порядка |
normalvariate(mu, sigma) или gauss(mu, sigma) | normal() | Пример из нормального распределения со средним значением mu и стандартным отклонением sigma |
Обратите внимание: NumPy специализируется на построении и обработке больших, многомерных массивов. Если вам нужно только одно значение, то random будет достаточно, к тому же, еще и быстрее. Для небольших последовательностей, random может быть еще быстрее, так как NumPy имеет ряд дополнительных расходов.
Мы рассмотрели две фундаментальные опции PRNG, так что теперь мы можем перейти к еще более безопасным адаптациям.
CSPRNG в Python
os.urandom(): настолько случайно, на сколько возможно
Функция Python под названием os.urandom() используется как в secrets, так и в uuid (мы к ним скоро придем). Чтобы не вдаваться в лишние подробности, os.urandom() генерирует зависимые от операционной системы случайные байты, которые спокойно можно назвать криптографически надежными: