Stavo solo esaminando come risolvere questo stesso problema, ma voglio anche che la mia funzione crei un token che può essere utilizzato anche per il recupero della password. Ciò significa che devo limitare la capacità del token di essere indovinato. Perché uniqid
si basa sul tempo e secondo php.net "il valore di ritorno è leggermente diverso da microtime ()", uniqid
non soddisfa i criteri. PHP consiglia di utilizzare openssl_random_pseudo_bytes()
invece per generare token crittograficamente sicuri.
Una risposta rapida, breve e precisa è:
bin2hex(openssl_random_pseudo_bytes($bytes))
che genererà una stringa casuale di caratteri alfanumerici di lunghezza = $ byte * 2. Sfortunatamente questo ha solo un alfabeto di [a-f][0-9]
, ma funziona.
Di seguito è la funzione più forte che potrei svolgere che soddisfa i criteri (Questa è una versione implementata della risposta di Erik).
function crypto_rand_secure($min, $max)
{
$range = $max - $min;
if ($range < 1) return $min; // not so random...
$log = ceil(log($range, 2));
$bytes = (int) ($log / 8) + 1; // length in bytes
$bits = (int) $log + 1; // length in bits
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
$rnd = $rnd & $filter; // discard irrelevant bits
} while ($rnd > $range);
return $min + $rnd;
}
function getToken($length)
{
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
$max = strlen($codeAlphabet); // edited
for ($i=0; $i < $length; $i++) {
$token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
}
return $token;
}
crypto_rand_secure($min, $max)
funziona come un calo in sostituzione di rand()
o mt_rand
. Usa openssl_random_pseudo_bytes per aiutare a creare un numero casuale tra $ min e $ max.
getToken($length)
crea un alfabeto da utilizzare all'interno del token e quindi crea una stringa di lunghezza $length
.
EDIT: ho trascurato di citare la fonte - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
EDIT (PHP7): Con il rilascio di PHP7, la libreria standard ora ha due nuove funzioni che possono sostituire / migliorare / semplificare la funzione crypto_rand_secure sopra. random_bytes($length)
erandom_int($min, $max)
http://php.net/manual/en/function.random-bytes.php
http://php.net/manual/en/function.random-int.php
Esempio:
function getToken($length){
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
$max = strlen($codeAlphabet);
for ($i=0; $i < $length; $i++) {
$token .= $codeAlphabet[random_int(0, $max-1)];
}
return $token;
}