How random name pickers work — and why most of them are unfair

· 3 min read
By Spin of luck team

Most online wheel-of-names tools use Math.random(), which is statistically uniform but predictable. Here's why that matters, what crypto.getRandomValues() does differently, and how to verify a name picker is actually fair.


Key Takeaways

  • Math.random() is statistically uniform but predictable — fine for casual picks, not for verifiable draws.
  • crypto.getRandomValues() pulls from OS entropy and has no recoverable internal state, making it unpredictable.
  • For high-stakes draws (raffles, livestream giveaways), use a tool that uses crypto.getRandomValues() under the hood.
  • Verifiability matters more than RNG quality alone: share the entrant list before the spin and run the draw on-screen.

If you've ever used a wheel-of-names to pick a winner — for a class, a raffle, a giveaway — you've probably wondered: is this thing actually random? The honest answer is that most online name pickers are statistically uniform but cryptographically weak. For low-stakes uses (cold-calling students, deciding who buys lunch) that's fine. For higher-stakes uses (regulated raffles, prize draws over $1000, anything where someone might claim the result was rigged) the difference matters.

Math.random() is fast but predictable

The default JavaScript random function, Math.random(), is a pseudo-random number generator (PRNG). Given the same seed, it produces the same sequence — that's what 'pseudo' means. Modern browsers seed it from system entropy and don't expose the seed, so in practice you can't reproduce it. But the algorithm itself (xorshift128+ in V8, an LCG variant in Safari) is well-documented, the period is finite, and the statistical properties of the output have been studied to death.

For picking names from a list, this is overkill-good: the output is uniformly distributed across [0,1), and the pseudo-random sequence is long enough that you'll never hit a repeat in a practical wheel-spin context. So why ever use anything else?

crypto.getRandomValues() is slower but unpredictable

The Web Crypto API exposes a function called crypto.getRandomValues(). Unlike Math.random(), it's seeded from the operating system's entropy pool — randomness the OS gathers continuously from unpredictable hardware-level events such as interrupt and device timing — and it's the same pool the system draws on to generate cryptographic keys.

The practical difference: an attacker who could observe a few outputs from Math.random() can in principle reconstruct the internal state and predict future outputs. (For V8, this is published research.) The same attacker observing crypto.getRandomValues() output gets nothing they can leverage — there's no internal state to recover, just a stream of fresh entropy.

See it in action

Run a quick draw on the cryptographically secure random name picker — no signup, no setup.

Open the Random Name Picker

What 'fair' actually means in practice

There are three properties an audience-of-strangers will care about when watching a draw:

  1. Uniform distribution: every entrant has the right probability relative to their entry weight. Both Math.random() and crypto.getRandomValues() satisfy this.
  2. Unpredictability: nobody (including the host) can predict the result before the spin. Math.random() formally fails this; crypto.getRandomValues() satisfies it.
  3. Verifiability: an outside observer can confirm after the fact that the result was the legitimate output of the random source. This is the hardest property and it's where most online tools fall down.

The first two are mathematical properties of the RNG. The third is a process property: did the entrant list match what the host claimed? Was anyone added or removed between announcement and pick? Can we verify the wheel showed the result the RNG produced, not a pre-chosen winner the wheel was 'driven' to?

How to verify a draw is fair

Three concrete things you can do, ordered by effort:

  • Share the entrant list before the draw. SpinOfLuck encodes the wheel into a shareable URL — co-organizers verify the URL matches before the spin and notice instantly if it changes.
  • Live-stream or record the draw. If the wheel is on screen the entire time, an after-the-fact audit can confirm no entrants were added.
  • For high-stakes draws, use multiplayer-spin-wheel mode so multiple devices see the same wheel and the same animation. If anyone's screen disagrees, the discrepancy is visible.

Should you actually care?

For 90% of name-picker uses — classroom cold-calls, friend-group restaurant decisions, low-value office raffles — Math.random() is genuinely fine. Nobody is going to attack a 'who-buys-coffee' draw, and the sequence-prediction concerns are theoretical at that scale.

For the other 10% — regulated charity raffles, cash-prize giveaways, livestream sub draws where the audience has reason to be suspicious — the cost of using a cryptographically secure RNG is essentially zero (single-digit microseconds slower per call) and the credibility benefit is large. There's no reason not to.

Frequently asked questions

Is Math.random() truly random?
No — Math.random() is a pseudo-random number generator (PRNG). It produces a statistically uniform sequence, but the sequence is deterministic given the internal state. For ordinary use it feels random; for security-sensitive or verifiable draws it isn't.
How is crypto.getRandomValues() different?
crypto.getRandomValues() draws from your operating system's randomness pool, which is seeded continuously from unpredictable low-level hardware noise. There's no recoverable internal state, so future outputs can't be inferred from past ones. It's the same source the OS uses to generate cryptographic keys.
Does the randomness quality matter for a classroom name picker?
Practically, no. Math.random() is more than uniform enough for picking which student presents next. The distinction only matters when someone has an incentive to predict or contest the result — high-value giveaways, regulated draws, public livestreams.
How can I verify a wheel actually picked fairly?
Three things: share the entry list before the spin (a URL-encoded wheel makes this easy), run the draw on-screen rather than off-camera, and for high-stakes draws use multiplayer mode so multiple devices render the same spin independently.