2010-09-11 11 views
5

Necesito un gran generador de números aleatorios grande (por ejemplo, de 128 bits) en PHP. Estaba pensando en almacenar este número en una cadena como hexadecimal.Gran generación de números aleatorios

Tenga en cuenta que esto está destinado para un sistema de inicio de sesión que se menciona la necesidad de un número "aleatorio", así que supongo que realmente necesito que sea "lo suficientemente aleatorio" (porque sé pseudo-aleatorio es nunca verdaderamente al azar).

El algoritmo que estaba pensando generaba el dígito hexadecimal número uno a la vez, luego lo concatenaba todo. De esta manera:

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

¿Puedo confiar en esta función para devolver buenos números pseudo-aleatorios o estoy jugando con algo que realmente no debería?

Respuesta

4

Probar:

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

He visto a menudo esta manejado en los sistemas de acceso con sólo hacer algo como:

$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 puede tener colisiones, pero esto es muy eficaz y muy sencillo .

+0

Por qué no basta con sustituir $ sal por rand()? ¿No sería igualmente aleatorio? Diablos, probablemente aún más al azar. – luiscubal

+0

eso es cierto, pero usar rand() anulará tu capacidad para comparar el hash esperado, si quieres hacerlo. P.EJ.en situaciones de contraseñas, a menudo se picará la contraseña de los usuarios con una sal-- entonces, dado que presumiblemente eres el único que conoce la sal, puedes comparar el hash que has grabado en la base de datos para ese usuario con el "esperado hash ", y puede verificar que sea correcto. – julio

3

Hice esta pregunta hace varios años y, desde entonces, mi conocimiento sobre este tema ha mejorado.

Antes que nada, mencioné que quería números aleatorios para un sistema de inicio de sesión. Los sistemas de inicio de sesión son mecanismos de seguridad. Esto significa que cualquier generador de números aleatorios en el que se base el sistema de inicio de sesión debe ser criptográficamente seguro.

PHP rand y mt_rand no son seguros criptográficamente.

En estos casos, es mejor prevenir que lamentar. Hay generadores de números aleatorios diseñados específicamente para ser seguros, especialmente openssl_random_pseudo_bytes (que desafortunadamente no siempre está disponible; debe habilitar la extensión OpenSSL para que funcione). En sistemas * NIX (como Linux), los bytes se leen de /dev/urandomcan be used también.

Desafortunadamente (para los fines de esta pregunta), ambos enfoques devuelven datos binarios en lugar de hexadecimales. Afortunadamente, PHP ya tiene una función para arreglar esto para nosotros, bin2hex, que funciona para cadenas de cualquier longitud.

Así que aquí es como el código se vería así:

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

A partir de PHP 5.3:

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

Para su ejemplo de 128 bits:

$rand128 = getRandomHex(16); 
Cuestiones relacionadas