Boneyard Tools

How random number generators work

How computers produce randomness, why crypto.getRandomValues beats Math.random, and how rejection sampling removes bias from a range.

Pseudo-random versus cryptographic randomness

Most everyday randomness comes from a pseudo-random number generator, a formula that starts from a seed and produces a stream of values that only look random. JavaScript's Math.random is one of these, and while it is fine for shuffling a slideshow, its output can be predicted if you learn the internal state. Cryptographically secure generators instead gather entropy from the operating system, seeded by hardware noise and other unpredictable events. This tool uses crypto.getRandomValues, the secure source built into every modern browser, so results are suitable for draws where fairness matters.

Why a naive range can be biased

A common shortcut for fitting a raw random integer into a range is the remainder operator, value modulo range. The problem is that a 32-bit random number holds just over four billion possibilities, and unless your range divides that total evenly, some remainders occur slightly more often than others. Over many draws this quietly favors the lower numbers in your range. For a coin flip the skew is invisible, but for anything audited or repeated it is a real flaw worth avoiding.

How rejection sampling fixes it

To keep every value equally likely, the generator finds the largest whole multiple of your range that fits inside the 32-bit space and discards any raw number above it before taking the remainder. Throwing away that thin sliver of high values means the numbers that remain map onto your range perfectly evenly. The cost is that a draw occasionally repeats, but the rejection rate is tiny, so the tool still returns results instantly. This is the same technique cryptographic libraries use for unbiased range reduction.

Drawing unique numbers without repeats

When you ask for distinct values, sorting or reshuffling the entire range would be wasteful for a wide span like 1 to a million. Instead the tool runs a partial Fisher-Yates shuffle: it swaps only as many positions as you requested, pulling each pick from a pool that shrinks by one after every draw. That keeps memory and time proportional to the count you asked for, not the size of the range, while every ordering of the winners stays equally likely.

Frequently asked questions

Is crypto.getRandomValues good enough for a prize draw?

For contests and giveaways, yes. It is the secure randomness source browsers expose for cryptographic work, so the output is unpredictable and unbiased. For legally regulated gambling you should still use a certified system, since rules there go beyond the quality of the randomness itself.

Can I reproduce the same numbers later with a seed?

No. A secure generator deliberately has no exposed seed, so draws cannot be replayed. If you need repeatable sequences for testing, use a seeded pseudo-random generator in code instead of this tool.