Checking a wheel spin: what is proven
How a result can be checked afterwards, and what that does and does not prove.
Why people doubt wheels
Whenever a prize is at stake, someone suspects the wheel was set up. With most online wheels there is no way to tell: the page decides in private, shows an animation, and you are asked to trust it. Many sites call the alternative "provably fair". It is worth being exact about what that can mean, whether you are drawing raffle numbers on the random number wheel or picking a presenter on the who goes first wheel.
This site records everything needed to repeat the calculation of a winner, so you do not have to trust the page: anyone can recompute the result with their own tools. What that proves, and what it cannot, is described below.
The random value
Before each spin, your browser creates a random number called the seed, using the cryptographic random generator that is built into every modern browser, the same one used for encryption keys. The seed and the list are the only inputs of the calculation. A short fingerprint of each is recorded with the result.
Because the winner follows from the seed and the list by a fixed method, nothing else can change it: not the animation, not the speed of the wheel, not where the pointer happens to stop inside the slice.
From the seed to the winner
The winner is not left to chance during the animation. It is calculated from two inputs: the seed and a hash of your list, written exactly as it was when you pressed SPIN. A short chain of hash calculations turns these into a number, and the number selects one entry. Entries that appear several times have a proportionally larger share.
The calculation is built so that every entry has exactly its fair share. Numbers that would favour some entries slightly are thrown away and the next one is used, which avoids the small bias a simple remainder would cause. The full recipe is written out on the verify page.
The place where the wheel stops inside the winning slice is only for show. It is chosen at random for the animation and is not part of the proof, which concerns who wins.
Checking a proof
- Spin, then open the Results tab and press Copy result link, or press Check this result to open the check page with the result already filled in.
- Send the link to whoever should check it. When they open it, the check page shows at once whether the result checks out. If they pasted the link into the box instead, they press Check.
- A green message means the result checks out: the list is the one that was used, and the winner follows from the recorded random value and that list. A red message says what does not fit, for example a changed list or a different winner.
The check runs in your browser and nothing is sent anywhere. The page includes a working example, so you can see a valid proof before you make your own.
What a check does not prove
A passing check shows that the winner was worked out correctly, with a method that gives every entry exactly its fair share, and that the result was not edited afterwards. It cannot show how the seed was chosen. Someone who modifies the page, or simply spins again and again until the result suits them, can still produce a result link that checks out, and no website can rule that out from a link alone.
The remedy is procedural, not technical: show the list before you spin, run the draw live or record your screen from before you press SPIN, and agree beforehand that the first spin counts. A step by step plan for prize draws is in the guide to running a fair giveaway, and the main wheel is where you try it yourself. A result check is evidence about one spin. It says nothing about whether the entries themselves were collected honestly.
Check it with your own tools
You can also verify a proof without this site. Here is the core of the calculation in Node.js, which gives the same winner for a wheel proof:
import { createHash } from 'node:crypto';
const sha = (s) => createHash('sha256').update(s);
const listHash = sha(list).digest('hex');
const total = entries.reduce((a, e) => a + e.weight, 0);
const limit = Math.floor(2 ** 32 / total) * total;
let r, i = 0;
do { r = sha(`${seed}|${listHash}|${i++}`).digest().readUInt32BE(0); } while (r >= limit);
let k = r % total;
const winner = entries.find((e) => (k -= e.weight) < 0);The variables seed, list and entries come from the proof text. Entries are the lines of the list, with a weight of 1 unless a tab and number follow the name.