Random Number Generator

Generate random numbers in any range, with control over count and duplicates — using cryptographic randomness rather than a predictable generator.

Why random % n is not a fair way to pick

Take a random integer from 0 up to m − 1 and reduce it modulo n. Every outcome gets ⌊m/n⌋ chances — and then the m mod n values left over get one more each. So unless n divides m exactly, the first few outcomes are simply more likely than the rest, by a factor of (base + 1) ⁄ base.

How much that matters depends entirely on how big the source is:

SourceOutcomesFavouredEach is likelier by
4,294,967,296 10 6 of 10 2.3e-7%
4,294,967,296 3 1 of 3 7.0e-8%
32,768 100 68 of 100 0.3%
32,768 10,000 2,768 of 10,000 33.3%
256 10 6 of 10 4.0%

A 32-bit source with a small n is genuinely invisible — not “small enough to ignore”, but below anything anyone will ever measure. A 15-bit source with a large n is a real defect: reducing a value under 32,768 modulo 10,000 makes 2,768 of the outcomes a third more likely than the other 7,232.

That combination is not hypothetical. It is exactly what rand() % n does in C wherever RAND_MAX is 32,767 — the minimum the standard permits, and what Microsoft's runtime actually uses.

The fix is to throw some numbers away

You cannot divide 32,768 things evenly into 10,000 boxes, so the honest options are to make the source bigger or to reject the leftovers and draw again. Rejection sampling discards anything at or above the largest exact multiple of n — 30,000 in that case — and costs about 1.092 draws per result in exchange for exact uniformity.

JavaScript sidesteps the problem: Math.random() returns a float, so Math.floor(Math.random() * n) is uniform to the limits of the double it came from. The bias belongs to integer sources — and it is worth knowing about precisely because it is invisible in testing. The distribution looks flat until you count carefully enough, which is also how it is easy to measure wrongly: comparing the most common outcome against the least common one across ten thousand buckets reports a ratio near 1.8, almost all of which is sampling noise rather than bias.

How to use

  1. Set the minimum and maximum.
  2. Choose how many numbers you want.
  3. Decide whether duplicates are allowed.
  4. Generate and copy the results.

Frequently asked questions

Is this truly random?

It uses the browser's cryptographic random source, which is seeded from operating system entropy and is unpredictable in practice. Strictly it is pseudorandom rather than drawn from a physical process, but the distinction has no practical consequence for anything short of specialised scientific work.

Why not use Math.random?

Because it is predictable. Its output comes from a simple algorithm, and observing a few values can reveal its internal state and therefore every subsequent value. That is fine for shuffling a background animation and unacceptable for a draw, a token, or anything where someone benefits from guessing.

What is modulo bias?

A subtle flaw where taking a random value modulo a range makes lower numbers slightly more likely, because the range rarely divides the generator's output space evenly. A correct implementation rejects and retries values that would skew the result, which is what this one does.

Is this fair enough for a prize draw?

For an informal one, yes. For anything with legal or financial weight, use a documented, auditable process — regulated draws have requirements about verifiability and record-keeping that no web page satisfies, however good its randomness.

How does drawing without duplicates work?

By shuffling the range and taking the first several values, or by tracking what has already been drawn. Both keep every remaining number equally likely, which naive retry-on-duplicate approaches also do but far more slowly as the range fills up.

Can I reproduce a set of numbers later?

Not from a cryptographic source, by design — there is no seed to record. Reproducibility requires a seeded pseudorandom generator, which is what simulations and testing use, and which is exactly the property you do not want in a draw.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.