Web Tools

How Random Number Generators Work

Updated 11 May 20267 minReviewed for accuracy

When you ask a computer for a random number, it almost never gives you one. Most "random" numbers are pseudorandom, produced by deterministic algorithms that look random and pass statistical tests but are technically predictable if you know the starting state. True random numbers exist, but they require physical sources of entropy and are rarely needed for everyday tasks.

Key Takeaways

  • Pseudorandom Number Generators (PRNGs) use deterministic algorithms with a seed.
  • True Random Number Generators (TRNGs) draw entropy from physical processes: radioactive decay, thermal noise, mouse movements.
  • Most software (games, simulations, dice rollers) uses PRNGs because they're fast and reproducible.
  • Cryptography requires special "cryptographically secure" PRNGs (CSPRNGs) or true random sources.
  • "Random" output is usually uniformly distributed; biased distributions are built on top.

What a Computer Means by "Random"

Computers are deterministic: they do exactly what their code tells them, in exactly the same order, every time. That makes generating actual randomness hard. To produce numbers that look random, computers use mathematical algorithms that take a starting value (a seed) and crunch through a long, complex computation that produces outputs that pass statistical tests for randomness.

The trick: if you know the algorithm and the seed, you can reproduce the entire sequence. So pseudorandom numbers are random-looking, not random.

Pseudorandom Number Generators (PRNGs)

A PRNG is defined by:

  1. A seed (initial value)
  2. A state (the internal variables of the algorithm)
  3. A transition function that maps current state to next state
  4. An output function that maps state to a number

The same seed always produces the same sequence. Different seeds produce different sequences. Good PRNGs produce sequences that are statistically indistinguishable from true randomness over reasonable lengths.

Common PRNG algorithms

Linear Congruential Generator (LCG): The simplest PRNG. Each new number is calculated from the previous one:

X_{n+1} = (a × X_n + c) mod m

With well-chosen a, c, and m, LCGs produce decent-looking sequences. They are fast, simple, and used in many old programming language libraries. They are not strong enough for serious simulation or cryptography.

Mersenne Twister: Developed in 1997, this has been the default PRNG in most languages (Python's random, MATLAB, Excel) for decades. It has a period of 2^19937 − 1, meaning the sequence repeats only after that many numbers, effectively never. It passes nearly all statistical tests but is not cryptographically secure.

Xorshift / PCG / Splitmix: Modern alternatives that are faster than Mersenne Twister and offer similar or better statistical quality. PCG (Permuted Congruential Generator) has become a popular choice for high-performance applications.

Cryptographically Secure PRNGs (CSPRNGs): Algorithms like ChaCha20, AES in counter mode, or specialized hash-based generators (HMAC-DRBG). These are slower but provide cryptographic guarantees: even with substantial output, an attacker cannot predict the next number without knowing the seed.

True Random Number Generators (TRNGs)

For genuine randomness, hardware draws entropy from physical processes:

  • Thermal noise in electronic circuits
  • Atmospheric noise captured by radio receivers
  • Photonic shot noise from light detectors
  • Radioactive decay timings
  • Mouse movements, keystroke timings, network jitter as entropy sources

Modern CPUs include hardware RNGs (Intel's RDRAND, AMD's equivalent) that produce true random bytes from on-chip noise. Operating systems pool entropy from many sources to seed their secure PRNGs.

For most non-cryptographic uses, a high-quality PRNG seeded from system entropy is indistinguishable from true randomness, and much faster.

Seeding: The Critical Step

A PRNG's output is only as random as its seed. Common seeding strategies:

Time-based: seed = current time. Works for casual use; predictable if an attacker knows when you ran the code. Bad for cryptography.

Process ID-based: uses operating system identifiers. Slightly less predictable than time but still weak alone.

OS entropy pool: modern systems maintain a kernel entropy pool from hardware sources. Calling os.urandom() or reading /dev/urandom produces seed material with strong randomness.

Hardware RNG: RDRAND or equivalent reads directly from hardware noise.

For anything cryptographic: always seed from the OS entropy pool or hardware. For casual simulations: time-based is fine.

Uniform vs Other Distributions

Most RNGs output uniformly distributed numbers: every value in the range is equally likely. To produce numbers from other distributions:

Range mapping: to get an integer between 1 and 100, generate a uniform [0, 1) float and compute floor(rand × 100) + 1. (Be careful with off-by-one issues at the upper bound.)

Bernoulli (coin flip): generate uniform [0, 1); if < 0.5, return heads, else tails. For weighted coins, change the threshold.

Discrete choice: assign probabilities summing to 1; generate uniform, find which range it falls in.

Normal distribution: the Box-Muller transform converts two uniform values into two normally distributed values. Most languages have built-in randn or normalvariate functions.

Exponential, Poisson, other distributions: use the inverse CDF method or specialized algorithms.

Worked Example: Drawing from a Weighted List

You have four items with weights [10, 20, 30, 40]. Total: 100. To pick one randomly:

  1. Generate uniform random number in [0, 100): say 67.5.
  2. Walk through cumulative thresholds: 10 (no), 30 (no), 60 (no), 100 (yes, so pick item 4).

This produces samples proportional to weights. The math is just dividing the unit interval into chunks.

Common Mistakes

Using a weak PRNG for security. Mersenne Twister, LCG, and Math.random() in browsers are NOT cryptographically secure. Use platform-provided crypto APIs for anything sensitive.

Reusing seeds across sessions. If your "random" daily password starts from the same seed every day, it's the same password every day.

Sampling with modulo bias. rand() % n produces biased output if n doesn't divide the RNG's range evenly. Modern libraries handle this; manual implementations often don't.

Trusting client-side randomness. Browser Math.random() is fast but not secure. Anything cryptographic must be server-side or via crypto APIs.

Confusing pseudorandom with predictable. Pseudorandom output is statistically indistinguishable from random unless you know the seed. Reasonable for most purposes.

Picking the wrong distribution. "Random between 1 and 100" usually means uniform. But "random word length" might be normal, log-normal, or something else entirely. Match the distribution to the use case.

Cryptographic vs Casual Randomness

Use CaseRequired Strength
Game dice rollsCasual PRNG fine
Statistical simulationGood PRNG (Mersenne Twister, PCG)
Picking a winner from a listCasual PRNG with good seed
Password generationCSPRNG (cryptographic)
Encryption keysCSPRNG, ideally with hardware entropy
Token generation (sessions, API keys)CSPRNG
Online lottery (regulated)TRNG or audited CSPRNG

The general rule: if the cost of someone predicting the output is significant, use cryptographic randomness.

Practical Scenarios

Scenario 1: Web app dice roller. Browser Math.random() is fine. Game players wouldn't gain anything by predicting it, and the performance is excellent.

Scenario 2: Password generator. Use crypto.getRandomValues() in browsers or secrets module in Python. Never use Math.random() or basic random modules for password material.

Scenario 3: A/B test assignment. Hash the user ID with a salt; assign based on the hash modulo number of variants. Reproducible (same user always gets same variant) and unbiased.

Scenario 4: Monte Carlo simulation. Mersenne Twister or PCG. Speed matters; cryptographic strength does not.

Scenario 5: Random shuffling. Use the Fisher-Yates algorithm with a good PRNG. Naive sort-by-random-key produces biased results.

How to Test for Randomness

You cannot prove a sequence is random; you can only fail to disprove it. Statistical tests check whether a sequence behaves like a true random sequence:

  • Chi-squared test: does the distribution match the expected uniform distribution?
  • Runs test: are sequences of identical outcomes about as long as expected?
  • Spectral test: do successive pairs fill the plane uniformly?
  • Diehard tests / TestU01: standardized batteries of tests for PRNGs.

Modern PRNGs (Mersenne Twister, PCG, Xoshiro) pass these tests. Weak PRNGs (basic LCGs) often fail.

FAQ

Are computer random numbers truly random? Usually no. They're pseudorandom, generated by deterministic algorithms from a seed. The output looks random and passes statistical tests, but is predictable if you know the seed.

What is a PRNG? A Pseudorandom Number Generator: an algorithm that produces sequences of numbers that look random, starting from a seed value. The same seed always produces the same sequence.

What is a seed? The starting value for a PRNG. Different seeds produce different sequences; the same seed always reproduces the same sequence.

Is Math.random() in JavaScript secure? No. Math.random() is suitable for games and casual use but not for cryptography. Use crypto.getRandomValues() for anything security-related.

What is a CSPRNG? A Cryptographically Secure Pseudorandom Number Generator. Designed so that even with substantial output observed, an attacker cannot predict future values without the seed.

How do online dice rollers work? Most use the client's built-in PRNG (e.g., Math.random()). Some draw from server-side random sources for stronger guarantees. For everyday games, either is fine.

Can I make a true random number generator at home? Yes. Read system entropy via /dev/random on Linux or crypto.randomBytes() in Node.js. These use hardware entropy where available.

Related Tools

The Random Number Generator produces uniformly random integers over any range. For dice and coin scenarios specifically, use the Coin Flip Simulator and Dice Roller. For probability questions, see the Probability Calculator.

Related Articles

Final Thoughts

True randomness is rare in computers; pseudorandomness is everywhere and usually sufficient. Knowing the difference matters when stakes rise (passwords, encryption keys, regulated drawings), but for everyday simulation, gaming, and casual randomness, a well-seeded PRNG produces output that no human (and no statistical test) can distinguish from "true" random. The deep beauty of the field is that determinism, applied cleverly enough, becomes indistinguishable from chaos.