用戶註冊、批量導入、測試數據生成等場景常需隨機用戶名/密碼。核心要求:不可預測、字符集可控、長度可配、避免歧義字符。
PHP 7+ 強制推薦 random_int() / random_bytes()(CSPRNG),棄用 mt_rand()、rand()。舊版本可用 paragonie/random_compat polyfill。
<?php
/**
* 生成加密安全的隨機字符串
* @param int $length 長度
* @param string $charset 字符集(默認排除易混淆字符)
* @return string
*/
function generateRandomString(int $length, string $charset = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%^&*'): string {
$bytes = random_bytes($length);
$max = strlen($charset) - 1;
$result = '';
for ($i = 0; $i < $length; $i++) {
$result .= $charset[$bytes[$i] % ($max + 1)];
}
return $result;
}
/** 生成用戶名:前綴 + 隨機字母數字 */
function generateUsername(int $len = 8, string $prefix = 'user_'): string {
return $prefix . generateRandomString($len, 'abcdefghijkmnpqrstuvwxyz23456789');
}
/** 生成強密碼:含大小寫、數字、特殊符號 */
function generatePassword(int $len = 16): string {
// 確保至少包含四類字符
$lower = 'abcdefghijkmnpqrstuvwxyz';
$upper = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
$digit = '23456789';
$special = '!@#$%^&*';
$all = $lower . $upper . $digit . $special;
$pwd = '';
$pwd .= $lower[random_int(0, strlen($lower)-1)];
$pwd .= $upper[random_int(0, strlen($upper)-1)];
$pwd .= $digit[random_int(0, strlen($digit)-1)];
$pwd .= $special[random_int(0, strlen($special)-1)];
for ($i = 4; $i < $len; $i++) {
$pwd .= $all[random_int(0, strlen($all)-1)];
}
// 打亂順序
return str_shuffle($pwd);
}
// 使用示例
echo "用戶名: " . generateUsername() . PHP_EOL; // user_7k9m2p4q
echo "密碼: " . generatePassword() . PHP_EOL; // K9#mP2@vL5!qR8$w
| 錯誤做法 | 風險 | 正確做法 |
|---|---|---|
mt_rand() / rand() | 可預測、非加密安全 | random_int() / random_bytes() |
chr(mt_rand(33,126)) | 包含空格、刪除符等不可見/危險字符 | 顯式定義安全字符集 |
time() / uniqid() 作種子 | 極易暴力破解 | CSPRNG 無需種子 |
| 固定長度 < 12 | 離線破解風險高 | 密碼 ≥ 16 位,用戶名 ≥ 8 位 |
zxcvbn-php 評估熵值)。使用 random_bytes() + 顯式字符集 + 強制四類字符覆蓋,可生成兼具安全性與可用性的隨機憑證。將上述函數封裝為 Composer 包(如 myapp/security-utils),專案間複用更優雅。