How a fair random number generator works
A random number generator (RNG) picks values from a range so that — over many draws — every
number is equally likely. The catch is that most everyday RNGs cheat in two ways: they are
predictable, and they are subtly biased. This tool fixes both. It draws from
crypto.getRandomValues(), the browser’s cryptographically secure generator, and it
removes the classic “modulo bias” using a technique called rejection sampling.
The math: why plain modulo is biased
Computers produce raw randomness as large integers — here, 32-bit values from 0 to 4,294,967,295.
To squeeze one into a smaller range you might reach for the remainder operator:
value % rangeSize. But unless the range divides 4,294,967,296 evenly, the lowest
few outcomes get one extra chance each, making them slightly more common. The fix is to compute a
cut-off and discard (reject) any raw value that lands in the leftover tail:
range = (max − min) + 1limit = floor(2³² / range) × range- Draw a raw 32-bit value
v; ifv ≥ limit, throw it away and draw again. - Otherwise return
min + (v % range)— now perfectly uniform.
For decimals the tool instead scales a uniform fraction across the span:
min + fraction × (max − min), then rounds to your chosen number of places.
A worked example
Suppose you want one integer from 1 to 6 (a dice roll). The range is
6 − 1 + 1 = 6. The cut-off is floor(4,294,967,296 / 6) × 6 = 4,294,967,292,
so only the top four raw values out of four billion are ever rejected. A draw of, say,
3,000,000,003 gives 1 + (3,000,000,003 % 6) = 1 + 3 = 4 — you rolled a 4.
Every face has an exactly equal 1/6 ≈ 16.67% chance.
Options at a glance
| Option | What it does |
|---|---|
| No duplicates | Draws without replacement, so every number is unique (like lottery balls). |
| Sort results | Orders the output from lowest to highest instead of draw order. |
| Decimals | Returns fractional values rounded to 0–10 places of your choosing. |
| Dice / Coin presets | One-click setups: 1–6 for a die, or 0/1 mapped to heads/tails. |
Cryptographically secure
Powered by the Web Crypto API — not the weak, seedable Math.random() most pages use.
Bias-free
Rejection sampling guarantees every value in your range is equally likely.
Flexible
Any range, batch sizes up to a thousand, integers or decimals, unique or repeatable.