Generování náhodných čísel je proces, při kterém algoritmus nebo zařízení produkuje posloupnost hodnot, které nelze předvídat. Náhodná čísla se využívají v mnoha oblastech informatiky a matematiky, například:
- Statistika
- Kryptografie
- Generování herních prvků (např. náhodné mapy, losování)
- Bezpečnostní tokeny, hesla, klíče
Přestože mluvíme o „náhodě“, tak získání doopravdy náhodného čísla je nesmírně obtížné a pro většinu problémů se jedná o přílišný nadstandard. Stačí u nich vygenerovat pouze čísla, která se blíží náhodnému číslu - tzv. pseudonáhodná číslo.
Generování pravých náhodných čísel (TRNG)
Pravá náhodná čísla (TRNG – True Random Number Generator) jsou čísla odvozená z fyzikálních jevů, které jsou skutečně náhodné, například:
- Termální šum v elektronice
- Radioaktivní rozpad
- Atmosférický šum
Výhody
- nelze je předpovědět
- vhodné pro silně bezpečnostní aplikace
Nevýhody:
- nákladnější hardware
- nižší rychlost generování
- obtížná dostupnost v běžných systémech
Generování pseudonáhodných čísel (PRNG)
V praxi se využívají téměř vždy pseudonáhodné generátory (PRNG – Pseudo Random Number Generator).
Charakteristiky PRNG:
- generují deterministickou posloupnost čísel na základě počáteční hodnoty (seed)
- stejný seed → stejná posloupnost čísel
- běží velmi rychle a nevyžadují speciální hardware
Seed (Semínko)
Jedná se o počáteční číslo, které ovlivňuje sekvenci generovaných čísel. Pokud by se povedlo útočníkovi toto číslo odhalit, tak je schopen plně zrekonstruovat vygenerovanou sekvenci čísel.
PRNG není skutečně náhodný, ale pokud má dobré vlastnosti, jeho výstup se statisticky tváří náhodně.
Kvalita generátoru náhodných čísel
U pseudonánhodných generátorů je potřeba, aby generovaly co nejkvalitnější pseudonáhodné posloupnosti čísel. Pro zajištění kvality jsou přítomny dva testy:
- Next-bit test
- State-compromised test
Next-bit test
Pokud jsou známé všechny dosavadní bity výstupu, neměli bychom být schopni předpovědět další bit s pravděpodobností vyšší než 50 %. To je zásadní požadavek například v kryptografii.
State-compromise test
Pokud dojde ke kompromitaci vnitřního stavu generátoru (například únik hodnoty seedu nebo paměti aplikace):
- útočník by neměl být schopen zpětně dopočítat předchozí výstupy
- ani předpovědět budoucí výstupy
Běžné PRNG tyto vlastnosti často nemají, což je zásadní problém u aplikací, které vyžadují bezpečnost (klíče, tokeny, hesla). Pro generování kryptograficky bezpečných pseudonáhodných čísel je pak nutné využít speciální generátory. V C# lze k tomuto účelu využít například RandomNumberGenerator (z namespace System.Security.Cryptography).
Generování náhodných čísel v C#
new Random()
Nejznámější způsob generování pseudonáhodných čísel.
Ukázka použití:
var rnd = new Random();
int number = rnd.Next(0, 100); // číslo 0–99Nevýhody této implementace:
- Random není thread-safe
- při více instancích vytvořených rychle za sebou se seedují stejným timestampem → generují stejné sekvence
- není vhodný pro bezpečnostní účely
Ukázka problému:
var rnd1 = new Random();
var rnd2 = new Random();
Console.WriteLine(rnd1.Next()); // např. 123456
Console.WriteLine(rnd2.Next()); // často stejná hodnota!Warning
Neexistuje jediný důvod proč tuto implementaci v aktuální době využívat. Vždy je lepší využít
Random.Shared.
Random.Shared
Od .NET 6 existuje nová implementace random - Random.Shared:
int number = Random.Shared.Next(0, 100);Výhody:
- thread-safe
- sdílená instance → šetří paměť
- rychlejší než opakované vytváření nových instancí
Stále však není kryptograficky bezpečná. Lze ji využít pro běžné náhodné úlohy (např. hry, simulace).
Kryptograficky bezpečné náhodné hodnoty
Pro kryptografii nebo generování tajných dat (tokeny, hesla) je vhodné v C# využívat RandomNumberGenerator:
using System.Security.Cryptography;
byte[] bytes = new byte[32];
RandomNumberGenerator.Fill(bytes); // Například 32 náhodných bajtůPokud je potřeba vygenerovat například náhodný řetězec (base64):
string randomString = Convert.ToBase64String(bytes); Console.WriteLine(randomString);