VERIFIABLE BY DESIGN

How randomness works here.

Most random pickers ask you to trust them. We do not. Every draw is replayable from a small piece of data we record alongside the winner, so you can recompute the result yourself in your own browser. No server access required.

The short version

  1. Your browser asks the operating system for cryptographically secure random bytes via the crypto.getRandomValues API. We do not use Math.random.
  2. Those bytes are turned into a uniform integer using rejection sampling, so every name has exactly the same chance of winning. No off-by-one or modulo bias.
  3. We store the exact bytes used (the "seed") alongside the winner. Anyone with the seed can replay the draw.
  4. When you visit a result page, your browser independently recomputes the result from the seed and confirms it matches.

Why rejection sampling

The naive way to pick a number 1..N from a 32-bit random word is word % N. That works perfectly when N divides 232, and is slightly biased otherwise — early numbers in the range get picked a tiny bit more often. The bias is tiny but it is real.

We avoid it by computing a threshold equal to the largest multiple of N that fits in 32 bits, and rejecting any drawn word at or above the threshold. The accepted word is then taken modulo N. The probability of needing to reject anything is microscopic for any reasonable list size, but the result is provably uniform.

The algorithm, in code

function pickIndex(n) {
  const max = Math.floor(0xFFFFFFFF / n) * n;
  const buf = new Uint32Array(1);
  let x;
  do {
    crypto.getRandomValues(buf);
    x = buf[0];
  } while (x >= max);
  return x % n;
}

We record every 32-bit word drawn (in big-endian order) so the loop can be replayed deterministically by anyone holding the seed.

What you can verify on a result page

  • The seed bytes used (shown as a hex string)
  • The full list of entries that were in the draw
  • The algorithm name (so any future change is explicit)
  • A "Recompute" button that runs the algorithm in your browser and confirms the recorded winner

Multi-user draws (coming soon)

When draws have multiple participants and the result matters, single-party randomness is not enough — somebody could in principle keep redrawing until they like the answer. We will add a commit-reveal protocol: the server publishes a hash of its seed before entries are locked, then reveals the seed after the draw, so no party can manipulate the outcome after the fact. Today's single-user draws skip this because there is nobody to coordinate with.

Questions or want to dig deeper? Try it.