2010-09-11 11 views
5

Ich brauche einen großen (wie sagen, 128-Bit-großen) Zufallszahlengenerator in PHP. Ich dachte daran, diese Zahl in einer Zeichenfolge als Hexadezimal zu speichern.Große Zufallsgeneration

Beachten Sie, dass dies für ein Login-System zu verstehen ist, dass die Notwendigkeit für eine „zufällige“ Nummer erwähnt, so vermute ich, ich wirklich brauche es „random-genug“ zu sein (weil ich weiß, pseudo-zufällig ist nie wirklich zufällig).

Der Algorithmus, den ich dachte, war die Nummer eins hexadezimal zu einer Zeit zu generieren, dann verkettete alles. Wie folgt aus:

$random = ''; 
for ($i = 0; $i < 32; ++$i) { 
    $digit = rand(0, 15); 
    $random .= ($digit < 10 ? $digit : ($digit - 10 + 'a')); 
} 
return $random; 

Kann ich vertraue dieser Funktion gut Pseudozufallszahl zurückzukehren, oder bin ich durcheinander mit etwas wirklich soll ich nicht?

Antwort

4

Versuche:

for ($str = '', $i = 0; $i < $len; $i++) { 
    $str .= dechex(mt_rand(0, 15)); 
} 
1

ich oft habe dies wie etwas zu tun, in Login-Systemen behandelt gesehen:

$salt = "big string of random stuff"; // you can generate this once like above 
$token = md5($salt . time()); // this will be your "unique" number 

MD5 Hashes Kollisionen haben kann, aber das ist sehr effektiv und sehr einfach .

+0

Warum nicht einfach ersetzen $ Salz von rand()? Wäre es nicht gleichermaßen zufällig? Verdammt, wahrscheinlich noch mehr zufällig. – luiscubal

+0

das stimmt, aber die Verwendung von rand() negiert Ihre Fähigkeit, den erwarteten Hash zu vergleichen, wenn Sie das tun wollen. Z.B.In Passwort-Situationen hasst du oft das Passwort des Users mit einem Salz - dann, da du vermutlich der einzige bist, der das Salz kennt, kannst du den Hash, den du in der Datenbank für diesen Benutzer notiert hast, mit dem "erwartet" vergleichen Hash ", und Sie können überprüfen, ob es korrekt ist. – julio

3

Ich habe diese Frage vor einigen Jahren gestellt und seitdem hat sich mein Wissen zu diesem Thema verbessert.

Zunächst erwähnte ich, ich wollte Zufallszahlen für ein Login-System. Anmeldesysteme sind Sicherheitsmechanismen. Das bedeutet, dass alle Zufallszahlengeneratoren, auf die sich das Anmeldesystem stützt, kryptographisch sicher sein müssen.

PHP rand und mt_rand sind nicht kryptographisch sicher.

In diesen Fällen ist Vorsicht geboten. Es gibt Zufallszahlengeneratoren, die speziell für die Sicherheit entwickelt wurden, insbesondere openssl_random_pseudo_bytes (die leider nicht immer verfügbar sind - Sie müssen die OpenSSL-Erweiterung aktivieren, damit sie funktioniert). Auf * NIX-Systemen (z. B. Linux) werden auch Bytes aus /dev/urandomcan be used gelesen.

Leider (für die Zwecke dieser Frage) geben beide Ansätze binäre Daten anstelle von hexadezimal zurück. Glücklicherweise hat PHP bereits eine Funktion, die das für uns repariert, bin2hex, die für Strings beliebiger Länge funktioniert.

Also hier ist, wie der Code aussehen würde:

function generate_secure_random_hex_string($length) { 
    // $length should be an even, non-negative number. 

    // Because each byte is represented as two hex digits, we'll need the binary 
    // string to be half as long as the hex string. 
    $binary_length = $length/2; 

    // First, we'll generate the random binary string. 
    $random_result = openssl_random_pseudo_bytes($binary_length, $cstrong); 

    if (!$cstrong) { 
     // The result is not cryptographically secure. Abort. 
     // die() is just a placeholder. 
     // There might be better ways to handle this error. 
     die(); 
    } 

    //Convert the result to hexadecimal 
    return bin2hex($random_result); 
} 

// Example: 
echo generate_secure_random_hex_string(32); 
0

Ab PHP 5.3:

function getRandomHex($num_bytes=4) { 
    return bin2hex(openssl_random_pseudo_bytes($num_bytes)); 
} 

Für Ihr Beispiel von 128 Bits:

$rand128 = getRandomHex(16);