> pick | shuffle | pair <
// Incolla un elenco, estrai i vincitori, mescola l'ordine o dividi le persone in gruppi - tutto nel tuo browser
Estrai N elementi a caso
Estrai un numero qualsiasi di vincitori dal tuo elenco. Senza reinserimento per vincitori unici, oppure con reinserimento per estrazioni in stile ponderato.
Mescolamento Fisher-Yates senza distorsioni
Riordina l'intero elenco con il classico mescolamento di Knuth. Ogni permutazione è equiprobabile - nessun trucco di ordinamento ingenuo qui.
Dividi in gruppi
Suddividi un elenco in coppie, trii o qualsiasi dimensione di gruppo. Perfetto per il lavoro in coppia, le rotazioni di revisione del codice o gli abbinamenti del Babbo Natale segreto.
Riproducibilità con seme
Fornisci una stringa di seme per ottenere un'estrazione deterministica. Lo stesso seme con lo stesso elenco produce sempre lo stesso risultato - condivisibile e verificabile.
// INFORMAZIONI SUL SELETTORE CASUALE
Come funziona:
Questo strumento usa il mescolamento di Fisher-Yates (detto anche Knuth): percorri l'array dall'ultimo indice al primo e, a ogni passo, scambia l'elemento corrente con uno a un indice precedente scelto in modo uniformemente casuale. Ciò produce una permutazione uniforme e priva di distorsioni in tempo O(n). Il trucco ingenuo array.sort(() => Math.random() - 0.5) è distorto perché i comparatori di ordinamento di JavaScript devono essere transitivi - i comparatori casuali violano questa regola e falsano la distribuzione. Per le estrazioni senza seme attingiamo entropia da window.crypto.getRandomValues. Quando fornisci una stringa di seme, la convertiamo con cyrb53 in un intero a 53 bit e poi alimentiamo un PRNG mulberry32 in modo che semi identici producano risultati identici e riproducibili.
Algoritmo:
for i = n-1 down to 1: j = randInt(0, i); swap(a[i], a[j]) - unbiased Fisher-Yates
Standard e riferimenti:
- >Web Crypto API (W3C) - crypto.getRandomValues per casualità crittograficamente forte
- >Mescolamento di Fisher-Yates (1938), reso popolare da Donald Knuth in The Art of Computer Programming Vol. 2
- >mulberry32 - PRNG con seme piccolo, veloce e ben distribuito di Tommy Ettinger
- >cyrb53 - hash di stringa a 53 bit di bryc, usato per trasformare una stringa di seme in uno stato numerico del PRNG
Casi d'uso comuni:
- >Concorsi, lotterie e scelta di un vincitore casuale tra le partecipazioni
- >Estrazione di nomi in classe e selezione di studenti per domande a sorpresa
- >Abbinamento di squadre sportive, allenamenti in coppia e tabelloni di torneo
- >Assegnazione dei revisori del codice in un team di ingegneria
- >Selezione del campione per test A/B e coorti di sondaggio randomizzate
- >Coppie del Babbo Natale segreto, scambi di regali e compagni di pranzo del team
- >Input di test casuali e semi di fuzzing per il QA
- >Decisioni di gruppo e spareggi
- >Selezione di giurie simulate e panel di colloqui randomizzati
- >Estrazioni in stile lotteria per eventi della comunità e premi
Strumenti correlati:
- >Generatore di numeri casuali — il complemento basato sul testo: scegli numeri in un intervallo con le stesse primitive di riproducibilità con seme
- >Generatore di UUID — identificatori v4 casuali quando serve un ID opaco univoco anziché un vincitore estratto da un elenco
- >Generatore di password — stringhe crittograficamente casuali con controllo del set di caratteri per token e credenziali
- >randompickerwheel.app — interfaccia a ruota della fortuna complementare a questo selettore testuale, perfetta per estrazioni davanti al pubblico dal vivo, domande in classe e rivelazioni a schermo
// ESEMPI DI ESTRAZIONE
Concorso — estrai 3 vincitori da 50 partecipazioni
> input:
alice@x.com
bob@x.com
carlos@x.com
…(50 righe in totale)
> config:
Modalità=Pick N, Quantità=3, Consenti duplicati=off, Seme=(vuoto)
> output:
1. carlos@x.com
2. priya@x.com
3. wei@x.com
Mescola un elenco di 10 nomi per un ordine di presentazione
> input:
Alice
Bob
Charlie
Dana
Evelyn
Farouk
Gabriela
Hiroshi
Isabella
Jamal
> config:
Modalità=Shuffle, Seme=(vuoto)
> output:
1. Hiroshi
2. Alice
3. Farouk
4. Jamal
5. Dana
6. Evelyn
7. Bob
8. Isabella
9. Gabriela
10. Charlie
Dividi una classe di 12 studenti in gruppi da 2
> input:
S01
S02
S03
S04
S05
S06
S07
S08
S09
S10
S11
S12
> config:
Modalità=Pair Up, Dimensione gruppo=2, Seme=class-2026-05-02
> output:
Gruppo 1: S07, S02
Gruppo 2: S11, S04
Gruppo 3: S09, S12
Gruppo 4: S01, S06
Gruppo 5: S03, S10
Gruppo 6: S08, S05
Estrazione riproducibile con seme — eseguila due volte con lo stesso seme, ottieni gli stessi vincitori
> input:
alpha
bravo
charlie
delta
echo
foxtrot
golf
hotel
> config:
Modalità=Pick N, Quantità=2, Seme=launch-day, Consenti duplicati=off
> output:
Esecuzione 1: 1. echo
2. bravo
Esecuzione 2: 1. echo
2. bravo (identico — con seme)
// PERCHÉ .SORT() INGENUO È DISTORTO
Un mescolamento in una riga molto diffuso è arr.sort(() => Math.random() - 0.5). Sembra elegante, sta in una riga e dà l'impressione di essere casuale — ma la distribuzione delle permutazioni risultanti è tutt'altro che uniforme. La specifica ECMAScript richiede che le funzioni di confronto siano deterministiche e transitive: se a < b e b < c, allora a < c. Un comparatore a testa o croce viola questo contratto e l'implementazione di ordinamento del motore visita le coppie di confronto secondo uno schema non uniforme.
V8 (Chrome, Node) usa Timsort; i motori più vecchi usavano quicksort o mergesort. Ogni implementazione visita un sottoinsieme diverso di coppie di confronto e riutilizza i confronti memorizzati in cache in modi diversi. Come dimostrato empiricamente da Mike Bostock (bost.ocks.org/mike/shuffle/compare.html), l'ordinamento ingenuo produce output fortemente distorti in cui alcune permutazioni compaiono molte più volte di altre — inaccettabile per un concorso, un bucket A/B o qualsiasi estrazione che debba essere equa.
L'algoritmo corretto è Fisher-Yates (mescolamento di Knuth): percorri l'array dall'ultimo indice al primo e, a ogni passo, scambia l'elemento corrente con uno scelto in modo uniformemente casuale tra gli indici 0..i. Viene eseguito in O(n), usa O(1) di spazio aggiuntivo e produce in modo dimostrabile ogni permutazione con uguale probabilità.
// 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;
}
// IMPLEMENTALO TU STESSO
Vuoi creare il tuo selettore o verificare il nostro? Queste sono le primitive esatte usate da questa pagina — piccole, senza dipendenze e identiche a ciò che gira nel tuo browser quando fai clic su PICK. Copiale direttamente in uno script Node o in un'altra app web.
// 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);
>> domande frequenti
D: Come viene generata la casualità?
R: Quando non viene fornito alcun seme, usiamo window.crypto.getRandomValues, il generatore di numeri casuali crittograficamente sicuro del browser basato sulla Web Crypto API. È la stessa fonte di entropia usata per chiavi e token crittografici, quindi più che robusta per lotterie e mescolamenti. Quando fornisci un seme, deriviamo in modo deterministico uno stato a 53 bit tramite l'hash di stringa cyrb53 e lo immettiamo in un PRNG mulberry32 affinché l'estrazione sia riproducibile.
D: Posso ottenere lo stesso risultato due volte usando un seme?
R: Sì. Digita una stringa qualsiasi nel campo SEME - una data, il nome di un concorso, un hash, qualsiasi cosa. Lo stesso seme combinato con lo stesso elenco di ingresso e la stessa modalità produrrà sempre esattamente lo stesso output. È preziosissimo per concorsi trasparenti in cui vuoi pubblicare il seme in anticipo e lasciare che i partecipanti verifichino l'estrazione, o per rotazioni di ingegneria che devono essere riproducibili tra le macchine.
D: Qual è la differenza tra Pick N e Shuffle?
R: Pick N seleziona un sottoinsieme di dimensione N dal tuo elenco, facoltativamente con reinserimento (duplicati consentiti). Shuffle restituisce l'intero elenco riordinato - nessun elemento viene eliminato o ripetuto, solo riorganizzato. Usa Pick N quando vuoi solo pochi vincitori tra molte partecipazioni; usa Shuffle quando ogni elemento deve ancora partecipare ma in un nuovo ordine casuale, come una coda di presentazione o una playlist.
D: array.sort(() => Math.random() - 0.5) è davvero casuale?
R: No, è distorto. La specifica ECMAScript richiede che i comparatori di ordinamento siano deterministici e transitivi (se a < b e b < c allora a < c). Un comparatore casuale viola questo contratto e diversi motori JavaScript eseguono diversi algoritmi di ordinamento sottostanti (TimSort, mergesort, quicksort) che interagiscono con il comparatore casuale in modi diversi. Il risultato è una distribuzione non uniforme in cui alcune permutazioni compaiono molto più spesso di altre. Fisher-Yates è l'algoritmo corretto.
D: Posso abbinare un elenco con un numero dispari di elementi?
R: Sì. La modalità Pair Up mescola il tuo elenco con Fisher-Yates e poi lo suddivide in base alla dimensione del gruppo scelta. Se il totale non si divide in modo esatto, l'ultimo gruppo sarà più piccolo e viene chiaramente etichettato come gruppo residuo nell'output. Per un elenco dispari puoi accettare una voce singola, aumentare la dimensione del gruppo o aggiungere un nome segnaposto come "bye" prima dell'estrazione.
D: Il mio elenco viene caricato da qualche parte?
R: No. Questo strumento è al 100% lato client - il tuo elenco, il tuo seme e l'output non lasciano mai il tuo browser. Non c'è alcuna chiamata al server, nessuna registrazione e nessuna analisi sull'input. Puoi disconnetterti da internet dopo il caricamento della pagina e ogni pulsante continua a funzionare. Ricarica la pagina e i dati spariscono per sempre.
D: Esiste una versione visiva con ruota della fortuna di questo strumento?
R: Per un'esperienza interattiva con ruota dei nomi, animazione, effetti sonori e una grande rivelazione visiva, consulta randompickerwheel.app. È un prodotto complementare incentrato su estrazioni davanti al pubblico dal vivo e condivisione dello schermo. Questa pagina è un selettore orientato al testo, focalizzato su elenchi di massa, estrazioni riproducibili con seme, esportazione CSV e abbinamento - utile quando serve una risposta deterministica rapida anziché una presentazione.