Il tuo generatore di numeri casuali è corretto? Lista di controllo pratica per l'audit
Quando organizzi una lotteria, scegli squadre casualmente o assegni compiti tramite lotteria, l'equità non è un optional: è il punto centrale. Ma "casuale" non significa automaticamente "giusto". Distorsioni nascoste nei generatori di numeri casuali (RNG) possono distorcere i risultati in modi invisibili a meno che tu non sappia dove guardare.
Questo articolo fornisce una pratica lista di controllo per verificare l'equità di qualsiasi RNG, sia che tu stia utilizzando il nostro Generatore di numeri casuali o che tu stia costruendo il tuo.
Cosa significa equità per le estrazioni rivolte agli utenti
Un RNG giusto produce risultati dove:
La mancanza di uno di questi elementi compromette la fiducia, anche se i risultati "sembrano" casuali.
Fonti comuni di pregiudizi
Bad Seeds
A PRNG (generatore di numeri pseudo-casuali) è imprevedibile quanto il suo seme. Semi cattivi comuni:
Semina sempre da una fonte crittografica: crypto.getRandomValues() nei browser, /dev/urandom su Linux o crypto.randomBytes() in Node.js.
Modulo Bias
Un bug sottile e comune: utilizzare l'operatore modulo per ridurre un numero casuale a un intervallo.
// BIASED: se l'intervallo RNG non è un multiplo di 6,
// alcuni risultati sono leggermente più probabili
const roll = randomUint32() % 6; // CORRETTO: campionamento del rifiuto
funzione fairDiceRoll() { const max = Math.floor(0xFFFFFFFF / 6) * 6; lascia valore; esegui { value = crypto.getRandomValues(new Uint32Array(1))[0]; } while (valore >= max); valore restituito % 6;
}Per un dado a 6 facce, la polarizzazione del modulo con un numero intero a 32 bit è solo ~0,00000009%. Ma per intervalli più ampi o valori a 8 bit, diventa significativo.
Filtri nascosti
Alcuni sistemi di estrazione escludono silenziosamente determinati risultati (ad esempio, filtrando i "vincitori recenti" o rilanciando i risultati che non piacciono all'operatore). Ciò viola l’equità anche se il RNG sottostante è perfetto. Documentare e divulgare eventuali regole di filtraggio prima dell'estrazione.
Lista di controllo di controllo per gli operatori
__Fonte entropia — L'RNG viene seminato da una fonte crittografica? (Non Math.random, non timestamp) Test di uniformità: esegui oltre 10.000 campioni e applica un test chi quadrato. il valore p dovrebbe essere > 0,05 Modulo bias — Il codice utilizza il campionamento del rifiuto o un metodo di mappatura imparziale? Independence — Le estrazioni sequenziali sono correlate? Esegui un test di autocorrelazione su set di campioni di grandi dimensioni Revisione del codice — Il codice di estrazione è open source o verificabile? Il codice nascosto può contenere backdoor Informativa sul filtraggio — I risultati vengono filtrati, rilanciati o esclusi? Questo deve essere divulgato Timing — L'operatore può vedere i risultati prima della pubblicazione? Se sì, possono scartare selettivamente le estrazioni sfavorevoli Modello di trasparenza per lotterie pubbliche
Per le estrazioni con posta alta (premi, assegnazioni, selezioni), utilizzare uno schema commit-reveal:
Prima dell'estrazione: Genera un seme casuale. Pubblicare il proprio hash SHA-256 (l'"impegno"), ad esempio sui social media o su un documento con timestamp Esegui l'estrazione: Usa il seme per generare risultati con un algoritmo deterministico Dopo l'estrazione: Pubblica il seme. Chiunque può verificarlo:- Il seed produce l'hash pubblicato
- Il seme + algoritmo produce i risultati annunciati
Utilizza il nostro Hash Generator per creare e verificare l'hash dell'impegno.
// Fase di impegno
const seed = crypto.randomBytes(32).toString('hex');
impegno costante = sha256(seme); // pubblicalo prima dell'estrazione // Fase di estrazione
risultato const = deterministicDraw(seme, partecipanti); // Fase di rivelazione
// pubblica seed: chiunque può verificare sha256(seed) === commitment
Comunicare correttezza agli utenti
La fiducia richiede trasparenza. Quando si eseguono estrazioni pubbliche:
Indica il metodo RNG utilizzato (es. "Web Crypto API") Pubblica l'algoritmo di estrazione (anche lo pseudocodice aiuta) Utilizza commit-reveal per la verificabilità Registra e pubblica i registri delle estrazioni con timestamp Consenti a osservatori indipendenti di verificare i risultati FAQ
Math.random è abbastanza buono?
No. Math.random() utilizza un generatore di numeri pseudo-casuali (PRNG) che non è crittograficamente sicuro. Il suo output può essere previsto se lo stato interno è noto. Per estrazioni corrette, utilizza crypto.getRandomValues() nel browser o crypto.randomInt() in Node.js.
Come posso dimostrare che un'estrazione non è stata manipolata?
Utilizza uno schema commit-reveal: prima dell'estrazione, pubblica un hash del seed casuale (impegno). Dopo l'estrazione, rivela il seme. Chiunque può verificare che il seed produca l'hash pubblicato e i risultati annunciati.
Di quanti campioni ho bisogno per i controlli di bias di base?
Per un semplice controllo di uniformità tra N risultati, sono necessari almeno 100×N campioni (ad esempio, 1.000 campioni per un'estrazione a 10 opzioni). Applicare un test chi quadrato: se il valore p è superiore a 0,05, la distribuzione è ragionevolmente uniforme. Per audit seri, utilizza oltre 10.000 campioni.
Strumenti e articoli correlati
Generatore di numeri casuali — numeri casuali crittograficamente corretti Hash Generator: crea hash di impegno per estrazioni verificabili Perché utilizzare un generatore di PIN? — proteggere PIN casuali __Lista di controllo per l'igiene digitale — pratiche di sicurezza generali