📖 Guide

Random Numbers: True, Pseudo-Random and Cryptographically Secure

Why your computer can't generate true randomness, the difference between Math.random() and crypto.getRandomValues(), and when it matters.

Ad Slot. Top Banner

Your Computer Cannot Roll Dice

Every random number your computer produces follows a formula. Run the same formula with the same starting value and you get the same sequence every time. That predictability, acceptable for a game or a simulation, becomes catastrophic for a password or an encryption key. In 2012, researchers discovered that 0.2% of all RSA public keys on the internet shared prime factors, a flaw traceable directly to weak pseudorandom number generation during key creation. Attackers extracted private keys from roughly 27,000 certificates.

The difference between a safe and unsafe random number comes down to the source of entropy (unpredictability) and the algorithm that processes it. This guide separates true randomness from pseudorandomness, explains how the linear congruential generator (the most common PRNG) works step by step, and maps each type of randomness to the applications that require it.

By the end you'll understand why picking lottery numbers with a PRNG gives you no advantage, why simulations use PRNGs on purpose, and what hardware randomness sources measure.

True Random vs Pseudorandom: Two Different Things

True random numbers come from physical processes that are unpredictable: thermal noise in a resistor, radioactive decay timing, atmospheric noise, photon arrival times. The output cannot be predicted even with full knowledge of the system. Hardware devices like random.org (which uses atmospheric radio noise) or Intel's RDRAND instruction (which samples thermal noise in a ring oscillator) generate true random numbers. True randomness is expensive in compute terms and produces bits at a limited rate.

Pseudorandom numbers come from deterministic algorithms initialized with a starting value called a seed. Given the same seed, a PRNG produces the same sequence. The output looks statistically random, it passes tests for uniform distribution, low correlation, and long period, but it is entirely predictable if you know the seed and the algorithm. JavaScript's Math.random(), Python's random module, and Excel's RAND() function all use PRNGs.

Cryptographically secure pseudorandom number generators (CSPRNGs) sit between the two. They use a PRNG internally but seed it from a true random source (OS entropy pool) and apply algorithms designed to make forward and backward prediction computationally infeasible. In Linux, /dev/urandom draws from hardware events (interrupt timing, network packet timing, disk access). In browsers, crypto.getRandomValues() uses the OS CSPRNG. CSPRNGs are fast enough for practical use and unpredictable enough for security.

A uniform distribution means every value in the range has equal probability. A PRNG for integers from 1 to 100 should produce each number with probability 1/100 over many draws. Quality PRNGs achieve this with period lengths exceeding 219937 before repeating.

How a PRNG Works: The Linear Congruential Generator

The linear congruential generator (LCG) is the simplest common PRNG. Its formula:

Xn+1 = (a × Xn + c) mod m

Where: Xn is the current value (seed for the first step), a is the multiplier, c is the increment, and m is the modulus. The output sequence cycles through at most m values before repeating.

A toy example with a = 5, c = 1, m = 16, seed X0 = 3:

  • X1 = (5 × 3 + 1) mod 16 = 16 mod 16 = 0
  • X2 = (5 × 0 + 1) mod 16 = 1
  • X3 = (5 × 1 + 1) mod 16 = 6
  • X4 = (5 × 6 + 1) mod 16 = 31 mod 16 = 15

The sequence continues until it loops back to 3. For m = 16, the maximum period is 16. Real-world LCGs use 64-bit or 128-bit moduli with carefully chosen multipliers (the Mersenne Twister, common in many languages, uses m = 219937 - 1, giving a period that won't repeat within any human timescale).

To convert the raw output to a range [1, n]: divide the PRNG output by m to get a float between 0 and 1, then multiply by n and take the floor, adding 1. For a die roll (n = 6): floor(output/m × 6) + 1. This approach has a tiny modulo bias when m isn't a multiple of n, which cryptographically secure generators eliminate by rejection sampling.

Ad Slot — In-Content

Common Misconceptions

  • Picking "lucky" lottery numbers improves your odds. Every combination of 6 numbers from 49 has probability 1 in 13,983,816. The numbers you pick have no effect on this probability. The machine drawing balls generates true random outcomes; your choice of numbers is independent of the result.