Randomness

The coin flip is not fair

A flipped coin is slightly more likely to land the same way up as it started — and the fix, in software, is older than the measurement.

The coin flip is the standard shorthand for a fair, unbiased binary choice. As a piece of physics it is not one, and the reason is more interesting than the result.

The bias is toward the starting side, not toward heads

The usual objection to coin fairness — that the two faces are stamped differently and therefore weigh differently — turns out to be the wrong objection. For a coin that is flipped, tumbling through the air and caught in the hand, the imbalance is elsewhere.

A 2007 analysis by Persi Diaconis, Susan Holmes and Richard Montgomery modelled the flip as rigid-body motion and pointed out that a real thumb does not impart clean rotation about an axis lying in the plane of the coin. The coin precesses: the rotation axis itself sweeps around, so the coin spends slightly more of its flight with its initial face pointing upward than pointing downward. Land it, and the side it started on is slightly favoured. Their estimate came out around 51%.

A large collaborative replication published in 2023 tested it the only way it can be tested, by flipping and recording an enormous number of coins by hand — over 350,000 flips across dozens of people and many currencies. The reported same-side rate was roughly 50.8%, with an interval that excluded 50%. Heads itself came out near enough to 50%; it is same-side that is biased, not heads.

Two consequences follow. If you must settle something with a physical coin, do not let either party see which face starts up. And a coin spun on a table rather than flipped is a different and generally worse proposition — that one really is dominated by the rim and the mass distribution, and can be badly skewed.

Proving a 51% bias is expensive

The bias is real and it is also nearly undetectable at any sample size a person would think to try. This is the part worth internalising, because it generalises to every small effect you will ever try to measure.

To distinguish a true rate p from 0.5 with a two-sided test at significance α and power 1−β, you need roughly

n = ( z(α/2)·√0.25 + z(β)·√(p(1−p)) )² / (p − 0.5)²

The denominator is the effect size squared, which is why halving the effect quadruples the cost.

Flips needed
Hours at 20 flips a minute
Excess same-side landings

At the default settings — a genuine 51% rate, 95% confidence, 80% power — the answer is a little under twenty thousand flips. At twenty flips a minute with no breaks that is more than sixteen hours of continuous flipping, and it only gives you an 80% chance of noticing. Ask for a 50.8% effect instead and the requirement climbs past thirty thousand. The 2023 study's sample size was not enthusiasm; it was arithmetic.

Anyone who tells you they flipped a coin two hundred times and "proved" it was weighted has proved nothing. Two hundred flips of a perfectly fair coin land 110 heads or more about 9% of the time — roughly one attempt in eleven, from a coin with no bias whatsoever.

Getting fair bits out of an unfair source

Suppose you are stuck with the biased coin. There is a classical trick, described by John von Neumann in 1951, that extracts perfectly unbiased bits from it without knowing the bias at all:

  1. Flip twice.
  2. Heads-then-tails → output heads.
  3. Tails-then-heads → output tails.
  4. Two the same → output nothing, discard, flip again.

It works because for independent flips with a constant bias p, the sequence HT has probability p(1−p) and TH has probability (1−p)p. Those are the same number for any p, so conditioned on the pair being mixed, the two outcomes are exactly equally likely. The bias cancels itself.

Output bits
Yield per source flip
Heads in source
Ones in output

Note what the simulator shows: the output is unbiased to within sampling noise no matter what you set the source bias to, but the yield is terrible. You spend two flips to get at most one bit and usually get zero. Peres published an iterated refinement in 1992 that recycles the discarded information and recovers substantially more of the available entropy, at the cost of a recursive implementation.

The trick's assumption is the thing that bites: flips must be independent and identically biased. A source whose bias drifts, or whose outputs are correlated with their predecessors, defeats it. Correlation is exactly the failure mode of real physical entropy sources.

Why hardware random number generators whiten

This is not an abstract concern. A hardware entropy source — ring oscillator jitter, thermal noise across a junction, avalanche noise in a diode — produces a raw bit stream that is measurably biased and measurably correlated, and gets worse with temperature, supply voltage and manufacturing variation. Nobody ships raw entropy.

Instead the raw stream is fed through a conditioner (whitening): typically a cryptographic function such as a hash or a block cipher in a chaining mode, which compresses many low-quality bits into fewer high-quality ones, and is then used to seed a deterministic random bit generator that produces the output stream. Standards bodies specify both halves separately — an entropy source with a health-test regime and a documented entropy estimate, and an approved conditioning and generation stage on top.

The awkward property of whitening is that it hides failure. A conditioner fed a constant will still emit output that passes every statistical test you can name, because the output looks like the hash of a counter, which is indistinguishable from random. This is why serious designs run continuous health tests on the raw source — repetition-count and adaptive-proportion checks — rather than testing the polished output. Testing the output tells you the cipher works. You already knew that.

What to actually do

  • For anything security-relevant, use the operating system's generator. On Linux the getrandom syscall, on Windows BCryptGenRandom, in a browser crypto.getRandomValues. These are seeded from hardware and kernel entropy and are already conditioned properly.
  • Never use a language's default rand/Math.random for anything that matters. It is a fast statistical generator, not a cryptographic one, and its state is usually recoverable from a handful of outputs.
  • If you are collecting your own entropy, debias it and test the raw source, not the whitened one.
  • And if you are settling a real dispute with a real coin: hide the starting face.