Генератор псевдослучайных чисел

Функции для получения целых «случайных» чисел – randint() и randrange()

Функции randint() и randrange() генерируют псевдослучайные целые числа. Первая из них наиболее простая и всегда принимает только два аргумента – пределы целочисленного диапазона, из которого выбирается любое число:

>>> random.randint(, 10)
6

или (если импортировались отдельные функции):

>>> randint(100, 200)
110

В случае randint() обе границы включаются в диапазон, т. е. на языке математики отрезок описывается как .

Числа могут быть отрицательными:

>>> random.randint(-100, 10)
-83
>>> random.randint(-100, -10)
-38

Но первое число всегда должно быть меньше или, по-крайней мере, равно второму. То есть a <= b.

Функция randrange() сложнее. Она может принимать один аргумент, два или даже три. Если указан только один, то она возвращает случайное число от 0 до указанного аргумента. Причем сам аргумент в диапазон не входит. На языке математики – это [0; a).

>>> random.randrange(10)
4

Или:

>>> randrange(5)
0

Если в randrange() передается два аргумента, то она работает аналогично randint() за одним исключением. Верхняя граница не входит в диапазон, т. е. [a; b).

>>> random.randrange(5, 10)
9
>>> random.randrange(1, 2)
1

Здесь результатом второго вызова всегда будет число 1.

Если в randrange() передается три аргумента, то первые два – это границы диапазона, как в случае с двумя аргументами, а третий – так называемый шаг. Если, например, функция вызывается как randrange(10, 20, 3), то «случайное» число будет выбираться из чисел 10, 13, 16, 19:

>>> random.randrange(10, 20, 3)
13
>>> random.randrange(10, 20, 3)
19
>>> random.randrange(10, 20, 3)
10

How to use random.randrange()

Let’s see the syntax first

This function returns a randomly selected integer from . This function takes three parameters. Out of three parameters, two parameters are optional. i.e., and are the optional parameters.

  • The argument is the starting number in a random range. i.e., lower limit. The default value of is 0 if not specified.
  • The argument is the last number in a random range. the argument is the upper limit.
  • The is a difference between each number in the sequence. The step is optional parameters. The default value of the is 1 if not specified.

Note:

The doesn’t include the stop number while generating random integer, i.e., it is exclusive.

For example, will return any random number between 2 to 20, such as 2, 4, 6, …18. It will never select 20.

random.randrange() Examples of generating random integers within a range

Here in the following example, we are trying to print a random int in a given range. This example demonstrates all the variants of function.

Output:

Generate random number within a given range in Python 
Random integer:  7
Random integer:  22
Random integer:  180

Note: You cannot use float value .  It will raise a if you used values other than an integer.

Generate the random integer number of a specific length

What if you want to generate a random number of length ? For example, you want to generate a random number of length 4. Let see the example to generate the random number of length 4 using .

Output:

First random number of length 4 is 1931
Second random number of length 4 is 5715

Note: As you can see we set a start to 1000 and stop to 10000 because we want to generate the random number of length 4 (from 1000 to 9999).

Generate a random integer number multiple of n

In this example, we will generate a random number between x and y, which is a multiple of 3 like 3, 6, 39, 66.

Output:

Random number multiple of 3 is  264

Generate a random negative integer

Let’s see how to generate a random negative integer between -60 to -6.

Output:

Random negative integer between -60 to -6
-49

Generate random positive or negative integer

Randomly generate 1 or -1

Note: we used random.choice() to choose a single number from the list of numbers. Here our list is

Cryptographically secure random generator in Python

Random Numbers and data generated by the random module are not cryptographically secure. So  How to generate a random number that is cryptographically secure in Python?

cryptographically secure pseudo-random number generator is a random number generator which has the properties that make it suitable for use in cryptography application where data security is essential.

  • All cryptographically secure random generator function returns random bytes.
  • Random bytes returned by this function depend on the random sources of the OS. Quality of randomness depends on randoms sources of the OS.

We can use the following approaches to secure the random generator in Python cryptographically

  • The secrets module to secure random data
  • Use the os.urandom()
  • use random.SystemRandom class

Example:

Output:

secure number is  0.11139538267693572

Secure byte token b'\xae\xa0\x91*.\xb6\xa1\x05=\xf7+>\r;Y\xc3'

Refer our guides which cover the above topic in detail.

  • Cryptographically secure random data in Python.
  • Secrets module to secure random data

Замена сеттеров и геттеров на свойство Python

Давайте представим, что у нас есть код, который написал кто-то, кто не очень понимает Python. Как и я, вы скорее всего, видели такого рода код ранее:

Python

# -*- coding: utf-8 -*-
from decimal import Decimal

class Fees(object):
«»»»»»
def __init__(self):
«»»Конструктор»»»
self._fee = None

def get_fee(self):
«»»
Возвращаем текущую комиссию
«»»
return self._fee

def set_fee(self, value):
«»»
Устанавливаем размер комиссии
«»»
if isinstance(value, str):
self._fee = Decimal(value)
elif isinstance(value, Decimal):
self._fee = value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# -*- coding: utf-8 -*-

fromdecimalimportDecimal

classFees(object)

«»»»»»

def__init__(self)

«»»Конструктор»»»

self._fee=None

defget_fee(self)

«»»

        Возвращаем текущую комиссию
        «»»

returnself._fee

defset_fee(self,value)

«»»

        Устанавливаем размер комиссии
        «»»

ifisinstance(value,str)

self._fee=Decimal(value)

elifisinstance(value,Decimal)

self._fee=value

Для использования этого класса, нам нужно использовать сеттеры и геттеры, которые определены как:

Python

f = Fees()
f.set_fee(«1»)

print(f.get_fee()) # Decimal(‘1’)

1
2
3
4

f=Fees()

f.set_fee(«1»)

print(f.get_fee())# Decimal(‘1’)

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

Python

# -*- coding: utf-8 -*-
from decimal import Decimal

class Fees(object):
«»»»»»
def __init__(self):
«»»Конструктор»»»
self._fee = None

def get_fee(self):
«»»
Возвращаем текущую комиссию
«»»
return self._fee

def set_fee(self, value):
«»»
Устанавливаем размер комиссии
«»»
if isinstance(value, str):
self._fee = Decimal(value)
elif isinstance(value, Decimal):
self._fee = value

fee = property(get_fee, set_fee)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# -*- coding: utf-8 -*-

fromdecimalimportDecimal

classFees(object)

«»»»»»

def__init__(self)

«»»Конструктор»»»

self._fee=None

defget_fee(self)

«»»

        Возвращаем текущую комиссию
        «»»

returnself._fee

defset_fee(self,value)

«»»

        Устанавливаем размер комиссии
        «»»

ifisinstance(value,str)

self._fee=Decimal(value)

elifisinstance(value,Decimal)

self._fee=value

fee=property(get_fee,set_fee)

Мы добавили одну строк в конце этого кода. Теперь мы можем делать что-то вроде этого:

Python

f = Fees()
f.set_fee(«1»)
print(f.fee) # Decimal(‘1’)

f.fee = «2»
print( f.get_fee() ) # Decimal(‘2’)

1
2
3
4
5
6

f=Fees()

f.set_fee(«1»)

print(f.fee)# Decimal(‘1’)

f.fee=»2″

print(f.get_fee())# Decimal(‘2’)

Как мы видим, когда мы используем свойство таким образом, это позволяет свойству fee настраивать и получать значение без поломки наследуемого кода. Давайте перепишем этот код с использованием декоратора property, и посмотрим, можем ли мы получить его для разрешения установки.

Python

# -*- coding: utf-8 -*-
from decimal import Decimal

class Fees(object):
«»»»»»
def __init__(self):
«»»Конструктор»»»
self._fee = None

@property
def fee(self):
«»»
Возвращаем текущую комиссию — геттер
«»»
return self._fee

@fee.setter
def fee(self, value):
«»»
Устанавливаем размер комиссии — сеттер
«»»
if isinstance(value, str):
self._fee = Decimal(value)
elif isinstance(value, Decimal):
self._fee = value

if __name__ == «__main__»:
f = Fees()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# -*- coding: utf-8 -*-

fromdecimalimportDecimal

classFees(object)

«»»»»»

def__init__(self)

«»»Конструктор»»»

self._fee=None

@property

deffee(self)

«»»

        Возвращаем текущую комиссию — геттер
        «»»

returnself._fee

@fee.setter

deffee(self,value)

«»»

        Устанавливаем размер комиссии — сеттер
        «»»

ifisinstance(value,str)

self._fee=Decimal(value)

elifisinstance(value,Decimal)

self._fee=value

if__name__==»__main__»

f=Fees()

Данный код демонстрирует, как создать сеттер для свойства fee. Вы можете делать это, декорируя второй метод, который также называется fee с декоратором, под названием <@fee.setter>. Сеттер будет вызван, когда вы сделаете что-то вроде следующего:

Python

f = Fees()
f.fee = «1»

1
2

f=Fees()

f.fee=»1″

Если вы взгляните на подписи под свойством, то это будут fget, fset, fdel и doc в качестве аргументов. Вы можете создать другой декорируемый метод, используя то же название связи с функцией delet при помощи <@fee.deleter*>*, если вы хотите поймать команду **del для атрибута.

Generate a secure random integer

Above all examples are not cryptographically secure. The cryptographically secure random generator generates random numbers using synchronization methods to ensure that no two processes can obtain the same number at the same time. If you are producing random numbers for a security-sensitive application, then you must use this approach.

If you are using Python version less than 3.6, and want to generate cryptographically secure random integer then use the   or functions. Refer to How to secure random data in Python.

Example:

Output:

Secure random integer is 30
Secure random integer is 162

If you are using Python version higher than 3.6 you can use the secrets module to generate a secure random integer.

Output:

Random integer generated using secrets module is 
8

Read More:

  • Secure random data in python.
  • Python secrets module

Use random.choice() to Randomly select an item from a list

Let assume you have the following movies list and you want to pick one movie from it randomly. Now, Let’s see the example to pick a random choice from a list of strings.

movie_list = 

In this example, we are using a to select an item from the above list randomly.

Output:

Randomly selected item from a list using random.choice is - The Shawshank Redemption
Randomly selected item from a list using random.choice is - The Godfather

As you can see we executed function two times and every time we got a different item from a list. Also, there are other ways to randomly select an item from a list lets see those now.

Why Not Just “Default to” SystemRandom?#

In addition to the secure modules discussed here such as , Python’s module actually has a little-used class called that uses . (, in turn, is also used by . It’s all a bit of a web that traces back to .)

At this point, you might be asking yourself why you wouldn’t just “default to” this version? Why not “always be safe” rather than defaulting to the deterministic functions that aren’t cryptographically secure ?

I’ve already mentioned one reason: sometimes you want your data to be deterministic and reproducible for others to follow along with.

But the second reason is that CSPRNGs, at least in Python, tend to be meaningfully slower than PRNGs. Let’s test that with a script, , that compares the PRNG and CSPRNG versions of using Python’s :

Now to execute this from the shell:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *