Модуль random на примерах — Изучение методов генерации случайных данных (Часть 2)

Продолжаем учиться тому, как генерировать случайные значения в Python. Ранее мы разобрали основные функции, с помощью которых можно получать псевдослучайные значения с целыми числами, числами с плавающей точкой. Также мы рассмотрели, как получать случайные элементы из заданной последовательности (списка либо строки) или перемешивать случайным образом элементы списка (подобно картам в колоде). Теперь же мы рассмотрим ряд других вопросов, в частности, особенности генерации случайной строки фиксированной длины.

Генерация случайной строки в Python

В этом разделе нам нужно рассмотреть следующие аспекты:

  1. Как получить случайную строку фиксированной длины.
  2. Как получить случайный набор букв и цифр.
  3. Как сгенерировать случайный пароль, в состав которого будут входить не только буквы и цифры, но и специальные символы.

Собственно, логика этих действий очень похожая. По мере того, как вы будете изучать эту статью дальше, вам станет более понятно, как это делать.

Но перед тем, как разбирать функции, с помощью которых вы сможете добиться этого результата, необходимо понять, как защищать генератор случайных чисел с помощью методов криптографии.

Криптографическая защита генератора случайных чисел

Модуль random в Python не защищает те значения, которые он генерирует. В свою очередь, для генерации пароля или уникального идентификатора пользователя необходимо сделать этот процесс максимально надежным. Необходимо, чтобы было соответствие следующим особенностям:

  1. Все функции возвращают байты, полученные с помощью надежного генератора случайных чисел. 
  2. Значение случайных байтов, которые получены вследствие использования функции, зависит от источников ОС. Соответственно, качество генерации также зависит от случайных источников операционной системы.

Чтобы генерация случайных значений была надежной, можно использовать такие варианты:

  1. Модуль secrets, с помощью которого можно защитить случайные значения.
  2. Модуль os.
  3. Использование класса random.SystemRandom.

А теперь приведем пример того, как можно генерировать данные в Python криптографически безопасно. 

import random

import secrets

 

 

number = random.SystemRandom().random()

print("Надежное число ", number)

 

print("Надежный токен байтов", secrets.token_bytes(16))

Результат выполнения этой функции:

Надежное число 0.11139538267693572 

Надежный токен байтов b’\xae\xa0\x91*.\xb6\xa1\x05=\xf7+>\r;Y\xc3′

Использование функций getstate() и setstate()

С помощью getstate() и setstate() модуля random можно зафиксировать текущее внутреннее состояние генератора. 

С использованием этих функций, мы можем получить одинаковое количество чисел либо последовательностей с ними.

Состояние генератора getstate()

Итак, getstate() позволяет получить определенный объект с помощью текущего внутреннего состояния генератора случайных чисел. Оно передается методу setstate(), чтобы восстановить полученное состояние в роли текущего.

Внимание. Если изменить значение текущего состояния на то, которое было до этого, мы можем получить те же данные, что и при прошлой генерации. 

То есть, эти функции могут использоваться для того, чтобы получить вновь ту же выборку данных.

Восстановление внутреннего состояния генератора

Для этого используется функция setstate(), которая относится к модулю random(). После того, как он будет запущен, функцией setstate() будет восстановлено внутреннее состояние генератора, и оно будет передано объекту.

То есть, параметр state будет использоваться тот же самый. 

Зачем используются функции getstate() и setstate()?

Если вами было получено прошлое состояние, и оно было восстановлено, то эти же данные могут использоваться многократно. Это удобно. Только следует помнить, что другая функция random использоваться в этом случае не может. Помимо этого, невозможно изменение значений заданных параметров. Если вы это сделаете, то просто измените значение state, чего нам точно не нужно.

Чтобы закрепить понимание принципов использования этих функций в генераторе случайных чисел, давайте приведем следующий пример. 

import random

 

 

number_list = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]

 

print("Первая выборка ", random.sample(number_list,k=5))

 

# хранит текущее состояние в объекте state

state = random.getstate()

 

print("Вторая выборка ", random.sample(number_list,k=5))

 

# Восстанавливает состояние state, используя setstate

random.setstate(state)

 

#Теперь будет выведен тот же список второй выборки

print("Третья выборка ", random.sample(number_list,k=5))

 

# Восстанавливает текущее состояние state

random.setstate(state)

 

# Вновь будет выведен тот же список второй выборки

print("Четвертая выборка ", random.sample(number_list,k=5))

Вывод:

Shell

Первая выборка  [18, 15, 30, 9, 6]

Вторая выборка  [27, 15, 12, 9, 6]

Третья выборка  [27, 15, 12, 9, 6]

Четвертая выборка  [27, 15, 12, 9, 6]

Обратите внимание, что нами были получены аналогичные наборы с данными.

Генерация псевдослучайных чисел с использованием numpy.random

С помощью numpy.random также можно генерировать псевдослучайные числа. Причем модуль numpy позволяет получить дополнительный набор функций для генерации случайных массивов данных с определенной «мерностью».

Давайте рассмотрим некоторые примеры.

Получение случайного n-мерного массива вещественных чисел

Есть несколько вариантов, с помощью которых можно выполнить эту задачу.

  1. Использование numpy.random.rand(), чтобы получить n-мерный массив случайных чисел с плавающей точкой в диапазоне от 0 до 1.
  2. Задействование numpy.random.uniform(), чтобы сгенерировать n-мерный массив случайных чисел с плавающей точкой в диапазоне между low, high
import numpy

 

 

random_float_array = numpy.random.rand(2, 2)

print("2 X 2 массив случайных вещественных чисел в [0.0, 1.0] \n", random_float_array,"\n")

 

random_float_array = numpy.random.uniform(25.5, 99.5, size=(3, 2))

print("3 X 2 массив случайных вещественных чисел в [25.5, 99.5] \n", random_float_array,"\n")

Результат выполнения этой функции:

2 X 2 массив случайных вещественных чисел в [0.0, 1.0] 

 [[0.08938593 0.89085866]

 [0.47307169 0.41401363]] 

 

3 X 2 массив случайных вещественных чисел в [25.5, 99.5] 

 [[55.4057854  65.60206715]

 [91.62185404 84.16144062]

 [44.348252   27.28381058]]

Генерация случайного массива целых чисел

Для получения случайного n-мерного массива необходимо использовать метод numpy.random.random_integers()

import numpy

 

 

random_integer_array = numpy.random.random_integers(1, 10, 5)

print("1-мерный массив случайных целых чисел \n", random_integer_array,"\n")

 

random_integer_array = numpy.random.random_integers(1, 10, size=(3, 2))

print("2-мерный массив случайных целых чисел \n", random_integer_array)

Получаем такой вывод:

1-мерный массив случайных целых чисел

 [10  1  4  2  1] 

 

2-мерный массив случайных целых чисел

 [[ 2  6]

 [ 9 10]

 [ 3  6]]

Выбор случайного элемента массива чисел либо последовательности

Для этого используется numpy.random.choice(). Этот же метод может использоваться для того, чтобы получить один либо несколько случайных чисел из массива определенной «мерности» с заменой либо без нее. 

Давайте приведем такой пример, чтобы вы могли увидеть, как работает эта функция. 

import numpy 

 

 

array =[10, 20, 30, 40, 50, 20, 40] 

single_random_choice = numpy.random.choice(array, size=1) 

print("один случайный выбор из массива 1-D", single_random_choice) 

 

multiple_random_choice = numpy.random.choice(array, size=3, replace=False) 

print("несколько случайных выборов из массива 1-D без замены", multiple_random_choice) 

 

multiple_random_choice = numpy.random.choice(array, size=3, replace=True) 

print("несколько случайных выборов из массива 1-D с заменой", multiple_random_choice)

После выполнения этой функции мы получаем такой вывод:

один случайный выбор из массива 1-D [40]

несколько случайных выборов из массива 1-D без замены [10 40 50]

несколько случайных выборов из массива 1-D с заменой [20 20 10]

Генерация случайных ID

А теперь рассмотрим, как можно генерировать уникальные идентификаторы пользователя (и пароли, соответственно). Полученные значения можно использовать для идентификации документов, пользователей, ресурсов либо других данных на компьютерах.

Вот пример того, как использовать uuid

import uuid

 

 

# получить уникальный UUID

safeId = uuid.uuid4()

print("безопасный уникальный id ", safeId)

Вывод:

безопасный уникальный id  fb62463a-cd93-4f54-91ab-72a2e2697aff

Игра в кости

Теперь приведем пример кода, который используется для простой игры в кости. 

import random

 

 

PlayerOne = "Анна"

PlayerTwo = "Алекс"

 

AnnaScore = 0

AlexScore = 0

 

# У каждого кубика шесть возможных значений

diceOne = [1, 2, 3, 4, 5, 6]

diceTwo = [1, 2, 3, 4, 5, 6]

 

def playDiceGame():

    """Оба участника, Анна и Алекс, бросают кубик, используя метод shuffle"""

 

    for i in range(5):

        #оба кубика встряхиваются 5 раз

        random.shuffle(diceOne)

        random.shuffle(diceTwo)

    firstNumber = random.choice(diceOne) # использование метода choice для выбора случайного значения

    SecondNumber = random.choice(diceTwo)

    return firstNumber + SecondNumber

 

print("Игра в кости использует модуль random\n")

 

#Давайте сыграем в кости три раза

for i in range(3):

    # определим, кто будет бросать кости первым

    AlexTossNumber = random.randint(1, 100) # генерация случайного числа от 1 до 100, включая 100

    AnnaTossNumber = random.randrange(1, 101, 1) # генерация случайного числа от 1 до 100, не включая 101

 

    if( AlexTossNumber > AnnaTossNumber):

        print("Алекс выиграл жеребьевку.")

        AlexScore = playDiceGame()

        AnnaScore = playDiceGame()

    else:

        print("Анна выиграла жеребьевку.")

        AnnaScore = playDiceGame()

        AlexScore = playDiceGame()

 

    if(AlexScore > AnnaScore):

        print ("Алекс выиграл игру в кости. Финальный счет Алекса:", AlexScore, "Финальный счет Анны:", AnnaScore, "\n")

    else:

        print("Анна выиграла игру в кости. Финальный счет Анны:", AnnaScore, "Финальный счет Алекса:", AlexScore, "\n")

В нашем случае у нас был следующий вывод:

Shell

Игра в кости использует модуль random

 

Анна выиграла жеребьевку.

Анна выиграла игру в кости. Финальный счет Анны: 5 Финальный счет Алекса: 2 

 

Анна выиграла жеребьевку.

Анна выиграла игру в кости. Финальный счет Анны: 10 Финальный счет Алекса: 2 

 

Алекс выиграл жеребьевку.

Анна выиграла игру в кости. Финальный счет Анны: 10 Финальный счет Алекса:

ОфисГуру
Adblock
detector