Náhodná čísla
Pokud v aplikaci potřebujeme používat náhodná čísla, nejspíš použijeme nějaký generátor pseudonáhodných čísel, protože k lepším zdrojům náhody nebudeme mít přístup. Tyto generátory mohou vykazovat poměrně dobré vlastnosti, problémem je, jak je inicializovat. Dříve to bylo potřeba dělat ručně funkcí srand, resp. mt_srand, od PHP 4.2.0 se o to postará PHP za nás (pokud inicializaci neprovedeme ručně). Výchozí inicializace používá aktuální čas, ID procesu a hodnotu z lineárního kongruenčního generátoru, který pro svou inicializaci také používá aktuální čas a ID aktuálního procesu nebo vlákna. Z toho plyne, že pokud by se posloupnost náhodných čísel pokusil někdo uhádnout, tak má při znalosti času požadavku docela slušnou šanci.
Pokud to je pro nás nepřijatelné, můžeme do inicializace generátoru pseudonáhodných čísel přidat vlastní konstantu, která uhodnutí podstatně ztíží. Na Unixu lze pro inicializaci nebo pro vlastní získávání náhodných čísel také použít speciální soubor /dev/random
, který při čtení vrací náhodná data:
<?php /** Načtení náhodných dat ze souboru * @param int minimální hodnota, výchozí je 0 * @param int maximální hodnota, výchozí je getrandmax() * @param string název souboru s náhodnými daty, výchozí je /dev/random * @return int náhodné číslo z rozsahu $min - $max (včetně) */ function random($min = 0, $max = null, $filename = "/dev/random") { if (!isset($max)) { $max = getrandmax(); } $return = 0; $range = 1; $fp = fopen($filename, "rb"); while ($range < $max - $min + 1) { $return = 256*$return + ord(fgetc($fp)); $range *= 256; } fclose($fp); return $min + floor($return / $range * ($max - $min + 1)); } ?>
Při zapnuté extenzi OpenSSL se dá od PHP 5.3.0 použít také funkce openssl_random_pseudo_bytes.
Diskuse
Satai:
Pokud se nepletu, tak urandom neni specifikovan a je to rozsireni Linuxu a snad i Solarisu.
llook:
Spíš asi cat /dev/urandom > /dev/dsp, ne?

tark:
Nestačilo by tohle?<?php
$random = (rand() * rand() / rand() + rand()) . rand();
?>
Jakub Vrána
:
Z hlediska náhodnosti je to pořád totéž. Jakmile se mi podaří uhodnout, z jakého místa v posloupnosti pseudonáhodných čísel jsem je začal brát, tak už je jedno, co s nimi provádím a kolikrát.


Jakub Vrána
:
Koho toto téma zaujalo, určitě si rád přečte i pěkný a hutný článek o tom, jak /dev/random a /dev/urandom funguje: http://swordfish.buslab.org/?p=67.


mach:
Nebo v jednom dile (2. nebo 3.) The Art of Computer Programming je cela cast venovana generovani nahodnych cisel.Hds:
OT: aneb jak se ještě dá získat náhodné číslo: http://thedailywtf.com/forums/thread/105411.aspxKarel:
1) Dá se jako seed použít výraz z microtime a nějakého počitadla přístupů, které se zvyšuje s každým požadavkem?2) Lehce top-topic, ale neslyšel někdo o *hardwarovém* generátoru náhodných čísel?
Jakub Vrána
:
1. Seed je lepší vůbec nepoužívat, protože ať už ho vezmu z jakéhokoliv zdroje, vyresetuji stav generátoru náhodných čísel, takže se potom útočníkovi snadněji odhaduje.
2. Hardwarový generátor je v Linuxu mapován právě na /dev/random - viz http://en.wikipedia.org/wiki//dev/random.


v6ak:
Teď si to čtu znovu a vzpomínám si na http://www.phpguru.cz/clanky/nenechte-uhodnout-sid#comment-56 .
Problém má jen ten linaární kongruenční generátor?

Diskuse je zrušena z důvodu spamu.

