Ich habe nur untersucht, wie ich das gleiche Problem lösen kann, aber ich möchte auch, dass meine Funktion ein Token erstellt, das auch zum Abrufen von Passwörtern verwendet werden kann. Dies bedeutet, dass ich die Fähigkeit des zu erratenden Tokens einschränken muss. Da uniqid
basierend auf der Zeit und laut php.net "der Rückgabewert sich kaum von microtime () unterscheidet", uniqid
erfüllt er die Kriterien nicht. PHP empfiehlt, openssl_random_pseudo_bytes()
stattdessen kryptografisch sichere Token zu generieren.
Eine schnelle, kurze und präzise Antwort lautet:
bin2hex(openssl_random_pseudo_bytes($bytes))
Dadurch wird eine zufällige Zeichenfolge mit alphanumerischen Zeichen der Länge = $ bytes * 2 generiert. Leider hat dies nur ein Alphabet von [a-f][0-9]
, aber es funktioniert.
Unten ist die stärkste Funktion, die ich machen könnte, die die Kriterien erfüllt (Dies ist eine implementierte Version von Eriks Antwort).
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)
funktioniert als Ersatz für rand()
oder mt_rand
. Es verwendet openssl_random_pseudo_bytes, um eine Zufallszahl zwischen $ min und $ max zu erstellen.
getToken($length)
Erstellt ein Alphabet zur Verwendung innerhalb des Tokens und erstellt dann eine Zeichenfolge mit der Länge $length
.
EDIT: Ich habe es versäumt, die Quelle zu zitieren - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
EDIT (PHP7): Mit der Veröffentlichung von PHP7 verfügt die Standardbibliothek nun über zwei neue Funktionen, die die oben genannte Funktion crypto_rand_secure ersetzen / verbessern / vereinfachen können. random_bytes($length)
undrandom_int($min, $max)
http://php.net/manual/en/function.random-bytes.php
http://php.net/manual/en/function.random-int.php
Beispiel:
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;
}