How to Use This Tool
Set a range and press generate. Numbers come from crypto.getRandomValues with rejection
sampling, so every value in the range is equally likely.
Why % n is not uniform
The obvious way to turn a random byte into a number from 1 to 6 is to take the remainder. A byte holds 256 values, and 256 divided by 6 is 42 remainder 4 — so four of the six outcomes get one extra byte each.
Counted exactly: outcomes 0 to 3 each collect 43 byte values, outcomes 4 and 5 collect 42. That makes the low rolls 2.38% more likely than the high ones. At a range of 10 the excess is 4.00%.
Nobody notices this over a hundred rolls. It becomes real when the draw decides something worth money, or when it runs millions of times, or when someone is looking for an edge.
Rejection sampling, which is simpler than it sounds
Take the largest multiple of your range that fits — for a range of 6 in a byte, that is 252. Throw away any byte of 252 or more and draw again. What is left divides evenly, so the remainder is exactly uniform.
The cost is the discarded draws: 4 out of 256, which is 1.56%. In the worst case — a range just over half the space — you discard just under half your draws and still finish almost immediately, because each retry has an independent chance of succeeding.
This tool widens to 16 or 32 bits for larger ranges, which keeps the rejection rate small no matter how big the range is.
Uniform is not the same as unpredictable
Math.random() is a fast pseudorandom generator. Its output is spread evenly enough for a
game or a shuffle animation, and it is not unpredictable: given enough consecutive outputs, the
internal state can be recovered and every future value computed.
So the question is not "is it random enough" but "would anyone benefit from guessing it". Prize draws,
tokens, passwords, anything with money attached — use
crypto.getRandomValues, which is designed to resist exactly that and is available in every
current browser. This tool always uses it.
Draws with and without repeats
Picking six numbers from 1 to 49 for a lottery is without replacement: each number can appear once. Rolling a die six times is with replacement, and getting the same number twice is normal, not a malfunction.
People routinely misread the second case. In six rolls of a die, the chance that all six faces are different is only about 1.5% — so repeats are the expected outcome, and a generator that avoided them would be the broken one.
