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

Když pořádáte tombolu, vybíráte týmy náhodně nebo přidělujete úkoly loterií, férovost není volitelná – jde o to. Ale „náhodné“ automaticky neznamená „spravedlivé“. Skryté zkreslení v generátorech náhodných čísel (RNG) může zkreslit výsledky způsoby, které jsou neviditelné, pokud nevíte, kde je hledat.
Tento článek vám poskytuje praktický kontrolní seznam pro kontrolu spravedlnosti jakéhokoli RNG, ať už používáte náš Generátor náhodných čísel nebo vytváříte svůj vlastní.
Co znamená férovost pro losování zaměřená na uživatele
Spravedlivé RNG přináší výsledky, kde:
- Uniformita — každý výsledek má stejnou pravděpodobnost (pro rovnoměrné rozdělení)
- Nezávislost — žádné losování není ovlivněno předchozími losováními
- Nepředvídatelnost — žádný pozorovatel nemůže předpovědět další výsledek lépe než náhoda
- Ověřitelnost — účastníci mohou potvrdit, že proces nebyl zmanipulován
Chybějící některý z těchto narušuje důvěru, i když výsledky náhodou „vypadají“.
Obvyklé zdroje zkreslení
Špatná semena
PRNG (generátor pseudonáhodných čísel) je pouze tak nepředvídatelný, jako jeho zárodek. Běžná špatná semena:
- Aktuální časové razítko — předvídatelné na milisekundu; útočník, který zhruba ví, kdy probíhá losování, může výsledek reprodukovat
- Sekvenční čítače — vůbec ne náhodné
- Vstup uživatele — mohou s ním manipulovat účastníci
Vždy z kryptografického zdroje: crypto.getRandomValues() v prohlížečích, /dev/urandom v Linuxu nebo crypto.randomBytes() v Node.js.
Představení modulu
Drobná a běžná chyba: použití operátoru modulo ke snížení náhodného čísla na rozsah.
// PŘEDMĚTNÉ — pokud rozsah RNG není násobkem 6,
// některé výsledky jsou o něco pravděpodobnější
const roll = randomUint32() % 6; // SPRÁVNĚ — vzorkování odmítnutí
function fairDiceRoll() { const max = Math.floor(0xFFFFFFFF / 6) * 6; nechat hodnotu; do { value = crypto.getRandomValues(new Uint32Array(1))[0]; } while (hodnota >= max); návratová hodnota % 6;
U 6stranné kostky je předpětí modulo s 32bitovým celým číslem pouze ~0,00000009 %. Ale pro větší rozsahy nebo 8bitové hodnoty to nabývá na významu.
Skryté filtry
Některé systémy losování tiše vylučují určité výsledky (např. filtrování „nedávných vítězů“ nebo přehazování výsledků, které se operátorovi nelíbí). To porušuje spravedlnost, i když je podkladový RNG dokonalý. Před losováním zdokumentujte a zveřejněte všechna pravidla filtrování.
Kontrolní seznam auditu pro operátory
- Zdroj entropie — Je RNG nasazeno z kryptografického zdroje? (Ne Math.random, ne časová razítka)
- Test jednotnosti — Spusťte 10 000+ vzorků a použijte test chí-kvadrát. p-hodnota by měla být > 0,05
- Zkreslení modulu — Používá kód vzorkování odmítnutí nebo nezaujatou metodu mapování?
- Nezávislost — Jsou sekvenční losování korelované? Spusťte test autokorelace na velkých sadách vzorků
- Přezkoumání kódu — Je losovací kód open source nebo auditovatelný? Skrytý kód může obsahovat zadní vrátka
- Filtrování zveřejnění — Jsou nějaké výsledky filtrovány, přehodnoceny nebo vyloučeny? Toto musí být zveřejněno
- Časování — Může operátor vidět výsledky před publikováním? Pokud ano, mohou selektivně odhodit nepříznivé losování
Vzor transparentnosti pro veřejné tomboly
Pro losování s vysokými sázkami (ceny, úkoly, výběry) použijte schéma odhalení závazku:
- Před losováním: Vygenerujte náhodný seed. Zveřejněte svůj hash SHA-256 (dále jen „závazek“) – např. na sociálních sítích nebo v dokumentu s časovým razítkem
- Spusťte losování: Použijte zdroj ke generování výsledků pomocí deterministického algoritmu
- Po losování: Zveřejněte semeno. Kdokoli může ověřit, že:
- Seed vytváří publikovaný hash
- Algoritmus seed + produkuje oznámené výsledky
K vytvoření a ověření hash závazku použijte náš Generátor hashů.
// Fáze závazku
const seed = crypto.randomBytes(32).toString('hex');
const závazek = sha256(seed); // toto zveřejníme před losováním // Fáze kreslení
const vysledek = deterministicDraw(seed, účastníci); // Fáze odhalení
// zveřejnit seed — kdokoli může ověřit sha256(seed) === závazek Spravedlivá komunikace s uživateli
Důvěra vyžaduje transparentnost. Při spouštění veřejných losování:
- Uveďte použitou metodu RNG (např. "Web Crypto API")
- Zveřejněte algoritmus kreslení (pomůže i pseudokód)
- Pro ověření použijte příkaz commit-reveal
- Zaznamenávejte a publikujte protokoly losování s časovými razítky
- Umožněte nezávislým pozorovatelům ověřit výsledky
Časté dotazy
Je Math.random dost dobrý?
Ne. Math.random() používá generátor pseudonáhodných čísel (PRNG), který není kryptograficky bezpečný. Jeho výstup lze předvídat, pokud je znám vnitřní stav. Pro spravedlivé losování použijte crypto.getRandomValues() v prohlížeči nebo crypto.randomInt() v Node.js.
Jak mohu dokázat, že losování nebylo zmanipulováno?
Použijte schéma potvrzení-odhalení: před losováním publikujte hash náhodného semene (závazek). Po losování odkryjte semínko. Kdokoli může ověřit, že seed produkuje publikovaný hash a oznámené výsledky.
Kolik vzorků potřebuji pro základní kontroly zkreslení?
Pro jednoduchou kontrolu jednotnosti N výsledků potřebujete alespoň 100×N vzorků (např. 1 000 vzorků pro losování s 10 možnostmi). Aplikujte test chí-kvadrát: pokud je p-hodnota vyšší než 0,05, distribuce je přiměřeně rovnoměrná. Pro seriózní audity použijte více než 10 000 vzorků.
Související nástroje a články
- Generátor náhodných čísel — kryptograficky spravedlivá náhodná čísla
- Generátor hashů — vytvořte hodnoty hash závazků pro ověřitelná losování
- Proč používat generátor PIN? — bezpečné náhodné PINy
- Kontrolní seznam digitální hygieny — celkové bezpečnostní postupy