2010-09-11 20 views
5

Ho bisogno di un grande generatore di numeri casuali (come, ad esempio, 128-bit) in PHP. Stavo pensando di memorizzare questo numero in una stringa come esadecimale.Generazione di numeri casuali di grandi dimensioni

Si noti che questo è pensato per un sistema di login che menzionato la necessità di un numero "casuale", in modo da sto indovinando io davvero bisogno di essere "random-basta" (perché so pseudo-casuale è mai veramente casuale).

L'algoritmo che stavo pensando stava generando la cifra esadecimale numero uno alla volta, quindi concatenando tutto. Come questo:

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

Posso fidarmi di questa funzione per restituire buoni numeri pseudo-casuali o sto scherzi con qualcosa che in realtà non dovrebbe?

risposta

4

Prova:

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

ho spesso visto questo gestito in sistemi d'accesso da solo facendo qualcosa di simile a:

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

hash MD5 possono avere collisioni, ma questo è abbastanza efficace e molto semplice .

+0

Perché non basta sostituire $ sale di rand()? Non sarebbe ugualmente casuale? Diamine, probabilmente ancora più casuale. – luiscubal

+0

è vero, ma l'utilizzo di rand() negherà la possibilità di confrontare l'hash previsto, se si desidera farlo. PER ESEMPIO.in situazioni di password, spesso si hash la password degli utenti con un salt - quindi poiché presumibilmente sei l'unico a conoscere il sale, puoi confrontare l'hash che hai registrato nel DB per quell'utente con il "previsto" hash ", e puoi verificare che sia corretto. – julio

3

Ho fatto questa domanda diversi anni fa e, da allora, la mia conoscenza di questo argomento è migliorata.

Prima di tutto, ho detto che volevo numeri casuali per un sistema di login. I sistemi di accesso sono meccanismi di sicurezza. Ciò significa che qualsiasi generatore di numeri casuali su cui si basa il sistema di accesso deve essere protetto da crittografia.

PHP rand e mt_rand non sono crittograficamente protetti.

In questi casi, è meglio prevenire che curare. Ci sono generatori di numeri casuali progettati specificamente per essere sicuri, in particolare openssl_random_pseudo_bytes (che sfortunatamente non è sempre disponibile - è necessario abilitare l'estensione OpenSSL perché funzioni). Sui sistemi * NIX (come Linux), i byte letti da /dev/urandomcan be used.

Sfortunatamente (ai fini di questa domanda), entrambi questi approcci restituiscono dati binari anziché esadecimali. Fortunatamente, PHP ha già una funzione per risolvere questo problema per noi, bin2hex, che funziona con stringhe di qualsiasi lunghezza.

Quindi, ecco come il codice sarà simile:

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

Dal PHP 5.3:

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

Per il vostro esempio di 128 bit:

$rand128 = getRandomHex(16); 
Problemi correlati