Zufallszahlengenerator – Random.org
Ein in der IT immer wieder auftretendes Problem ist das Erzeugen von Zufallszahlen. Jede Programmiersprache bietet heute einen Zufallszahlengenerator an der zufällige Zahlen in einem bestimmten Bereich und Format ausgibt. Leider sind diese aber nicht tatsächlich zufällig.
Pseudo-Zufallszahlen
Zufallsgeneratoren aller Programmiersprachen liefern so genannte Pseudo-Zufallszahlen. Diese Generatoren kann man üblicherweise mit einem seed Wert initialisieren. Danach kann man sich Zahlen im gewünschten Bereich ausgeben lassen, die eine mathematisch gesehen normale Verteilung haben, also ca. gleich oft ausgegeben werden, wenn man eine sehr große Menge an Zahlen abfragt. Man wird jedoch schnell bemerken, dass bei neuerlichem Aufruf mit dem selben seed Wert wieder die exakt gleichen Zeilen ausgegeben werden. Braucht man echte Zufallszahlen ist dieser Weg nicht interessant. Anders sieht es zum Beispiel bei Simulationen aus, die zwar zufällige Zahlen brauchen, jedoch bei öfteren Berechnen immer wieder das selbe Ergebnis ausgeben sollen.
Lösungsansatz
Ein Lösungsansatz für ungeübte Programmierer oder für Leute die keine optimale Lösung brauchen ist folgendes. Man kann den Zufallszahlengenerator mit einer zufälligen Zahl initialisieren. Üblicherweise nimmt man dafür die Systemzeit. Bei PHP zum Beispiel mit:
srand(time());
Das schaut zwar im ersten Augenblick gut aus, tatsächlich wird aber hier davon ausgegangen, dass die Systemzeit korrekt verwendet wird. Stellt man die Systemzeit zurück, kann man so den Zufallsgenerator manipulieren.
Zufallszahlengenerator – Perfekte Lösung
Die perfekte Lösung ist ein echter Zufallszahlengenerator. Dies ist normalerweise eine Hardware, welche aus dem Rauschen zufällige Zahlen generiert. Rauschen ist das, was man am Fernseher sehen kann, wenn kein Sender eingestellt ist! Random.org verwendet für den Generator eine Messung des atmosphärischen Rauschens, dass als zufällig gilt. Dankenswerter Weise kann man als Programmierer, sofern man nicht selbst so eine Hardware besitzt, von diesem Service seine Zufallszahlen beziehen oder zumindest eine Zufallszahl im den eigenen Zufallszahlengenerator zufällig zu initialisieren. Ein solches Service ist random.org, ich zeige euch wie man davon eine echte zufällige Zahl bezieht. Das geht zum Beispiel so:
function get_true_random_number($min = 1, $max = 1000000) { // Validate parameters $max = ((int) $max >= 1) ? (int) $max : 100; $min = ((int) $min < $max) ? (int) $min : 1; // Curl options $options = array( CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false, CURLOPT_FOLLOWLOCATION => true, CURLOPT_ENCODING => '', CURLOPT_USERAGENT => 'PHP', CURLOPT_AUTOREFERER => true, CURLOPT_CONNECTTIMEOUT => 120, CURLOPT_TIMEOUT => 120, CURLOPT_MAXREDIRS => 10, ); // Curl init & run $ch = curl_init('http://www.random.org/integers/?num=1&min=' . $min . '&max=' . $max . '&col=1&base=10&format=plain&rnd=new'); curl_setopt_array($ch, $options); $content = curl_exec($ch); curl_close($ch); return trim($content); }
Bei eigenen Skripten verwende ich aus Performancegründen diese Abfrage nur einmal um den PHP Zufallszahlengenerator zu initialisieren:
srand(get_true_random_number());
Die PHP-Funktion time() gibt die Anzahl vergangener Sekunden seit dem 01.01.1970 zurück (UNIX-Timestamp) und ist damit bei jedem Aufruf einzigartig – ausser er wird innerhalb einer Sekunde mehrmals aufgerufen, aber dann gibt es ja auch noch `microtime()`.
und wenn man vor dem time() Befehl die Systemuhr setzt, dann liefert es immer die selbe zufällige Zahl. Nicht umsonst ist es sehr gefährlich auf die systemeigenen Pseudo-Zufallszahlen zu vertrauen. Meistens ist das egal, nicht aber bei Verschlüsselung und anderer sicherheitskritischer Software.