Blog
How Do Random Number Generators Actually Work?
How random number generators work — true vs pseudo randomness, crypto.getRandomValues, uniform distribution, and getting fair draws every time.
August 11, 2026 · Updated September 17, 2026
Every time you hit Generate on this site, your browser produces numbers that look random — but “random” is a word with a lot of history behind it. Let’s unpack what’s really happening, from dice and roulette wheels to the cryptography inside your browser. If you’d rather skip the theory, you can jump straight to the random number generator and try it below, on the homepage.
What is a random number generator, anyway?
A random number generator (RNG) is any process that produces a sequence of values with no discernible pattern — where each number is independent of the ones before it. You already rely on them every day, often without noticing:
- Shuffling a music playlist or a card game
- Rolling dice in a board game or RPG
- Drawing a winning raffle or lottery ticket
- Spawning items, enemies, or loot in video games
- Picking a random sample for a survey or experiment
In code, an RNG is a function you can call again and again:
rng() // 73
rng() // 11
rng() // 58
rng() // 90
The output changes every time, and nothing about 73, 11, and 58 lets you guess what comes next. But “looks random” and “is random” are very different claims — and that gap is where all the interesting engineering lives.
The old way: physical randomness
For thousands of years, randomness came from physics. A coin toss, a shuffled deck, a spinning wheel — these all depend on tiny, hard-to-predict forces: air resistance, friction, how hard you flick your wrist.
That’s real randomness, in the strict sense. A truly random event can’t be predicted, even in principle, because it’s driven by processes nobody can fully model.
Scientists and casinos still chase this standard today. Hardware true random number generators (TRNGs) amplify physical noise — the jitter in an electrical signal, the decay of a radioactive atom, the static in the air — into streams of unpredictable digits. For most everyday tools that’s overkill, but it’s the gold standard that everything else tries to imitate.
The computer way: pseudo-random numbers
Computers are deterministic machines. Give a program the same inputs and it produces the same outputs, every single time. So how can a computer be random?
The classic answer is a pseudo-random number generator (PRNG). A PRNG is a mathematical recipe that takes a starting value — the seed — and churns out a long, seemingly pattern-free sequence of numbers.
The catch: if you know the seed, you can predict the entire sequence. That’s fine for shuffling a playlist or generating test data, but it’s dangerous for security-critical things like passwords, encryption keys, or lottery-style picks where you don’t want anyone guessing the pattern.
How a PRNG actually computes numbers
Under the hood, every PRNG is just a loop — seed once, then compute the next value from the previous one. The differences come down to how clever that update step is:
- Linear congruential generators (LCGs) are the oldest and simplest:
next = (a × current + c) mod m. They’re fast and tiny, but their patterns are detectable, and given only a few outputs an attacker can often recover the whole sequence. This is the classic “don’t roll your own crypto” warning. - The Mersenne Twister was the workhorse from the late 1990s onward. With an enormous period and excellent statistical quality, it powered countless games, languages, and simulations. But it is not cryptographically secure: observe roughly 624 outputs and you can reconstruct its internal state and predict everything after it.
- xorshift and xoshiro families are modern, very fast generators favored in games and Monte Carlo simulation where speed matters more than security.
They all share the same shape: seed → iterate → output. Give any of them the same seed and they replay the identical sequence — that reproducibility is actually a feature for simulations, where researchers want results they can rerun.
The modern way: cryptographic randomness
Your browser ships with a much better tool: crypto.getRandomValues. This taps into the operating system’s cryptographically secure random number generator (CSPRNG), which mixes in real-world entropy — things like the timing of keystrokes, mouse movements, network jitter, and hardware noise.
That makes the output unpredictable in practice. Knowing every previous number gives you no meaningful edge on the next one. This is a cryptographically secure pseudo-random generator: it’s still deterministic inside, but it’s built so that even an attacker who captures thousands of outputs cannot recover its state or forecast the future. It’s the same source that protects bank logins and HTTPS connections, so it’s well beyond what you need for a game or a fair team pick.
The three families, side by side
Putting it together, the generators you’ll meet fall into three categories:
True random number generators (TRNGs)
- Draw from an unpredictable physical process (thermal noise, atmospheric noise, radioactive decay)
- Genuinely unpredictable, in principle
- Require specialized hardware, so rare in everyday software
- Used to seed and refresh the entropy pools that everything else depends on
Pseudo-random number generators (PRNGs)
- Purely mathematical, deterministic formulas (LCG, Mersenne Twister, xorshift)
- Fast, cheap, reproducible — ideal for games, test data, and simulations
- Predictable by design: the seed controls everything
Cryptographically secure PRNGs (CSPRNGs)
- PRNGs hardened so their output is indistinguishable from true randomness
- Seeded from OS-collected entropy, continuously refreshed
- Past outputs give no information about future ones
- The right choice for passwords, tokens, encryption, and any fair draw
On this site, every tool uses the third category: a CSPRNG seeded by your operating system’s entropy.
What “fair” really means: uniform distribution
A random number generator is only as fair as its distribution. The goal is a uniform distribution: every value in your chosen range has the exact same chance of being selected. Roll a die a million times and each face should come up roughly a sixth of the time. Generate a million numbers from 1 to 100 and each value should appear about one percent of the time.
Two facts make “fair” feel unintuitive:
- Small samples are clumpy. Run just ten draws and you might see the same number three times — that isn’t a bug, it’s probability doing its job. Patterns average out only over large samples.
- Randomness is forgetful. Dice have no memory. After five sixes in a row, the next roll is still a one-in-six chance for a six. Believing a “hot streak” must end is the gambler’s fallacy.
If you need each value at most once, this site’s no duplicates option switches from sampling with replacement (one number pool, reused each draw) to sampling without replacement (each drawn value is removed). Both modes stay uniform; they just answer different questions.
Why the architecture matters on this site
Generating numbers locally in your browser isn’t just a performance choice — it’s a privacy one:
- Nothing leaves your device. Your ranges, counts, and results never travel over the network.
- No server to trust. The numbers are produced on your own machine, by code that’s public on this project’s repository.
- Served as static files. After the page loads, there are no network calls at all — just your browser doing the math.
You can put all of that to the test right now: pick any range, flip on “no duplicates” if you want unique values, and hit Generate in the tool above or on the online random number generator. The numbers you get are computed locally by your browser’s CSPRNG — nothing is sent anywhere.
Every tool on the site shares one engine
The same crypto-grade source powers the dedicated tools, so each one is exactly as fair as the generator itself:
- Dice roller — a fair virtual die. Choose the number of sides (6, 20, or any range) and the dice to roll, and get uniform, independent rolls.
- Lottery picker — draws your set of unique numbers from a chosen range (the classic six from 1–49), using rejection-based sampling without replacement.
- Bingo caller — calls balls from 1–75 without ever repeating a number, tracking what’s been called so your game stays straight.
- Team picker — assigns names or numbers to teams in a genuinely random, unbiased shuffle, so nobody can complain the draw was rigged.
Each preset is just the random number generator behind it, specialized for a job — which means any “how is it fair?” question has the same answer: it’s the same CSPRNG, running entirely in your browser.
How to check whether a generator can be trusted
With randomness, trust should be earned. Here’s a practical checklist worth applying to any randomizer you find online:
- Is the source crypto-grade? Look for
crypto.getRandomValues, the Web Crypto API, or an explicit “cryptographically secure” claim. A genericMath.random()isn’t enough for draws that matter. - Does it run locally? If results are generated on your device, nobody is filtering, steering, or logging your numbers. If they’re generated on a server, you’re trusting whoever runs it.
- Is the code inspectable? A public, readable implementation means the “fair” claim can be verified rather than taken on faith.
- Does duplicate prevention exist? “No repeats” mode should sample without replacement, not just reroll until something new appears (though a correct implementation looks identical either way).
- Can you pass a statistical test? Regularity checks like the chi-squared test tell you whether observed frequencies match a uniform distribution. A good CSPRNG passes them by default.
Any generator that fails the first two points should not decide a lottery, a prize, or a research sample.
The fine print
A few classic misunderstandings are worth clearing up:
- Pseudo-random isn’t automatically bad. For games and experiments, quality PRNGs are perfectly adequate. But on this site we reach for the crypto-grade source anyway, because it’s free and standard.
- Full randomness can repeat. Getting the same number twice isn’t a bug — it’s how independent random events behave. If you need unique values, use the “no duplicates” toggle.
- A fair tool needs a good source. Using
crypto.getRandomValuesmeans we never have to ask you to send data to a “randomness API” — the security comes from your own operating system.
TL;DR
If you take one thing away, let it be this: a computer can’t be random on its own, so it fakes it very, very well — and the quality of that fake decides whether results are merely fun or genuinely fair. True randomness comes from physics and needs hardware. Pseudorandom generators are deterministic math, fine for games but predictable if seeded poorly. And cryptographically secure generators, seeded with operating-system entropy, are unpredictable enough for encryption — which is what chooses your numbers here.
So next time the numbers appear, you know the story: physics meets math, wrapped up in your browser’s crypto module, all without your values ever leaving the tab. Ready to see it in action? Generate some random numbers and pick your own range, count, and duplicates setting.
Frequently asked questions
Can a computer generate truly random numbers?
Not with software alone. A normal program is deterministic, so anything it computes can in principle be predicted. True randomness has to come from an unpredictable physical source — thermal noise, atmospheric noise, radioactive decay — which is why it usually needs specialized hardware. Browsers get close by mixing real-world entropy from your operating system into a cryptographically secure generator, which is unpredictable in practice for everything short of a nation-state adversary.
What's the difference between random and pseudo-random numbers?
A truly random number can never be predicted, even with perfect knowledge of the system. A pseudo-random number comes from a deterministic algorithm: given the same starting seed, it always produces the same sequence. Pseudo-random isn't automatically bad — it's fine for games and simulations — but it's only as unpredictable as its seed. Cryptographically secure generators are designed so that even if you observe many outputs, you still cannot predict the next one.
Is Math.random() random enough for a lottery or prize draw?
Generally, no. Math.random() is a fast non-cryptographic generator. It looks random and is fine for casual games, but its state can sometimes be recovered, and it is not guaranteed to be seeded from unpredictable entropy. For a prize draw, a lottery, or any pick where fairness must be beyond doubt, use a cryptographically secure source like crypto.getRandomValues, which is what the tools on this site use.
Why do I get the same number twice in a row?
That is how true randomness behaves. Independent draws treat each number as a fresh coin flip, so repeats are expected — rolling 4-4 on dice, or drawing the same lottery number twice, is normal. If you need unique values, turn on duplicate prevention. That switches the generator from sampling with replacement to sampling without replacement, so every drawn value is removed from the pool.
Are the numbers on this site really random and trustworthy?
Yes, and you can verify it. Every tool here generates values locally in your browser using the crypto.getRandomValues API, which your operating system seeds from genuine hardware entropy — the same class of source used for encryption keys and security tokens. Nothing is sent to a server, so there is no external party that could influence the result, and the code is public on the project repository.