Necesito generar miles (posiblemente millones) de códigos únicos para un cliente. Estos códigos pueden tener un valor monetario, por lo que es vital que sean VERDADERAMENTE aleatorios, y que un hacker inteligente no pueda detectar ni explotar ningún patrón.
He analizado varias soluciones para generar el código (generado cíclicamente = podría suponerse, demasiado arriesgado, uniqid()
= bueno, pero es posible que necesite un código de diferente longitud).
Ahora mismo estoy pensando en generar el código usando AZ y 0-9 MINUS VOWELS (para garantizar que no se generen accidentalmente palabras groseras) aunque esto puede aumentar en el futuro a caracteres en minúsculas, etc.
Hasta ahora tengo esto (usando una función rand personalizada tomada de aquí ):
function generateCode($length = 12) {
$chars = 'BCDFGHJKLMNPQRSTVWXYZ0123456789';
$count = mb_strlen($chars);
for ($i = 0, $result = ''; $i < $length; $i++) {
$randomIndex = devurandom_rand(0, $count - 1);
$result .= mb_substr($chars, $randomIndex, 1);
}
return $result;
}
// CUSTOM RAND FUNCTION
// equiv to rand, mt_rand
// returns int in *closed* interval [$min,$max]
function devurandom_rand($min = 0, $max = 0x7FFFFFFF) {
$diff = $max - $min;
if ($diff < 0 || $diff > 0x7FFFFFFF) {
throw new RuntimeException("Bad range");
}
$bytes = mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
if ($bytes === false || strlen($bytes) != 4) {
throw new RuntimeException("Unable to get 4 bytes");
}
$ary = unpack("Nint", $bytes);
$val = $ary['int'] & 0x7FFFFFFF; // 32-bit safe
$fp = (float) $val / 2147483647.0; // convert to [0,1]
return round($fp * $diff) + $min;
}
Es bastante básico, así que obviamente me preocupa que no sea lo suficientemente aleatorio. ¿Alguien puede decirme si esta es una forma decente de garantizar que el código generado sea verdaderamente aleatorio?
(Nota: Obviamente, un pirata informático aspirante siempre podrá intentar un ataque de fuerza bruta. Estos intentos se manejarán en otro lugar, solo quiero asegurarme de que este código sea verdaderamente aleatorio).