V programovacích jazycích jako je C/C++, ale i Go, je potřeba před vygenerováním náhodného čísla nastavit seed. Ten totiž přímo určuje, jak bude vypadat posloupnost čísel, které bude vracet generátor (PRNG). U jazyků jako je Python, PHP Nebo JavaScript se seed nastavovat nemusí. Je totiž nastaven automaticky, nejčastěji pomocí aktuálního času počítače nebo jiného vstupu.
Proč si chtít nastavit vlastní seed?
Z odstavce výše tedy vyplývá, že pokud se seed nenastaví, nebo se nastaví pomocí konstanty, bude generována posloupnost vždy stejná. To se může hodit při debugování nebo unit testech. Ale jsou i jiné situace, kdy se to může hodit. Osobně jsem možnost nastavit vlastní seed využil 2x.
- Na hlavní stránce mého webu se zobrazují 3 náhodné recenze z 5. Nemění se ale při každém načtení, ale po celý den je výběr a pořadí stejné. Jako seed totiž používám aktuální číslo dne.
- V nástroji Regex patterns to sentences pro generování souborů pro Google DialogFlow se v některých případech vybírají náhodná slova. Pokud je ale výsledný soubor verzován, není příjemné, když se kompletně změní při přegenerování. Proto je možné si seed nastavit.
Na hlavní stránce používám sice vlastní seed, ale zamíchat pole není tak triviální, jak se může zdát. Více je to rozebráno v článku Shuffle - náhodné seřazení pole.
Malá ukázka s Pythonem, jak konstantní seed bude stále generovat stejnou posloupnost. Kód lze spustit online a bez instalace třeba bez na programiz.com.
import random import math random.seed(10) # Vždy vypíše [57, 42, 57, 20, 81, 82, 65, 16, 52] print([math.floor(random.random()*100) for x in range(1,10)])
Jak si seed nastavit?
- Pro Python je ukázka výše. V případě, že se funkce
random.seed()
zavolá bez parametru, je seed opět nastaven implicitně, tedy aktuálním časem systému. - Pro PHP je to podobné jako u Pythonu. Zde se akorát volá funkce
srand()
, případněmt_srand()
. A opět při zavolání bez parametru je seed nastaven implicitně. - JavaScript tuto možnost vůbec nemá a je tedy nutné použít nějakou knihovnu. Ve výše zmíněném projektu Regex patterns to sentences jsem použil knihovnu seedrandom. Názorná ukázka je v souboru ContextRandomNumber.ts.
- V Go je možností trochu více. Lze použít
rand.Seed()
z balíčkumath/rand
. Pokud jsou ale náhodná čísla použita pro zabezpečení, je lepší použít balíčekcrypto/rand
. Tyto náhodná čísla budou kryptograficky mnohem bezpečnější.
package main import ( crand "crypto/rand" "fmt" "math/big" mrand "math/rand" "time" ) func main() { mrand.Seed(time.Now().UTC().UnixNano()) fmt.Println(mrand.Int31n(50)) // crypto/rand.Int vrací kromě čísla ještě error fmt.Println(crand.Int(crand.Reader, big.NewInt(50))) }
Zkušenosti s jazyky a náhodnými čísly můžete sdílet v komentářích
K tomuto článku již není možné přidávat další komentáře