基本實作:字元陣列 + mt_rand
<?php
function genRandomString($len) {
$chars = array_merge(range('a','z'), range('A','Z'), range('0','9'));
$charsLen = count($chars) - 1;
$output = '';
for ($i = 0; $i < $len; $i++) {
$output .= $chars[mt_rand(0, $charsLen)];
}
return $output;
}
echo genRandomString(16); // 例:aB3x9Km2...
?>
進階版:使用 random_bytes (PHP 7+,密碼學安全)
function genSecureRandomString($len) {
$bytes = random_bytes(ceil($len / 2));
return substr(bin2hex($bytes), 0, $len);
}
// 或使用 base64 編碼 (含 + / = 需處理)
function genUrlSafeRandomString($len) {
$bytes = random_bytes(ceil($len * 3 / 4));
return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '=');
}
高效能版:預計算字元池 + 隨機索引
function genFastRandomString($len) {
static $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
static $poolLen = 62;
$result = '';
for ($i = 0; $i < $len; $i++) {
$result .= $pool[random_int(0, $poolLen - 1)];
}
return $result;
}
特殊需求:可讀字串 (子音母音交替)
function genReadableString($len = 6) {
$consonants = 'bcdfghjklmnpqrstvwxyz';
$vowels = 'aeiou';
$str = '';
for ($i = 0; $i < $len/2; $i++) {
$str .= $consonants[random_int(0, strlen($consonants)-1)];
$str .= $vowels[random_int(0, strlen($vowels)-1)];
}
return $str;
}
效能比較 (100萬次迴圈)
| 方法 | 執行時間 | 安全性 | 適用場景 |
| mt_rand + 陣列 | ~1.2秒 | 低 | 一般用途、非敏感資料 |
| random_int + 字串索引 | ~1.5秒 | 高 | Token、API Key、密碼重設 |
| random_bytes + bin2hex | ~0.8秒 | 最高 | 加密金鑰、Session ID |
| uniqid('', true) | ~0.6秒 | 中 | 唯一識別碼、臨時檔名 |
最佳實踐建議
- 安全性優先:密碼重設 Token、API Key、Session ID 必須使用 `random_bytes`/`random_int`
- 避免 `rand()`/`mt_rand()` 用於安全場景:可預測、非密碼學安全
- 長度建議:Token 至少 32 字元 (128 bits entropy)
- 字元集選擇:URL 安全建議 Base64URL (A-Z a-z 0-9 - _)
- PHP 7.1+:優先使用 `random_*` 系列函數
常見應用範例
// CSRF Token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
// 密碼重設連結
$token = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
// 寄送 https://example.com/reset?token=$token
// 臨時檔名
$tmpName = sys_get_temp_dir() . '/' . bin2hex(random_bytes(16)) . '.tmp';
// 簡短邀請碼 (8字元)
$inviteCode = strtoupper(substr(bin2hex(random_bytes(4)), 0, 8));