How Random Selection Works

What “random” means in a browser, why the Web Crypto API matters, and how a spinning wheel can be both animated and genuinely fair.

Pseudorandom and cryptographic randomness are not the same thing

Every random number a computer produces comes from an algorithm. A pseudorandom generator such as JavaScript’s Math.random() starts from an internal seed and produces a sequence that looks random and passes casual inspection, but is completely determined by that seed. Observe enough outputs and you can, in principle, work out where the sequence is going.

A cryptographically secure generator is built so that this is not feasible. It draws entropy from unpredictable physical sources the operating system collects — timing jitter, hardware noise, device events — and passes it through a construction designed to resist prediction even when an attacker has seen a large amount of previous output. In the browser this is exposed as crypto.getRandomValues().

For a name draw, does it matter? Usually not for security, but it matters for confidence. A pseudorandom generator with a poor implementation can have visible structure, and “the same person keeps winning” is a much harder accusation to answer if the underlying source is weak. Using the strongest available source removes an entire category of doubt.

Turning random bytes into a fair choice

Getting random bytes is the easy part. Turning them into a number between 0 and n-1 without introducing bias is where implementations usually go wrong.

The naive approach is to take a 32-bit random value and use the remainder after dividing by n. This is subtly unfair whenever n does not divide evenly into 2³². Suppose n is 3: the range 0 to 4,294,967,295 contains one more value that maps to 0 than to 2, so entry 0 is very slightly more likely. With three entries the effect is far too small to notice, but the same reasoning applies to any list size, and the bias is real.

The fix is rejection sampling. Work out the largest multiple of n that fits in 32 bits, draw a value, and if it lands at or above that limit, throw it away and draw again. The remaining values divide perfectly among the n outcomes, so every entry is exactly equally likely. On average this rejects less than one draw in two, so the cost is negligible.

Weighted selection

A weighted draw gives some entries a larger share. The clean way to implement it is to imagine a strip of tickets: an entry weighted 3 owns three tickets, an entry weighted 1 owns one. Draw a ticket uniformly and see who owns it.

Fractional weights complicate this slightly, so weights here are multiplied by 1,000 and rounded to integers first — which is why weights support three decimal places. The draw is then pure integer arithmetic with no floating-point comparison to get wrong.

The important design rule is transparency. A weighted draw must always be visibly weighted: the wheel slices must be proportional to the weights, the chance percentages must be shown, and the result must say that weights were applied. A tool that hides weights behind an equal-looking interface is not a random picker, it is a rigged one.

Fisher-Yates, and the shuffle mistake almost everyone makes

To produce a random order, the correct algorithm is Fisher-Yates. Walk through the list from the end, and for each position swap it with a uniformly chosen position at or before it. The result is uniform: every one of the n! possible orderings is exactly equally likely.

The common mistake is to sort the array with a comparison function that returns a random result. This looks elegant and is measurably wrong. Sorting algorithms assume the comparator is consistent, and violating that assumption produces orderings that are far from uniform — with results that vary depending on which sorting algorithm the browser uses.

Drawing several winners without repeats uses the same machinery: a partial Fisher-Yates pass resolves only as many positions as you need, which is both correct and faster than shuffling a 10,000-name list to pick three.

Why the animation must never decide the result

A spinning wheel could be implemented by starting a physics simulation, letting friction slow it down, and reading off whatever slice ends up under the pointer. This is the intuitive approach and it is a bad one.

The problem is that the outcome then depends on frame rate, on how the browser throttles background tabs, on floating-point accumulation over hundreds of frames, and on whatever easing curve the developer chose. A user on a slow phone genuinely gets a different distribution from a user on a fast desktop. It is also impossible to verify.

The correct approach inverts it. Choose the winner first, from the secure source. Then solve for the final rotation that places the winner’s slice under the pointer, and animate from the current angle to that value. The easing curve, the duration and the frame rate now affect only how the wheel looks along the way. As a final check, the tool recomputes which slice sits under the pointer at the end and logs an error if it disagrees.

Browser support and limitations

crypto.getRandomValues() is available in every current browser and in every version of Chrome, Firefox, Safari and Edge released in the last decade. On the rare browser without it, this site falls back to Math.random() and says so on the page rather than pretending nothing changed.

There are limits worth stating plainly. Statistical tests can detect obvious implementation bias, but no amount of testing proves randomness. Browser generators are not certified for regulated gambling or clinical trials, and this site is not built for either. And randomness cannot make a decision meaningful — it can only make it unbiased.

Tools mentioned in this guide

More guides

  • How to Run a Fair Giveaway Drawing — A practical checklist for prize draws: cleaning the entry list, handling duplicates, eligibility, exclusions, alternates, redraw rules and keeping a record.
  • Classroom Random Picker Guide — How to call on students fairly: no-repeat rounds, absences, presentation orders, keeping sound and motion low and protecting student privacy.
  • How to Create Balanced Teams — Fully random teams, equal headcount, skill-score balancing, spreading leaders, keep-apart rules, and why no algorithm can promise perfect balance.