ฉันเพิ่งดูวิธีแก้ปัญหาเดียวกันนี้ แต่ฉันต้องการให้ฟังก์ชันสร้างโทเค็นที่สามารถใช้สำหรับการดึงรหัสผ่านได้เช่นกัน ซึ่งหมายความว่าฉันต้องจำกัดความสามารถของโทเค็นที่จะเดาได้ เนื่องจากuniqid
ขึ้นอยู่กับเวลาและตาม php.net "ค่าส่งคืนแตกต่างจาก microtime ()" เล็กน้อยuniqid
ไม่ตรงตามเกณฑ์ PHP แนะนำให้ใช้openssl_random_pseudo_bytes()
แทนเพื่อสร้างโทเค็นที่ปลอดภัยด้วยการเข้ารหัส
คำตอบสั้น ๆ และตรงประเด็นคือ:
bin2hex(openssl_random_pseudo_bytes($bytes))
ซึ่งจะสร้างสตริงสุ่มของตัวอักษรและตัวเลขความยาว = $ ไบต์ * 2 น่าเสียดายที่นี่มีเพียงตัวอักษร [a-f][0-9]
แต่ใช้งานได้
ด้านล่างเป็นฟังก์ชันที่แข็งแกร่งที่สุดที่ฉันสามารถทำได้เพื่อให้เป็นไปตามเกณฑ์ (นี่คือคำตอบของ 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)
ทำงานเป็นลดลงในการเปลี่ยนเป็นหรือrand()
mt_rand
มันใช้ openssl_random_pseudo_bytes เพื่อช่วยสร้างตัวเลขสุ่มระหว่าง $ min และ $ max
getToken($length)
$length
สร้างตัวอักษรที่จะใช้งานภายในโทเค็นและจากนั้นสร้างสตริงของความยาว
แก้ไข:ฉันไม่สนใจแหล่งอ้างอิง - http://us1.php.net/manual/th/function.openssl-random-pseudo-bytes.php#104322
แก้ไข (PHP7):ด้วยการเปิดตัว PHP7 ทำให้ไลบรารีมาตรฐานมีสองฟังก์ชันใหม่ที่สามารถแทนที่ / ปรับปรุง / ลดความซับซ้อนของฟังก์ชั่น crypto_rand_secure ด้านบน random_bytes($length)
และrandom_int($min, $max)
http://php.net/manual/en/function.random-bytes.php
http://php.net/manual/en/function.random-int.php
ตัวอย่าง:
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;
}