Skip to tool
ecech.
📊 Math & Statistics

The One-Line Shuffle Everyone Uses Leaves the First Item in Place 36% of the Time

sort with a random comparator is measurably biased. This uses Fisher-Yates with the browser's cryptographic random source, and shows you the difference.

Result


See the bias for yourself

Shuffle four items many times and count where the first one ends up. A fair shuffle puts it in each position 25% of the time.

Advertisement

How the calculation works

Where the first item lands, over 60,000 shuffles of four sort with a random comparator 35.8%   17.0%   15.7%   31.5% Fisher-Yates 24.9%   24.8%   25.5%   24.8% Real measurements. The one-line version is not slightly off — it is not a shuffle.

How to Use This Tool

Paste a list and draw. The shuffle is Fisher-Yates using the browser's cryptographic random source, and you can measure the alternative for yourself at the bottom of the page.

Why the one-line shuffle is broken

The most-copied shuffle in JavaScript is array.sort(() => Math.random() - 0.5). It is short, it looks obviously fair, and it produces a measurably skewed distribution.

The reason is that sorting algorithms rely on the comparator being consistent — if a is less than b and b is less than c, then a must be less than c. A random comparator breaks that promise, so the algorithm's internal decisions no longer mean anything and the final order depends on the implementation's traversal order rather than on chance.

The measured result on four items: the first element stays in position about 36% of the time instead of 25%, and lands in the middle two positions only about 16% each. That is not a rounding artefact. Run the comparison below and watch it appear.

What Fisher-Yates does instead

Walk backwards through the array. At each position, pick a random index from the part not yet fixed and swap. Every one of the possible orderings comes out with equal probability, and it takes one pass.

It has been the correct answer since 1938 and it is four lines long. The only reason the broken version persists is that it fits on one.

Two sources of randomness Math.random() fast, deterministic algorithm, seeded by the engine fine for animation and sampling, not for anything at stake crypto.getRandomValues() from the operating system's entropy pool unpredictable, and available in every browser
The second costs nothing extra, which is why this page uses it by default.

Math.random is not secure

It is a pseudo-random generator: a deterministic algorithm producing a sequence that looks random. For a game, an animation or picking a placeholder, that is entirely fine.

It is not fine when someone has a reason to game the result. The sequence is predictable in principle from enough observed output, and browsers make no promises about it. This tool uses crypto.getRandomValues, which draws on the operating system's entropy pool, because a prize draw is exactly the case where the difference matters and it costs nothing.

Drawing more than one winner

With "no repeats" on, the list is shuffled and the first few are taken, which is the correct way to draw several distinct winners. Without it, each draw is independent and the same name can come up twice — which is what you want for dice or simulated trials and not what you want for a raffle.

If it needs to be provably fair

For anything with real value at stake, a tool on a web page is the wrong instrument — not because the arithmetic is wrong, but because nobody can verify what happened. The usual answer is to publish the list and a commitment in advance, then draw using a public source of randomness that nobody controls, so participants can check afterwards. That is a different problem from generating a good random number, and it is the one that matters when people care about the outcome.

Advertisement

Frequently Asked Questions

Is array.sort(() => Math.random() - 0.5) a fair shuffle?
No. Sorting algorithms assume the comparator is consistent, and a random one breaks that, so the result depends on the sorting implementation rather than on chance. Measured over 60,000 shuffles of four items, the first element stayed in place about 36% of the time instead of 25%.
What is the correct way to shuffle an array?
Fisher-Yates: walk backwards through the array, and at each position swap with a randomly chosen index from the portion not yet fixed. Every possible ordering comes out equally likely, in a single pass. It is four lines rather than one, which is the only reason the broken version persists.
Is Math.random good enough for a prize draw?
Not if anyone has a reason to game it. Math.random is a deterministic pseudo-random generator with no security guarantees, fine for animation or sampling. crypto.getRandomValues draws on the operating system's entropy pool, is available in every browser, and costs nothing extra.
How do I pick several winners without repeats?
Shuffle the whole list and take the first few. Drawing repeatedly and discarding duplicates works but gets slow as the list empties, and drawing independently each time lets the same name come up twice — which is right for dice and wrong for a raffle.
Can I trust an online picker for something valuable?
The arithmetic can be correct and still not be verifiable, which is the real problem. For anything with value at stake, publish the entrant list and a commitment beforehand and draw from a public randomness source participants can check afterwards. Verifiability and randomness are different problems.
Does the list get sent anywhere?
No. Everything runs in your browser and nothing is transmitted.

Related tools in Math & Statistics

Browse all Math & Statistics tools
The desk where ecech. tools get written: a laptop, a notebook of to-dos and a whiteboard listing the tools on the site.

Made by one person

ecech. is not a content farm. Every tool here is written and checked by hand, one at a time, by someone who wanted the tool to exist and could not find a version that showed its working.

No accounts and no sign-in, and nothing you type reaches a server — every calculation on this page runs inside your browser. The ads are served by Google and do set their own cookies, which is set out in full on the privacy page. More about the site.