# Generate Cryptographically Secure Numbers in Python 3.6+

The most common way to generate random numbers in Python that you probably know is using Python's random module:

```
import random
# Generate a random integer between an interval
>>> random.randint(1, 100) # returns 4, for example
4
# Randomly choose an element from a sequence
>>> numbers = [1, 2, 3, 4, 5]
>>> random.choice(numbers) # returns 2, for example
2
```

*You can check all the possibilities in the docs*

Python's random module implements pseudo-random number generators, which means they can be used for modelling and simulation.

However, they are not recommended in applications where guarantee randomness is key (such as lotteries, tokens, safe passwords, etc) or other security-sensitive applications.

Fortunately, if you are using Python 3.6 (or higher) you can take advantage of secrets module to generate Cryptographically Secure Random Numbers. It generates random data using synchronization methods to ensure that **no two processes can obtain the same data at the same time**.

Note: If you are using a Python version < 3.6 you can use

`os.urandom()`

and`random.SystemRandom`

class to cryptographically secure random generator (In fact, secrets module is based on them).

This is how we can use secrets in Python:

```
import secrets
# Generate a random number between 0 and a number
secrets.randbelow(100) # returns 34, for example
# Randomly choose an element from a sequence
numbers = [1, 2, 3, 4, 5]
secrets.choice(numbers) # returns 4, for example
```

secrets also has some handy goodies to deal with tokens like:

```
>>> secrets.token_urlsafe(16) # 16 random bytes, it could be empty
'dCfl7o42IJFfFXY-M9JaxA'
```

Hope you find it useful