基礎實現
function generate_rand(int $length = 16): string {
$pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$max = strlen($pool) - 1;
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= $pool[random_int(0, $max)]; // PHP 7+ 安全隨機
}
return $str;
}
// PHP 5 相容寫法
function generate_rand_legacy(int $length = 16): string {
$pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$max = strlen($pool) - 1;
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= $pool[mt_rand(0, $max)];
}
return $str;
}
一行式現代寫法 (PHP 7+)
// 使用 random_bytes + base64 編碼(長度約 4/3 倍)
function generate_token(int $bytes = 24): string {
return rtrim(strtr(base64_encode(random_bytes($bytes)), '+/', '-_'), '=');
}
// 範例:32 字節 -> 43 字符 URL-safe Base64
echo generate_token(32);
UUID v4 (RFC 4122) 標準唯一標識
function uuid_v4(): string {
$data = random_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // version 4
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // variant 10
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
效能與安全對比
| 方法 | 速度 | 安全性 | 長度可控 | 用途 |
random_int 循環 | 中 | 高 (CSPRNG) | 是 | Token、驗證碼、短代碼 |
random_bytes + Base64 | 快 | 高 | 按位元組 | API Key、Session ID、CSRF Token |
| UUID v4 | 中 | 高 | 固定 36 | 分散式 ID、資料庫主鍵 |
uniqid('', true) | 極快 | 低 (可預測) | 23+ | 臨時檔名、非安全標識 |
最佳實踐
- 安全敏感(Token、密碼重設、API Key)必須用
random_bytes / random_int。
- 長度建議 ≥ 128 位熵值(Base64 22 字符、Hex 32 字符、字母數字 22 字符)。
- 資料庫主鍵優先用 自增整數 或 UUID v4(分散式);避免自建隨機字符串主鍵導致索引碎片。
- 去重檢查:生成後查詢資料庫是否存在,極小概率衝突重試。