Are the numbers we generate truly random?
Introduction
Whenever we need our code to produce a random number, we usually call a method from a library to generate it for us. But are the numbers generated from the library really "random"? In this article, we take a look at Python's random module.
What Does It Mean To Be Truly Random?
To start, we should define what it means to be truly random. To generate a truly random number, the generator needs to choose a number that is unpredictable in which there is no pattern or sequence of events that we can follow to derive the same "random" number. In other words, we would need the generator to be indeterministic.
Pseudo-Random Numbers
The random numbers generated by our software are pseudo-random. We cannot generate a truly random number with the current software we have because they are deterministic. To generate pseudo-random numbers, we usually use a seed as an input to an algorithm. If we use the same seed, we will always get the same number from the algorithm. If a seed is not specified, the software will get a random number based on the machine state. In Python's case, the current system time is used as the seed.
Python's Random Library
Next, let's look at the documentation for Python's built-in Random library.
Right off the bat, Python tells us that the numbers are pseudo-random in its title.
random — Generate pseudo-random numbers
To highlight, we can see that they used the Mersenne Twister algorithm to get a random number.
Python uses the Mersenne Twister as the core generator. It produces 53-bit precision floats and has a period of 2**19937-1.
As a little exercise, let's generate a random number in Python using the random module. We will use a seed of 478.
Below is a Repl that generates a random number based on the seed “478”. You will realise that clicking on the ‘Run’ button will always give you the same result because the same seed will always return you the same number in a pseudo-random number generator.
Is Pseudo-Randomness Good Enough?
In most cases, pseudo-random algorithms are good enough, especially if we just need a random number to pick a colour for our app, or randomly shuffle a playlist.
However, there are some cases where it is not ideal to have random numbers that are predictable. For example, we would not want to use a predictable random number in cryptography. In this case, we would have to look at Cryptographically Secure Pseudorandom Number Generators.
Another example would be if we were playing an online game of Poker. If the game generated predictable random numbers, we could potentially write a program to predict the cards that will be dealt if we can figure out the algorithm and seed used.
How Can We Generate Truly Random Numbers?
Next, you might be wondering: Is it possible to generate truly random numbers? To generate truly random numbers, we would have to use an external physical variable that is unpredictable. This is also known as a Hardware Random Number Generator.
One source of unpredictability is subatomic particles. At a quantum level, they have completely random behaviour, making them a good physical source of randomness. Another example would be that in Cloudflare, lava lamps are used as a source of randomness because they are consistently random and never take the same shape twice.
Conclusion
To conclude, the numbers generated by our software are not truly random because our software are deterministic. To get a truly random number, we would have to use a physical source of randomness, such as the behaviour of subatomic particles or images of constantly moving lava lamps.