**Disclosure**: This post may contain affiliate links, meaning when you click the links and make a purchase, we receive a commission.

Randomness is found everywhere, from Cryptography to Machine Learning. Without random number generation, many things would be impossible to accomplish; in the case of cryptography, everything would be predictable and easy to break.

A random number generator (RNG) is a system (software or hardware component) that generates a sequence of random numbers from a true source of randomness, which can be reliable for cryptographic use. However, there are pseudo-random number generators (PRNG), which generate random numbers that look random, but are actually deterministic, which means we can reproduce it if the state (or seed) of the PRNG is known.

In this tutorial, you will learn how you can generate random numbers, strings, and bytes in Python using the built-in random module; this module implements pseudo-random number generators (which means, you shouldn't use it for cryptographic use, such as key or password generation).

We will also explore the secrets module for generating cryptographically secure random numbers suitable for passwords, encryption keys, account authentication, and related secrets. In the file encryption tutorial, we have used the `secrets`

module to derive encryption keys; make sure to check it out if you're curious.

We also used `secrets`

and `random`

modules to generate random passwords.

Note that there are definitely easier ways to generate random data, especially in Linux. However, the goal of this tutorial is to how to use Python for that.

**Related**: How to Use Pickle for Object Serialization in Python.

Table of content:

- Generating Random Integers
- Randomly Choosing Elements
- Generating a Random Vector
- Generating a Random Matrix
- Generating Floating-Point Numbers
- Shuffling Sequences
- Generating Strings
- Cryptographically Secure Generation

To generate random integers, we can either use `random.randint()`

or `random.randrange()`

functions, let's see the difference:

```
import random
import os
import string
import numpy as np
# generate random integer between a and b (including a and b)
randint = random.randint(1, 500)
print("randint:", randint)
# generate random integer from range
randrange = random.randrange(0, 500, 5)
print("randrange:", randrange)
```

Output:

```
randint: 87
randrange: 80
```

`random.randint()`

function returns a random integer between a and b (in this case, 1 and 500) which includes a and b, in other words: a<= x <=b.

Whereas `random.randrange()`

chooses a random item from that range (start=0, stop=500, step=5), which can be 0, 5, 10, 15 and so on, until 500.

Let's say we have a big list of elements, and we want to randomly select one item, `random.choice()`

comes into the rescue:

```
# get a random element from this list
choice = random.choice(["hello", "hi", "welcome", "bye", "see you"])
print("choice:", choice)
```

This will randomly choose one element from that list. Here is the output:

`choice: hi`

If you wish to select more than one element once, you can use `random.choices()`

function instead:

```
# get 5 random elements from 0 to 1000
choices = random.choices(range(1000), k=5)
print("choices:", choices)
```

This will select 5 elements from that range:

`choices: [889, 832, 537, 110, 130]`

For data science and machine learning use, you may want to use Numpy to generate random vectors and matrices of the desired shape. Let's generate a vector of size 20 where the values range from 0 to 1:

```
# get a random vector of size 20
vector = np.random.random((30,))
print("vector:\n", vector)
```

Output:

```
vector:
[0.46724415 0.75177385 0.9832122 0.01245131 0.35557827 0.34014858
0.60991217 0.21269721 0.45915176 0.84400412 0.85336154 0.84169998
0.41310374 0.80452164 0.92334229 0.75396105 0.47011402 0.2941423
0.35021264 0.82592184 0.85020283 0.31313478 0.27498346 0.71593234
0.20603687 0.31449463 0.60271275 0.28838185 0.47468129 0.18365603]
```

If you don't have NumPy installed, simply install using pip install numpy.

You can also generate a random matrix using the same np.random.random() function, this time we generate the values between 0 and 100:

```
# get a random matrix of size (3, 3) in the range [0, 100]
matrix = np.random.random((3, 3)) * 100
print("matrix:\n", matrix)
```

Output:

```
matrix:
[[22.40423343 17.06827518 79.81260103]
[74.79307033 83.86064577 92.8321372 ]
[53.75464161 61.92659985 53.06586537]]
```

You can also generate floating-point numbers:

```
# generate a random floating point number from 0.0 <= x <= 1.0
randfloat = random.random()
print("randfloat between 0.0 and 1.0:", randfloat)
```

Output:

`randfloat between 0.0 and 1.0: 0.49979177801639296`

If you want to generate a float between 2 numbers, you can use `random.uniform()`

function:

```
# generate a random floating point number such that a <= x <= b
randfloat = random.uniform(5, 10)
print("randfloat between 5.0 and 10.0:", randfloat)
```

This will generate any float between 5 and 10:

`randfloat between 5.0 and 10.0: 5.258643397238765`

In order to randomly shuffle any iterable in Python, you can use `random.shuffle()`

function, here is an example:

```
l = list(range(10))
print("Before shuffle:", l)
random.shuffle(l)
print("After shuffle:", l)
```

Output:

```
Before shuffle: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After shuffle: [7, 8, 4, 5, 6, 9, 2, 1, 0, 3]
```

There isn't a direct way to generate random strings in the `random`

module. However, we can use the `random.sample()`

or `random.choices()`

functions to randomly select characters from a list of characters:

```
# generate a random string
randstring = ''.join(random.sample(string.ascii_letters, 16))
print("Random string with 16 characters:", randstring)
```

This will generate 16 characters (as we specified) from `string.ascii_letters`

which includes all ASCII characters:

`Random string with 16 characters: MjIRHEGnxCSNeAiv`

You can also add numbers by using `string.ascii_letters + string.digits`

, or you can use only lowercase characters by using `string.ascii_lowercase`

.

As we mentioned previously, the random module is extremely insecure for password generation or any cryptographic use. In fact, you can even use `random.seed()`

function to set the seed of randomness, which will generate the same sequence of numbers every time you run the program. This can be useful for machine learning or other purposes.

However, for cryptographic use, you should use the secrets module instead; the below lines of code randomly generate different types of data securely:

```
# crypto-safe byte generation
randbytes_crypto = os.urandom(16)
print("Random bytes for crypto use using os:", randbytes_crypto)
# or use this
randbytes_crypto = secrets.token_bytes(16)
print("Random bytes for crypto use using secrets:", randbytes_crypto)
# crypto-secure string generation
randstring_crypto = secrets.token_urlsafe(16)
print("Random strings for crypto use:", randstring_crypto)
# crypto-secure bits generation
randbits_crypto = secrets.randbits(16)
print("Random 16-bits for crypto use:", randbits_crypto)
```

Here is the output:

```
Random bytes for crypto use using os: b'\xf4\xa1\xed\xb3\xef)\xfe\xd2\xe6\x86\xdb&=\xff\xf5\x9c'
Random bytes for crypto use using secrets: b'\x99^\x96\x90\xe93[\x1d\x86C\xe8\xcf\x1f\xa3\x06\x86'
Random strings for crypto use: RJDD-8iCEsAuDC1-N9EbQA
Random 16-bits for crypto use: 2371
```

**Learn also:** How to Use Hash Algorithms in Python using hashlib.

In practice, you should use the random module for statistical modeling, simulation, machine learning, and other purposes (you can also use numpy's random module to generate random arrays), to generate random data reproducible, which are significantly faster than cryptographically secure generators.

You should only use the secrets module for cryptographic applications where data security is critical.

For further information, you can check Python's official documentation for different modules used in this tutorial:

- random — Generate pseudo-random numbers
- secrets — Generate secure random numbers for managing secrets
- string — Common string operations

**Learn also:** How to Make a Simple Math Quiz Game in Python.

Finally, many of the Python and cryptography concepts aren't discussed in detail here. If you feel you want to dig more into Python and cryptography, I highly suggest you get these courses:

Happy Generating ♥

View Full CodeJOIN OUR NEWSLETTER THAT IS FOR PYTHON DEVELOPERS & ENTHUSIASTS LIKE YOU !