使用者註冊初始密碼、重設密碼 Token、API Key、驗證碼、訂單號等皆需固定長度、高熵值、可自訂字元集的隨機字串。
直接在可列印字元範圍(33~126)隨機取整數,轉字元。
優點:程式碼極短、無需預定字元陣列、記憶體佔用極低。
缺點:含特殊符號可能不符合某些系統密碼規則、分布不完全均勻(mt_rand 偏差極小)。
定義允許字元字串,隨機索引取字元。
?';
$maxIndex = strlen($charset) - 1;
$pwd = '';
for ($i = 0; $i < $length; $i++) {
$pwd .= $charset[mt_rand(0, $maxIndex)];
}
return $pwd;
}
// 使用範例
echo generatePasswordV2(12); // 預設字元集
echo generatePasswordV2(6, '0123456789'); // 純數字驗證碼
echo generatePasswordV2(32, '0123456789abcdef'); // 16 進位 Token
?>
優點:完全可控字元集、分布均勻、效能極佳、業界最常用。
缺點:需手動維護字元集字串。
致命缺點:array_rand() 不重複抽樣,導致字元不可重複,嚴重降低熵值(8 字元最多 8 種字元),不適合密碼/Token 生成。效能也較差。
| 方法 | 耗時 (秒) | 相對效能 | 記憶體 |
|---|---|---|---|
| V1: chr(mt_rand) | 0.42 | 1.00x | 極低 |
| V2: 字元池索引 | 0.38 | 1.11x ⭐ | 極低 |
| V3: array_rand | 1.85 | 0.23x | 較高 |
結論:V2 最快且最靈活,V1 略慢(chr 函數呼叫開銷),V3 又慢又不安全。
mt_rand() 非加密安全,可預測。安全敏感場景(密碼、Token、API Key)必須使用 CSPRNG:
| 場景 | 推薦函數 | 字元集建議 |
|---|---|---|
| 一般密碼、驗證碼 | generatePasswordV2() | 字母+數字+常用符號 |
| 重設密碼 Token、API Key、Session ID | secureRandomString() / secureToken() | Base64url 或 16 進位 |
| 純數字驗證碼 (SMS/Email) | generatePasswordV2(6, '0123456789') | 0-9 |
| UUID v4 | ramsey/uuid 套件 | 標準格式 |
隨機字串生成看似簡單,字元集控制、熵值保證、加密安全性三大面向缺一不可。日常業務用 V2 字元池索引法;安全敏感場景必須升級 CSPRNG (random_bytes)。棄用 array_rand、uniqid、md5(time()) 等不安全寫法。