Randomness and RNG
Not all 'random' is the same. We separate the three tiers — PRNG, CSPRNG, TRNG — with plain-language analogies, real examples (Mersenne Twister, ChaCha20, hardware noise), and the jobs each is built for.
"Random number generator" covers three very different machines. Confusing them is how projects end up drawing prizes with a generator built for video-game dust particles. Here are the three tiers, what actually separates them, and where each one belongs.
A pseudo-random number generator is a deterministic formula. You give it a starting value (the seed), and it churns out a sequence that looks random but is completely fixed by that seed. Same seed, same sequence, every time.
The honest analogy: a deck of cards that was shuffled once, photographed, and is now dealt in order. Every deal looks unpredictable to someone at the table — but anyone holding the photograph knows every card that is coming.
The classic example is the Mersenne Twister, published by Matsumoto and Nishimura in 1998 and for decades the default generator in Python, R, PHP and many scientific libraries. Its numbers are superb by statistical measures — its period is 2^19937 − 1, a number with over 6,000 digits. And yet its own authors' documentation states plainly that it is not cryptographically secure: observe 624 consecutive outputs and you can reconstruct the internal state and predict everything that follows. The photograph leaks.
The same applies to xorshift128+, the engine behind JavaScript's Math.random() — we walk through its published state-recovery attack in why Math.random() must never draw a lottery.
Where PRNGs belong: simulations, games, procedural graphics, statistical sampling — anywhere you need lots of plausible randomness fast, and reproducibility from a seed is a feature (re-running a simulation) rather than a flaw. Our draw simulator is a legitimate use: it models millions of hypothetical draws where speed matters and nobody wins money on the outcome.
A cryptographically secure PRNG is still deterministic underneath — but with two properties the first tier lacks:
Analogy: the deck is still dealt by a machine, but the machine's memory sits behind a lock that scrambles everything you can see. Watching cards come out tells you nothing usable about the cards still inside — not because there is no pattern, but because extracting the pattern is computationally out of reach.
Modern CSPRNGs are built from the same primitives as encryption. The Linux kernel's random pool, for instance, generates its output with the ChaCha20 stream cipher — the design change is documented in LWN's "Replacing /dev/urandom", and ChaCha20 itself is specified in RFC 8439. Predicting the generator's next output would mean breaking ChaCha20, a cipher trusted to protect a large share of the world's internet traffic.
Where CSPRNGs belong: passwords, session tokens, encryption keys — and any draw where someone has an incentive to predict the outcome. When your browser runs our number generator, the numbers come from crypto.getRandomValues(), which is the operating system's CSPRNG surfaced to the web page (details here).
A true random number generator doesn't compute anything. It measures a physical process that is unpredictable at the level of physics: thermal noise in a resistor, jitter between oscillators, radioactive decay timing, quantum optics.
Analogy: instead of dealing from any deck, you flip a real coin — the outcome isn't stored anywhere in advance, not even in principle.
Real examples: Intel CPUs since 2012 include a hardware entropy source behind the RDRAND/RDSEED instructions, documented in Intel's Digital Random Number Generator guide — thermal noise sampled, conditioned and served to software. The engineering discipline around such devices is codified in NIST SP 800-90B, the standard for validating entropy sources.
TRNGs have their own honest weaknesses: they are slow compared to computation, the raw physical measurements are usually biased (more 1s than 0s, correlations from the circuit) and must be post-processed, and a failing or sabotaged sensor can silently degrade. That is why real systems use TRNGs to feed CSPRNGs rather than serve numbers directly: physics supplies unpredictability, cryptography supplies speed and robustness. That layered design is exactly what sits under getrandom() on Linux and BCryptGenRandom on Windows.
Where TRNGs belong: seeding everything else; standalone certified gambling hardware; lab work needing physical randomness. Ball machines in televised lottery draws are, in a sense, the oldest TRNGs in the business — mechanical chaos as entropy source (can physics predict a draw?).
| Tier | Determined by a seed? | Predictable from outputs? | Speed | Typical use |
|---|---|---|---|---|
| PRNG (Mersenne Twister, xorshift128+) | Yes | Yes — published attacks | Fastest | Simulations, games |
| CSPRNG (ChaCha20-based, OS pools) | Yes, but state is secret and refreshed | No, barring a cipher break | Fast | Keys, tokens, fair draws |
| TRNG (hardware noise) | No seed — physical measurement | No, but needs conditioning | Slow | Seeding, certified hardware |
The tiers are not "bad, good, best" — they are different tools. The failure mode that matters for a lottery site is using tier 1 where tier 2 is required. Every fairness claim on this site is built on tier 2 randomness with the bias mathematically removed — the full construction is in how we built an unbiased generator, and how certifiers audit such systems is in certified RNGs and testing labs.
Last verified: 2026-08-29