Je váš generátor náhodných čísel spravodlivý? Kontrolný zoznam praktického auditu

Keď spustíte tombolu, náhodne vyberáte tímy alebo prideľujete úlohy lotériou, férovosť nie je voliteľná – ide o to. Ale „náhodné“ automaticky neznamená „spravodlivé“. Skryté odchýlky v generátoroch náhodných čísel (RNG) môžu skresliť výsledky spôsobom, ktorý je neviditeľný, pokiaľ neviete, kde hľadať.
Tento článok vám poskytuje praktický kontrolný zoznam na kontrolu spravodlivosti akéhokoľvek RNG, či už používate náš generátor náhodných čísel alebo si vytvárate svoj vlastný.
Čo znamená spravodlivosť pre žrebovania orientované na používateľa
Spravodlivé RNG prináša výsledky, kde:
- Jednotnosť — každý výsledok má rovnakú pravdepodobnosť (pre rovnomerné rozdelenia)
- Nezávislosť — žiadne žrebovanie nie je ovplyvnené predchádzajúcimi žrebovaniami
- Nepredvídateľnosť — žiadny pozorovateľ nedokáže predpovedať ďalší výsledok lepšie ako náhoda
- Overiteľnosť — účastníci môžu potvrdiť, že proces nebol zmanipulovaný
Chýbajúca ktorákoľvek z týchto možností narúša dôveru, aj keď výsledky náhodou „vyzerajú“.
Bežné zdroje zaujatosti
Zlé semená
PRNG (generátor pseudonáhodných čísel) je len taký nepredvídateľný ako jeho základ. Bežné zlé semená:
- Aktuálna časová pečiatka — predvídateľná na milisekundu; útočník, ktorý približne vie, kedy prebieha žrebovanie, môže reprodukovať výsledok
- Sekvenčné počítadlá — vôbec nie náhodné
- Vstup používateľa — môžu s ním manipulovať účastníci
Vždy z kryptografického zdroja: crypto.getRandomValues() v prehliadačoch, /dev/urandom v systéme Linux alebo crypto.randomBytes() v Node.js.
Smerovanie modulu
Jemná a bežná chyba: používanie operátora modulo na zmenšenie náhodného čísla na rozsah.
// OBJEDNATÝ — ak rozsah RNG nie je násobkom 6,
// niektoré výsledky sú o niečo pravdepodobnejšie
const roll = randomUint32() % 6; // SPRÁVNE — vzorkovanie odmietnutia
function fairDiceRoll() { const max = Math.floor(0xFFFFFFFF / 6) * 6; nechať hodnotu; do { value = crypto.getRandomValues(new Uint32Array(1))[0]; } while (hodnota >= max); návratová hodnota % 6;
Pre 6-strannú matricu je modulo bias s 32-bitovým celým číslom iba ~0,00000009 %. Ale pre väčšie rozsahy alebo 8-bitové hodnoty sa to stáva významným.
Skryté filtre
Niektoré systémy žrebovania potichu vylučujú určité výsledky (napr. odfiltrovanie „nedávnych víťazov“ alebo prehodnotenie výsledkov, ktoré sa operátorovi nepáčia). To porušuje spravodlivosť, aj keď je základný RNG dokonalý. Pred žrebovaním zdokumentujte a zverejnite všetky pravidlá filtrovania.
Kontrolný zoznam auditu pre operátorov
- Zdroj entropie — Je RNG nasadený z kryptografického zdroja? (Nie Math.random, nie časové pečiatky)
- Test jednotnosti — Spustite viac ako 10 000 vzoriek a použite test chí-kvadrát. p-hodnota by mala byť > 0,05
- Odchýlka modulu — Používa kód vzorkovanie odmietnutia alebo nezaujatú metódu mapovania?
- Nezávislosť — Sú sekvenčné žrebovania korelované? Spustite test autokorelácie na veľkých súboroch vzoriek
- Revízia kódu — Je žrebovací kód open source alebo auditovateľný? Skrytý kód môže obsahovať zadné vrátka
- Filtrovanie zverejnených informácií — Sú nejaké výsledky filtrované, prerolované alebo vylúčené? Toto musí byť zverejnené
- Načasovanie — Môže operátor vidieť výsledky pred zverejnením? Ak áno, môžu selektívne vyradiť nepriaznivé žreby
Vzor transparentnosti pre verejné tomboly
V prípade žrebovaní s vysokými stávkami (ceny, úlohy, výbery) použite schému odhalenia záväzku:
- Pred žrebovaním: Vytvorte náhodný základ. Zverejnite svoj hash SHA-256 (ďalej len „záväzok“) – napr. na sociálnych médiách alebo v dokumente s časovou pečiatkou
- Spustite žrebovanie: Použite základ na generovanie výsledkov pomocou deterministického algoritmu
- Po žrebovaní: Zverejnite základ. Ktokoľvek môže overiť, že:
- Semeno vytvára publikovaný hash
- Algoritmus seed + vytvára oznámené výsledky
Na vytvorenie a overenie hash záväzku použite náš Generátor hashov.
// Fáza záväzku
const seed = crypto.randomBytes(32).toString('hex');
const záväzok = sha256(seed); // zverejnite to pred žrebovaním // Fáza kreslenia
const vysledok = deterministicDraw(seed, participanti); // Fáza odhalenia
// zverejniť seed — ktokoľvek môže overiť sha256(seed) === záväzok Správna komunikácia s používateľmi
Dôvera vyžaduje transparentnosť. Pri verejných žrebovaniach:
- Uveďte použitú metódu RNG (napr. „Web Crypto API“)
- Zverejnite algoritmus kreslenia (dokonca pomáha aj pseudokód)
- Na overenie použite príkaz commit-reveal
- Zaznamenávajte a publikujte denníky žrebovania s časovými pečiatkami
- Umožnite nezávislým pozorovateľom overiť výsledky
Časté otázky
Je Math.random dosť dobrý?
Nie. Math.random() používa generátor pseudonáhodných čísel (PRNG), ktorý nie je kryptograficky bezpečný. Jeho výstup možno predpovedať, ak je známy vnútorný stav. Na čestné žrebovanie použite crypto.getRandomValues() v prehliadači alebo crypto.randomInt() v Node.js.
Ako môžem dokázať, že žreb nebol zmanipulovaný?
Použite schému odovzdania a odhalenia: pred žrebovaním zverejnite hash náhodného semena (záväzku). Po žrebovaní odhaľte semienko. Ktokoľvek môže overiť, že seed produkuje publikovaný hash a ohlásené výsledky.
Koľko vzoriek potrebujem na základné kontroly skreslenia?
Na jednoduchú kontrolu jednotnosti N výsledkov potrebujete aspoň 100 × N vzoriek (napr. 1 000 vzoriek na žrebovanie s 10 možnosťami). Aplikujte test chí-kvadrát: ak je p-hodnota vyššia ako 0,05, distribúcia je primerane rovnomerná. Na seriózne audity použite viac ako 10 000 vzoriek.
Súvisiace nástroje a články
- Generátor náhodných čísel — kryptograficky spravodlivé náhodné čísla
- Generátor hashov — vytvorte hodnoty hash záväzku pre overiteľné žrebovania
- Prečo používať generátor kódov PIN? — bezpečné náhodné kódy PIN
- Kontrolný zoznam digitálnej hygieny — celkové bezpečnostné postupy