Why Random Number Generators Aren't Always Random

Miscellaneous - 3 min read - Published 2026-09-06 - Updated 2026-10-19

Computers are built to be predictable: the same input always gives the same output. That makes randomness surprisingly tricky. Yet games, simulations, raffles, shuffles and every password and encryption key depend on it. Most "random" numbers on a computer are generated by formulas, and whether that's fine depends entirely on what the numbers are for.

Pseudo-random numbers

A pseudo-random number generator (PRNG) starts from a value called a seed and applies a formula to produce a long sequence of numbers that look random and pass statistical tests. But the sequence is completely determined by the seed: start from the same seed and you get exactly the same numbers.

That's often a feature. Games use seeds so a level or world can be recreated; scientists use them so a simulation can be repeated exactly. JavaScript's Math.random and the default generators in many languages are PRNGs. They're fine for games, animations and picking a random quote, but not for anything security-related, because someone who can work out the internal state can predict every following number.

Cryptographically secure randomness

For passwords, encryption keys, session tokens and lottery-style draws, you need a cryptographically secure generator (CSPRNG). Operating systems build one by collecting unpredictable data - timing of hardware events, dedicated hardware random number circuits in modern processors - and mixing it so the output can't be predicted even by someone who has seen earlier outputs.

In browsers, crypto.getRandomValues gives access to this source; in Python it's the secrets module; most languages have an equivalent. Using the ordinary random function for a password generator is one of the most common security mistakes in code.

True random numbers

True random number generators measure physical processes that are unpredictable, such as electronic noise or radioactive decay. Some services publish random numbers from atmospheric noise, and some companies have famously used physical sources such as walls of lava lamps filmed by a camera as one input to their randomness. In practice, a well-built CSPRNG seeded from good hardware sources is indistinguishable for every everyday purpose.

Modulo bias: a subtle bug

Even with a perfect source, the way numbers are turned into a range can skew them. Suppose you take a random byte (0 to 255) and want a dice roll, so you calculate byte mod 6 and add 1. Because 256 isn't divisible by 6, the remainders 0-3 each come up 43 times out of 256 while 4 and 5 come up only 42 times. Faces 1-4 become slightly more likely than 5 and 6.

The difference is small, but for passwords, PINs, cards or anything where fairness matters, it's a real flaw. The standard fix is rejection sampling: discard any raw value from the uneven top end of the range (here, 252-255) and draw again, so every outcome is exactly equally likely.

Real randomness looks streaky

People expect random results to alternate evenly, so genuine randomness often looks suspicious. In 100 fair coin flips, there's about an 81% chance of a run of at least six identical results in a row, and about a 54% chance of seven or more. A long streak is normal, not a sign the coin is broken.

The gambler's fallacy is the belief that after a run of heads, tails is "due". It isn't: a fair coin has no memory, and the next flip is still 50/50. Music services have even described adjusting their shuffle features to be less random, because listeners hearing two songs by the same artist in a row assumed the shuffle was broken.

Choosing the right kind

For games, simulations and casual choices, a standard generator is fine, and seeding it lets you reproduce results. For anything involving security, money or fairness - passwords, keys, tokens, prize draws - use a cryptographically secure source and an unbiased method of mapping numbers to a range. If results look streaky, that's very likely just what randomness looks like.

Related Tools