方法一:random_bytes() + Base62 編碼(推薦,加密級安全)
<?php
function generateRandomString(int $length = 32): string {
$bytes = random_bytes($length);
// Base62: 0-9 a-z A-Z (62字符),去除 + / = 等特殊字符
$base62 = '';
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
foreach (str_split($bytes) as $byte) {
$base62 .= $chars[ord($byte) % 62];
}
return $base62;
}
// 使用
echo generateRandomString(16); // 如: 7k9mP2qR8xY1zL4a
?>
方法二:random_int() 逐字符構建(簡單直觀)
<?php
function randomString(int $length = 16, string $charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'): string {
$max = strlen($charset) - 1;
$result = '';
for ($i = 0; $i < $length; $i++) {
$result .= $charset[random_int(0, $max)];
}
return $result;
}
// 使用
echo randomString(20); // 默認字符集
echo randomString(10, '0123456789'); // 純數字
echo randomString(8, 'abcdefghijklmnopqrstuvwxyz'); // 純小寫字母
?>
方法三:bin2hex(random_bytes())(十六進制,長度固定為 2n)
<?php
function hexToken(int $byteLength = 16): string {
return bin2hex(random_bytes($byteLength));
}
// 輸出 32 字符十六進制字符串
echo hexToken(16); // 如: a3f29c8e7d1b4f6092837465abcdef12
?>
方法四:UUID v4(標準格式,含連字符)
<?php
function uuidV4(): string {
$data = random_bytes(16);
// 設置版本位 (4) 和變體位 (10xx)
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
echo uuidV4(); // 如: 550e8400-e29b-41d4-a716-446655440000
?>
方法五:uniqid() + 隨機增強(非加密安全,僅用於非敏感場景)
<?php
// 微秒級時間戳 + 隨機後綴
echo uniqid('prefix_', true); // 如: prefix_65a3b2c1d4e5f7.12345678
// 注意:可預測,不可用於 Token、密碼重置、Session ID 等安全場景
?>
場景選擇指南
| 場景 | 推薦方法 | 理由 |
| API Token / 密碼重置 / Session ID | 方法一、二、三 | 加密級隨機源,抗暴力破解 |
| 文件名去重 / 臨時標識 | 方法三、四 | 長度固定、無特殊字符、UUID 可追蹤 |
| 數據庫主鍵 (非自增) | 方法四 (UUID) / ULID | 分布式唯一、無協調開銷 |
| 測試數據 / 非安全業務流水號 | 方法五 | 簡單快速、可讀性好 |
安全提醒
- 禁用
rand()、mt_rand()、shuffle()、array_rand() 生成安全字符串,它們基於偽隨機數生成器,可預測。
- PHP 7.0+ 請直接使用
random_bytes() / random_int()(底層調用系統 CSPRNG)。
- PHP 5.x 專案請引入
paragonie/random_compat 兼容庫。
- 生成後請檢查唯一性(如數據庫唯一索引),極小概率碰撞仍需處理。