> pick | shuffle | pair <
// Paste a list, pick winners, shuffle the order, or pair people into groups - all in your browser
Pick N Random Items
Draw any number of winners from your list. Pick without replacement for unique winners, or with replacement for weighted-style draws.
Unbiased Fisher-Yates Shuffle
Reorders the entire list using the classic Knuth shuffle. Every permutation is equally likely - no naive sort hacks here.
Pair Up Into Groups
Split a roster into pairs, trios, or any group size. Perfect for partner work, code review rotations, or secret santa pairings.
Seeded Reproducibility
Provide a seed string to get a deterministic draw. Same seed plus same list always produces the same result - shareable and verifiable.
// ABOUT THE RANDOM PICKER
How It Works:
This tool uses the Fisher-Yates (a.k.a. Knuth) shuffle: walk the array from the last index to the first, and at each step swap the current element with one at a uniformly random earlier index. This produces an unbiased uniform permutation in O(n) time. The naive trick array.sort(() => Math.random() - 0.5) is biased because JavaScript sort comparators must be transitive - random comparators violate that and skew the distribution. For unseeded draws we pull entropy from window.crypto.getRandomValues. When you provide a seed string, we hash it with cyrb53 to a 53-bit integer, then drive a mulberry32 PRNG so identical seeds produce identical, reproducible results.
Algorithm:
for i = n-1 down to 1: j = randInt(0, i); swap(a[i], a[j]) - unbiased Fisher-Yates
Standards & References:
- >Web Crypto API (W3C) - crypto.getRandomValues for cryptographically strong randomness
- >Fisher-Yates shuffle (1938), popularized by Donald Knuth in The Art of Computer Programming Vol. 2
- >mulberry32 - small, fast, well-distributed seeded PRNG by Tommy Ettinger
- >cyrb53 - 53-bit string hash by bryc, used to turn a seed string into a numeric PRNG state
Common Use Cases:
- >Giveaways, raffles, and naming a random winner from entries
- >Classroom name draws and student cold-call selection
- >Sports team pairing, partner workouts, and tournament brackets
- >Code review reviewer assignment across an engineering team
- >A/B test sample selection and randomized survey cohorts
- >Secret Santa pairs, gift exchanges, and team lunch buddies
- >Random testing inputs and fuzzing seeds for QA
- >Group-based decision-making and tie-breaking
- >Mock jury selection and randomized interview panels
- >Lottery-style draws for community events and prizes
Related Tools:
- >Random Number Generator — the text-based companion: pick numbers in a range with the same seeded reproducibility primitives
- >UUID Generator — random v4 identifiers when you need a unique opaque ID rather than a winner from a list
- >Password Generator — cryptographically random strings with character pool control for tokens and credentials
- >randompickerwheel.app — spinning-wheel UI complement to this text picker, perfect for live audience draws, classroom calls, and on-screen reveals
// EXAMPLE PICKS
Giveaway — pick 3 winners from 50 entries
> input:
alice@x.com
bob@x.com
carlos@x.com
…(50 lines total)
> config:
Mode=Pick N, Count=3, Allow duplicates=off, Seed=(empty)
> output:
1. carlos@x.com
2. priya@x.com
3. wei@x.com
Shuffle a 10-name list for a presentation order
> input:
Alice
Bob
Charlie
Dana
Evelyn
Farouk
Gabriela
Hiroshi
Isabella
Jamal
> config:
Mode=Shuffle, Seed=(empty)
> output:
1. Hiroshi
2. Alice
3. Farouk
4. Jamal
5. Dana
6. Evelyn
7. Bob
8. Isabella
9. Gabriela
10. Charlie
Pair up a classroom of 12 students into groups of 2
> input:
S01
S02
S03
S04
S05
S06
S07
S08
S09
S10
S11
S12
> config:
Mode=Pair Up, Group size=2, Seed=class-2026-05-02
> output:
Group 1: S07, S02
Group 2: S11, S04
Group 3: S09, S12
Group 4: S01, S06
Group 5: S03, S10
Group 6: S08, S05
Reproducible seeded draw — run twice with the same seed, get the same winners
> input:
alpha
bravo
charlie
delta
echo
foxtrot
golf
hotel
> config:
Mode=Pick N, Count=2, Seed=launch-day, Allow duplicates=off
> output:
Run 1: 1. echo
2. bravo
Run 2: 1. echo
2. bravo (identical — seeded)
// WHY NAIVE .SORT() IS BIASED
A common one-liner shuffle is arr.sort(() => Math.random() - 0.5). It looks elegant, runs in one line, and feels random — but the resulting permutation distribution is far from uniform. The ECMAScript spec requires comparator functions to be deterministic and transitive: if a < b and b < c, then a < c. A coin-flip comparator violates that contract, and the engine's sort implementation visits comparator pairs in a non-uniform pattern.
V8 (Chrome, Node) uses Timsort; older engines used quicksort or mergesort. Each implementation visits a different subset of comparator pairs and reuses cached comparisons in different ways. As Mike Bostock demonstrated empirically (bost.ocks.org/mike/shuffle/compare.html), the naive sort produces strongly biased outputs where some permutations appear several times more often than others — unacceptable for a giveaway, an A/B bucket, or any draw that has to be fair.
The correct algorithm is Fisher-Yates (Knuth shuffle): walk the array from the last index down to the first, and at each step swap the current element with one chosen uniformly at random from indices 0..i. It runs in O(n), uses O(1) extra space, and provably produces every permutation with equal probability.
// BAD: NOT uniformly random
const shuffled = arr.sort(() => Math.random() - 0.5);
// GOOD: Fisher-Yates (Knuth) shuffle
function shuffle(arr) {
const a = arr.slice();
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
// IMPLEMENT IT YOURSELF
Want to build your own picker, or audit ours? These are the exact primitives this page uses — small, dependency-free, and identical to what runs in your browser when you click PICK. Copy them straight into a Node script or another web app.
// Fisher-Yates shuffle (uniform, O(n))
function shuffle(arr, rng = Math.random) {
const a = arr.slice();
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(rng() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
// Pick N without replacement (shuffle then slice)
function pickN(arr, n, rng = Math.random) {
if (n > arr.length) {
throw new Error('n exceeds list size');
}
return shuffle(arr, rng).slice(0, n);
}
// mulberry32 seeded PRNG + cyrb53 string hash
// cyrb53: turn a seed string into a 53-bit integer
function cyrb53(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed;
let h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
// mulberry32: tiny seeded PRNG -> [0, 1)
function mulberry32(a) {
return function () {
a |= 0; a = (a + 0x6D2B79F5) | 0;
let t = a;
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
// Build a seeded picker:
const h = cyrb53('my-seed', 1);
const state = (h ^ Math.floor(h / 4294967296)) >>> 0;
const rng = mulberry32(state);
const winners = pickN(['alice', 'bob', 'carlos'], 2, rng);
>> frequently asked questions
Q: How is the randomness generated?
A: When no seed is provided, we use window.crypto.getRandomValues, the browser's cryptographically secure random number generator backed by the Web Crypto API. It is the same source of entropy used for cryptographic keys and tokens, so it is more than strong enough for raffles and shuffles. When you supply a seed, we deterministically derive a 53-bit state via the cyrb53 string hash and feed it into a mulberry32 PRNG so the draw is reproducible.
Q: Can I get the same result twice using a seed?
A: Yes. Type any string into the SEED field - a date, a contest name, a hash, anything. The same seed combined with the same input list and the same mode will always produce exactly the same output. This is invaluable for transparent giveaways where you want to publish the seed in advance and let participants verify the draw, or for engineering rotations that need to be reproducible across machines.
Q: What is the difference between Pick N and Shuffle?
A: Pick N selects a subset of size N from your list, optionally with replacement (duplicates allowed). Shuffle returns the entire list reordered - no items are dropped or repeated, just rearranged. Use Pick N when you only want a few winners out of many entries; use Shuffle when every item still needs to participate but in a new random order, like a presentation queue or playlist.
Q: Is array.sort(() => Math.random() - 0.5) actually random?
A: No, it is biased. The ECMAScript spec requires sort comparators to be deterministic and transitive (if a < b and b < c then a < c). A random comparator violates that contract, and different JavaScript engines run different underlying sort algorithms (TimSort, mergesort, quicksort) which interact with the random comparator in different ways. The result is a non-uniform distribution where some permutations appear far more often than others. Fisher-Yates is the correct algorithm.
Q: Can I pair up an odd-count list?
A: Yes. The Pair Up mode shuffles your list with Fisher-Yates and then chunks it by your chosen group size. If the total does not divide evenly, the final group will be smaller and is clearly labelled as a leftover group in the output. For an odd list you can either accept a solo entry, increase the group size, or add a placeholder name like "bye" before drawing.
Q: Is my list uploaded anywhere?
A: No. This tool is 100% client-side - your list, your seed, and the output never leave your browser. There is no server call, no logging, and no analytics on the input. You can disconnect from the internet after the page loads and every button still works. Refresh the page and the data is gone for good.
Q: Is there a visual spinning wheel version of this tool?
A: For an interactive wheel-of-names experience with animation, sound effects, and a big visual reveal, see randompickerwheel.app. It is a complementary product focused on live audience draws and screen sharing. This page is a text-first picker focused on bulk lists, reproducible seeded draws, CSV export, and pairing - useful when you need a quick deterministic answer rather than a presentation.