The CPU of a computer is essentially a massive binary calculator, and while it is completely deterministic, high-energy particles have the potential to flip some bits in the RAM or certain CPU registers, leading to rare instances of unpredictability. This could theoretically be a valuable source of random numbers, but unfortunately, our planet's magnetic field filters out a significant number of these particles from the universe. As a result, we are unable to generate a large quantity of truly random numbers based on this phenomenon. You can observe these particles at home using the Wilson chamber. It is a useful tool for visualizing the presence of high-energy particles in a given environment. By detecting the trails left by these particles as they pass through a superheated gas.

Good random sources

Random numbers play a crucial role in the field of cryptography, especially when security is a top priority. One way to generate random numbers in a highly secure manner is through the use of radioactive isotopes with a predictable half-life period. By registering the decay of these isotopes, we can produce truly random numbers that are virtually impossible to predict or reproduce.

Another way to generate random numbers is through the use of various sources of noise, such as radio noise, the blinking of starlight, and even the movements of the wind. These types of noise can be measured and analyzed to produce random data that is highly unpredictable.

Some unconventional methods for generating random numbers have also been explored, such as using the movements of lava lamps to produce random data. While these methods may seem unconventional, they can be highly effective in producing truly random numbers that are not easily predictable.

In summary, the security of many cryptographic systems relies heavily on the quality of the random numbers they use. By utilizing a variety of different sources of randomness, we can produce highly secure and unpredictable data that is essential for ensuring the safety and integrity of sensitive information.

A common usage of randomness in cryptography is in the process of generation the cryptographic keys. Cryptographic keys are used to encrypt and decrypt data and are typically created using high-quality random numbers.

For example, let's say a company wants to send sensitive data over the internet to another company. They generate a cryptographic key using a reliable source of randomness, such as a hardware-based random number generator. The key is then used to encrypt the data before it is sent over the internet, making it unreadable to anyone without the key.

If the key was not generated using truly random data, an attacker may be able to guess or reproduce the key and gain access to the sensitive data. However, by using high-quality random data to generate the key, the encryption becomes much more secure and resistant to attacks.


As I mentioned earlier — computers are deterministic machines that operate based on predefined rules. However, certain techniques can be used to generate sequences of numbers that appear random, such as pseudorandom number generators. These random-looking sequences are useful in various fields, including cryptography, simulation, and game design.

Do not use this in anything near production

For example, lets have some randomCollector with 0 value and getRandom function which would add 123 to the randomCollector, multiply the result by 987, divide by randomCollector mod 45, take the modulo 32768, and write the result back to the randomCollector. As a random number we would return randomCollector divided by 64. Let's test how random the result numbers are. I would draw 256 random numbers [0, 32] each frame:

px.frameRate = 6 var randomCollector = 0, getRandom = function() { randomCollector += 123; randomCollector *= 987; randomCollector /= randomCollector % 45; randomCollector %= 32768; return randomCollector % 32 |0; }; update = function() { clear(); for( var x = 0; x < w; x++ ) { point( x, getRandom(), 0x307020 ) } };

Looks quiet random. Let's see how 32*128 of such numbers are distributed. Our random function return numbers in range [0,31], so each row length represent how much numbers had value equal to the number of the row.

update = function() { clear(); var randoms = []; for( var i = 0; i < 32; i++ ) randoms[ i ] = 0; for( var i = 0; i < 32 * 128; i++ ) randoms[ getRandom() ]++; // Draw it for( var i = 0; i < 32; i++ ) rect( 0, i, randoms[ i ], 1, 0xff0000 ); };

It looks well distributed, but lets take some other values in the getRandom function:

var randomCollector = 0, getRandom = function() { randomCollector += 13; randomCollector *= 2233; randomCollector %= 32768; randomCollector *= randomCollector % 34; return randomCollector % 32 | 0; }; update = function() { clear(); for( var x = 0; x < w; x++ ) { point( x, getRandom(), 0x307020 ) } };

And here is the distribution

update = function() { clear(); var randoms = []; for( var i = 0; i < 32; i++ ) randoms[ i ] = 0; for( var i = 0; i < 32 * 128; i++ ) randoms[ getRandom() ]++; // Draw it for( var i = 0; i < 32; i++ ) rect( 0, i, randoms[ i ], 1, 0xff0000 ); };

Random in games

When you play some RPG there usually a lot of probability values around. For example if a sword have 10% chance of critical hit — player would assume that at least each 10 attack would be critical.

I've tested how often such random event happens. On 100000 cases I've got ~1000 events, but they were not distributed normally. Here are the numbers of not critical hit's in a row: 3, 8, 1, 5, 23, 4, 10, 10, 1, 1, 17, 11, 14, 1, 23, 8, 14, 7, 8, 3, 7, 6, 9, 1, 8, 9, 31, 39, 7, 3, 10. Player would be really upset if such a good sword would not make a critical hit for 30 hits.

Because of such expectations developers make random that looks more legit by making real probabilities higher, or by counting times when skill was not activated. For example with this 10% crit sword — it would look fair if at least the 15-th hit would be critical.

Seeded random

Seeded random is a pseudo random generator that have some collector. If we set this collector into some value — we would get the same randomly looking sequence.

In my projects I use the mulberry32 pseudo-random generator. It is quite fast and author declares that it passes all tests of gjrand testing suite and has a full 232 period.

Here is the code:

function mulberry32(a) {
    return function() {
      var t = a += 0x6D2B79F5;
      t = Math.imul(t ^ t >>> 15, t | 1);
      t ^= t + Math.imul(t ^ t >>> 7, t | 61);
      return ((t ^ t >>> 14) >>> 0) / 4294967296;

And here you can try it. It would generate a list of numbers [0, 999] when you change the seed. Backgrounds are also randomized with the same seed: