Random Number Generator
Generate fair, unbiased random numbers in any range using your browser’s
cryptographic generator (crypto.getRandomValues()) — with optional no-repeats,
decimals and sorting. Nothing is uploaded.
Last reviewed 2026-06-19.
How the randomness works
Every number is produced by crypto.getRandomValues(), the browser’s
cryptographically secure random source — the same entropy your operating
system uses for encryption keys. It is not seedable and cannot be predicted or reproduced.
For whole numbers we use rejection sampling: we draw a 32-bit value and discard
any draw that falls into the small “leftover” region that would otherwise make some
numbers slightly more likely than others. The result is a uniform distribution —
every value in your range is exactly equally likely, even when the range is not a power of two.
This is the bias that a naive Math.random() × range approach quietly introduces.
Common uses
| Use | Suggested settings |
|---|---|
| Giveaway / raffle winner | Range 1 to number of entrants, how many = number of winners, Unique on |
| Dice roll | 1 to 6 (or 1 to 20 for tabletop games) |
| Coin flip | 0 to 1 (0 = heads, 1 = tails) |
| Lottery-style draw | 1 to 49, how many = 6, Unique on |
| Random sample without replacement | 1 to population size, how many = sample size, Unique on |
| Random decimal (e.g. 0–1) | Min 0, Max 1, decimal places 2–4 |
Good to know
- Fair for draws. Because the distribution is uniform and unbiased, each entry has an equal chance — suitable for giveaways, prize draws and sampling.
- Unique vs with-repeats. Turn on Unique to draw distinct numbers (sampling without replacement); leave it off to allow repeats (independent draws).
- Range limits. Values are clamped to between −1,000,000,000 and 1,000,000,000, and up to 1,000 numbers per batch.
- Private. Generation is 100% in-browser — nothing is sent to a server, and it works offline.
True random versus pseudo-random
Computers are deterministic machines, so producing genuine randomness is surprisingly hard. There are two fundamentally different approaches. A true random number generator (TRNG) measures an unpredictable physical phenomenon — electronic thermal or shot noise, atmospheric radio noise, the timing of radioactive decay, or quantum effects such as photons hitting a beam splitter — and converts it into bits. The randomness comes from nature, so the output cannot be reproduced or predicted, but harvesting it is comparatively slow.
A pseudo-random number generator (PRNG) is a mathematical formula that starts from an initial value called the seed and churns out a long sequence that looks random. It is fast and convenient, but it is entirely deterministic: anyone who knows the seed and the algorithm can reproduce the exact same sequence, and the sequence eventually repeats after a length known as its period. Reproducibility is sometimes a feature — it lets scientists re-run a simulation exactly — but it is a fatal weakness when unpredictability matters.
Modern systems use a hybrid: a hardware entropy source seeds a fast, high-quality
pseudo-random algorithm. That is exactly what your browser does. The
crypto.getRandomValues() call that powers this page draws from your operating
system's entropy pool, which is continuously topped up from hardware noise, so the numbers it
produces have the unpredictability of a TRNG with the speed of a PRNG.
The algorithms behind pseudo-random numbers
Not all PRNGs are created equal. Decades of research have produced families of algorithms with very different quality and speed:
| Algorithm | Year / author | Notes |
|---|---|---|
| Linear congruential (LCG) | 1950s onward | Very fast, tiny state, but statistically weak — consecutive values fall on detectable hyperplanes. Still common in basic rand() functions. |
| Mersenne Twister | 1997, Matsumoto & Nishimura | Enormous period of 219937−1 and good statistical quality; the default in Python, R and many languages — but not cryptographically secure. |
| Xorshift | 2003, George Marsaglia | Extremely fast bit-shifting generators; pass strong tests when combined with a non-linear step. |
| PCG | 2014, Melissa O'Neill | A permuted congruential family combining a fast LCG core with an output scramble — small, fast and statistically excellent. |
A common misconception is that the Mersenne Twister, because of its astronomical period and strong test results, must be safe for security. It is not: by observing only 624 of its outputs, an attacker can recover its internal state and predict every future value. Statistical quality and cryptographic security are different requirements, which is the distinction this tool is built around.
What makes a generator "cryptographically secure"
A cryptographically secure PRNG (CSPRNG) must satisfy a far stricter bar than
simply passing statistical tests. Two properties define it. The next-bit test:
given every output bit so far, no efficient algorithm can predict the next bit with better than
a coin-flip's chance. And state-compromise resistance: even if its internal
state were somehow exposed, an attacker still could not reconstruct the random numbers it had
already produced. A non-cryptographic generator like JavaScript's Math.random()
fails both — it is designed for speed in games and animations, its state is recoverable
from its output, and the specification does not even guarantee a particular quality of
randomness.
The U.S. National Institute of Standards and Technology publishes the standard for approved
designs, NIST SP 800-90A, which specifies vetted deterministic random-bit
generators. The field also carries a famous cautionary tale: one algorithm in an earlier version
of that standard, Dual_EC_DRBG, was later shown to contain a probable backdoor
and was withdrawn — a reminder that a generator's design, not just its output, determines
whether it can be trusted. The crypto.getRandomValues() source used here is the
browser's interface to the operating system's vetted CSPRNG.
Why a fair range is harder than it looks
Suppose you want a fair number from 1 to 6 and you have a generator that returns a random byte
(0–255). The lazy approach is to take the remainder: byte % 6 + 1. But 256 is
not a multiple of 6. The values 0–251 divide evenly into six buckets of 42, but the four
leftover values 252–255 land in buckets for 1, 2, 3 and 4 — so those four outcomes
come up slightly more often than 5 and 6. This is modulo bias, and although the
skew is tiny for a die, it grows with the range and can matter for cryptographic keys, large
lotteries or scientific sampling.
The fix is rejection sampling: define the largest multiple of your range that fits in the generator's output (here, 252), and simply discard — reject and redraw — any value at or above it. Every value that survives maps to exactly one outcome, so each result is precisely equally likely. This generator applies that technique to a full 32-bit draw for every integer, which is why its ranges are mathematically uniform rather than merely "close enough."
Why people are bad at being random
It is tempting to just "pick a number in your head," but humans are remarkably poor random generators, which is precisely why a tool like this exists. When asked to choose a digit from 1 to 10, far more people pick 7 than any other — it feels the most "random" because it is odd, prime and sits away from the round endpoints. People also unconsciously avoid repeating the same value twice in a row and tend to alternate high and low choices, because a genuine run of repeats feels non-random even though true randomness produces such streaks all the time. The same instinct fuels the gambler's fallacy: the mistaken belief that after several heads a tail is "due." Each independent draw has no memory, so a fair generator will happily produce clusters and runs that a person editing by gut feel would never write down. If you need a result that is defensibly impartial — for a giveaway, a sampling decision or a tie-break — a uniform machine draw removes that hidden human bias entirely.
How randomness is tested
You cannot prove a finite sequence is random, but you can subject a generator to batteries of statistical tests that try to detect patterns a truly random source would not have. The classic suite is George Marsaglia's Diehard tests (later extended as Dieharder); the most demanding modern battery is Pierre L'Ecuyer's TestU01, whose "BigCrush" set runs over a hundred tests. NIST publishes its own Statistical Test Suite aimed specifically at generators used for cryptography. Underneath many of these sits the humble chi-squared test, which checks whether observed frequencies (how often each value appears) match the uniform distribution you would expect by chance. Passing these tests is necessary but, as noted above, not sufficient for cryptographic use.
Random numbers in the real world
Random number generation quietly underpins an enormous range of activities:
- Cryptography. Encryption keys, session tokens, nonces, salts and digital signatures all depend on numbers an attacker cannot guess. A weak generator here is catastrophic — predictable keys can be broken outright.
- Monte Carlo simulation. Physics, finance, weather and engineering models run millions of random trials to estimate outcomes that are too complex to solve directly, such as option pricing or particle behaviour.
- Games and procedural generation. Dice rolls, card shuffles, loot drops and entire generated worlds rely on randomness to stay fresh and fair.
- Statistical sampling. Drawing a random, representative sample from a population — for surveys, audits or A/B tests — depends on every member having an equal chance of selection.
- Lotteries and prize draws. Fairness and public trust require an unbiased, tamper-proof draw, the very property rejection sampling guarantees.
Frequently asked questions
- Is this random number generator truly random?
- It uses your browser's crypto.getRandomValues() API, which draws from the operating system's cryptographically secure pseudo-random number generator (CSPRNG) — the same entropy source used by password managers and TLS. Unlike Math.random(), it is unpredictable and not seedable, so results cannot be reproduced or guessed. For integers we also apply rejection sampling so every value in your range is exactly equally likely (no modulo bias).
- Can I use this for a giveaway or raffle fairly?
- Yes. Assign each entrant a number (1 to N), set the range to 1–N, turn on “unique (no repeats)” if you are drawing several winners, and generate. Because every number in the range is equally likely and the draw is unbiased, it is a fair selection. For full transparency you can screen-record the draw or generate in front of participants — nothing is sent to a server, so the result is produced live on your device.
- What does “unique (no repeats)” do?
- With it off, each number is drawn independently, so the same value can appear more than once (like rolling a die repeatedly). With it on, every number in the output is different — useful for lottery draws, picking distinct winners, or sampling without replacement. If you ask for more unique numbers than the range can hold (e.g. 10 unique numbers between 1 and 5), the count is automatically capped to the range size.
- How is this different from Math.random()?
- Math.random() is a fast, non-cryptographic generator intended for things like animations or shuffling unimportant lists; its output is not guaranteed unpredictable and can be biased when scaled to a range with the modulo operator. crypto.getRandomValues() is cryptographically secure, and our rejection-sampling step removes the modulo bias entirely, so for a range that is not a power of two every value is still exactly equally likely.
- Can it generate decimal numbers?
- Yes. Set “decimal places” to 1–4 and the generator returns uniform decimal values across your range (for example a random number between 0 and 1 with 4 decimals). At 0 decimal places it returns whole integers using the unbiased integer path.
- Does anything leave my browser?
- No. Every number is generated locally using your device’s CPU and OS entropy. Nothing is uploaded, transmitted or logged, and the page keeps working offline once loaded.