How this is worked out
Every draw uses crypto.getRandomValues, the browser's cryptographic random source, rather than Math.random. For choosing who makes the tea that is overkill; for a prize draw it is the difference between a fair result and one an informed participant could predict, and it costs nothing.
Shuffling uses Fisher-Yates, which is the only shuffle that gives every possible ordering exactly equal probability. The obvious-looking alternative — sorting by a random key — does not: it produces a measurably biased distribution, and it is a genuinely famous bug that shipped in a major browser ballot screen.
Two different questions, kept separate. Drawing WITHOUT replacement is a hat: every name comes out at most once. Drawing WITH replacement is a die: the same value can come up repeatedly. Conflating them is how a raffle draws the same person twice, so this tool asks which you meant rather than guessing.
The modulo trap applies here too. Taking random % 6 to roll a die biases the low faces, because 256 is not a multiple of 6. Values in the biased tail are rejected and redrawn, so every outcome is genuinely equally likely.
A worked example
- A list of 5 names
- Amara, Ben, Chidi, Dana, Eli
- Pick 1 without repeats
- each has a 20% chance
- Pick 3 without repeats
- each has a 60% chance
- Pick 8 without repeats
- capped at 5 — there are only 5
- Pick 8 with repeats
- 8 draws, duplicates possible
- Shuffle
- all 120 orderings equally likely
- A number 1–100
- 100 equally likely outcomes
Why not Math.random
Math.random is a fast pseudo-random generator designed for simulations and animation, where speed matters and predictability does not. Its internal state can often be recovered from a modest number of observed outputs, after which every future value is known in advance.
For a shuffle animation that is irrelevant. For a giveaway with something valuable at the end, it means a participant who can observe enough draws could in principle predict the next one — and nothing about the output would look wrong. The failure is completely invisible from the results.
crypto.getRandomValues has no such weakness and is available in every browser. There is no performance reason to prefer the weaker one at these volumes, so this tool simply does not use it anywhere.
With or without replacement is the question people get wrong
Drawing names from a hat is without replacement: once a name is out, it cannot come out again. Rolling a die is with replacement: a six does not stop another six. They are different operations with different results, and which one you want depends entirely on what you are doing.
A raffle with three prizes is almost always without replacement — you want three different winners. Assigning a random reviewer to each of twenty pull requests is with replacement, because the same reviewer can legitimately get several.
If you ask for more picks than the list can supply without repeats, this tool gives you the whole list and says so, rather than silently repeating entries or returning fewer than you asked for without explanation.
Fisher-Yates, and the shuffle that looks fine and is not
The intuitive way to shuffle is to give each item a random number and sort by it. It is one line, it looks obviously correct, and it produces a biased distribution — some orderings come up meaningfully more often than others, depending on the sort algorithm underneath.
This is not a theoretical concern. A well-known instance shipped in Microsoft's browser-choice screen in Europe, which was legally required to present browsers in random order and, because of exactly this bug, put one browser in last place far more often than chance would.
Fisher-Yates walks the list from the end, swapping each item with a randomly chosen earlier one. It is barely longer to write, it is provably uniform, and it is what this tool uses.
What "fair" means, and what it cannot fix
A fair draw means every eligible entry had an equal chance at the moment of drawing. It says nothing about whether the entry list itself was fair — duplicates, people entered twice under different spellings, or an entry that never made it into the box are all upstream problems a random picker cannot see.
For anything with a meaningful prize, the useful practice is to make the list itself verifiable: publish it before drawing, or record the draw. This tool deliberately keeps nothing and sends nothing, which is good for privacy and means it cannot serve as evidence of anything.
For a formal prize promotion there may be legal requirements about independent verification and record keeping, which vary by country and by prize value. A browser tool is the right instrument for choosing lunch and the wrong one for a regulated competition.
Assumptions and sources
- Random source
- crypto.getRandomValues, with rejection sampling so no outcome is favoured by modulo bias.
- Shuffle
- Fisher-Yates, the standard uniform shuffle. Sorting by a random key is not uniform and is not used.
- Replacement
- Picking without replacement returns distinct entries and is capped at the list length; picking with replacement allows duplicates.
- Privacy
- Your list stays in the browser. Nothing is transmitted and nothing is stored, which also means this tool cannot serve as a record of a draw.