How Random Name Pickers Work: Randomness, Bias and Fair Selection

Every random name picker does the same three things: it stores your list, it generates a random number, and it maps that number onto the list. The difference between a fair draw and a quietly biased one lives almost entirely in steps two and three.

By the WheelOurNames team · Published 22 August 2026

Editorial note: product-specific technical claims in this article have been checked against the current WheelOurNames implementation.

The three steps every picker performs

Strip away the animation and every name picker — a wheel, a hat simulator, a "random student" button — reduces to the same pipeline:

  • A list. Your entries, in some order, possibly with duplicates or weights.
  • A random number. Produced by a generator in the browser or on a server.
  • A mapping. The rule that turns the number into one chosen entry.

Step one is under your control. Steps two and three are where fairness is won or lost, and they are exactly the steps most tools never explain.

Where the random number comes from

Browsers ship two different random generators, and they are not interchangeable. Math.random() is a fast pseudo-random generator designed for games and visual effects: it is seeded automatically, its algorithm makes no unpredictability guarantees, and the specification explicitly says it is not cryptographically secure. crypto.getRandomValues is the browser's cryptographically secure generator — the same primitive used to create security keys — and is designed so its output cannot be predicted or reproduced from outside (MDN's reference explains the distinction).

For picking a name, the practical difference is not that one produces "more random-looking" results — over a handful of spins you could not tell them apart by eye. The difference is that a non-cryptographic generator can, in principle, be predicted or influenced, and its quality varies between engines. A picker that wants to make fairness claims should use the cryptographic source. WheelOurNames uses crypto.getRandomValues for every draw and deliberately has no silent fallback to Math.random(): if a browser did not expose Web Crypto, the draw would stop with an explicit error rather than quietly downgrade.

The bias hiding in the mapping

Even with a perfect random source, the mapping step can skew the result. Generators produce integers in a fixed range, and the obvious way to turn a big integer into a list position is the remainder operator: position = number mod list length. That is only exactly fair when the generator's range divides evenly by the list length — which it almost never does.

A small worked example makes the skew visible. Imagine a tiny generator that produces the eight values 0–7 with equal probability, and a wheel with three entries:

Drawn value01234567
value mod 301201201

Entry 0 wins on three of the eight values (0, 3, 6), entry 1 wins on three (1, 4, 7), but entry 2 wins on only two (2, 5). The "equal" wheel is actually 37.5% / 37.5% / 25%. This is called modulo bias, and it appears whenever the range is not a whole multiple of the number of outcomes.

The standard fix is rejection sampling: work out the largest whole multiple of the list length that fits in the range, discard any draw at or above it, and draw again. In the example, values 6 and 7 would be thrown away, leaving six values that map two-each onto the three entries. WheelOurNames draws a 32-bit unsigned integer and applies exactly this rule, so the leftover values are discarded rather than folded onto the first few entries. With a real 32-bit range the bias would be far smaller than in the toy example — but it would exist, so it is removed entirely.

Equal wheels, duplicate entries and weights

On an ordinary wheel every entry carries weight 1, so each has an identical chance: four entries means 25% each, regardless of list order or slice colour. Two deliberate exceptions are worth understanding because they change the odds on purpose:

  • Duplicate lines are independent entries. A name pasted twice occupies two slices and genuinely has twice the chance. That is a feature for giveaways where the rules award multiple entries — not a data-entry error the tool should silently "fix".
  • Weights set relative shares. With weighting enabled, each entry's chance is its weight divided by the total of all weights. An entry with weight 3 against one with weight 1 wins 75% of the time. WheelOurNames computes this with integers only: a single uniform draw over the total weight, then a cumulative walk to find which entry's range the draw landed in. No floating-point rounding is involved, so the drawn odds and the displayed slice sizes cannot drift apart.

With and without replacement

A second mapping decision is whether a winner stays eligible. With replacement, the list is unchanged after each draw and every spin is independent — the same name can win twice in a row, and over time some names will win several times while others never come up. That is correct behaviour for sampling, not a malfunction.

Without replacement, the winner leaves the list and the chances recompute. On WheelOurNames this is the auto-remove option: with four names each spin starts at 25%, and after one removal the remaining three are at 33.3% each. This is the mode to use when the goal is coverage — every student picked once, every prize going to a different entrant — rather than independent sampling.

Why the spinning animation is not the draw

On a well-built wheel the winner is selected the instant you press spin; the animation then rotates to display a result that already exists. Spin duration, easing, the number of turns and the small landing offset inside the winning slice are presentation. This separation is what makes the result auditable: the animation cannot influence the outcome because it is computed after it. If you are evaluating a picker, a tool that "decides" only when the pointer stops — where the physics determines the winner — is much harder to reason about than one where the draw is a single, inspectable random selection.

A checklist for judging any name picker

  • Does it say which random source it uses? "Cryptographically secure" should mean the Web Crypto API or an equivalent, not a marketing adjective.
  • Does it describe the mapping, or at least state that it avoids modulo bias?
  • Are duplicates and weights handled deliberately and documented?
  • Can you tell whether winners are drawn with or without replacement — and switch between the two?
  • Is the winner selected independently of the animation?
  • Does it fail loudly when secure randomness is unavailable, rather than falling back silently?

The fairness page documents how WheelOurNames answers each of these, including the exact reduction algorithm, and its built-in simulator lets you run thousands of virtual spins and inspect the distribution yourself.