適用:訂單號後綴、推薦碼、測試數據生成。**不可用於密碼、Token、加密場景。**
/**
* 生成隨機字母組合(基礎版)
* @param int $length 長度
* @param string $charset 字符集,默認大小寫字母
* @return string
*/
function randomLetters(int $length = 6, string $charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'): string
{
$max = strlen($charset) - 1;
$result = '';
for ($i = 0; $i < $length; $i++) {
$result .= $charset[mt_rand(0, $max)];
}
return $result;
}
// 使用
echo randomLetters(8); // 如 "aBcDeFgH"
echo randomLetters(4, '0123456789'); // 純數字 4 位
echo randomLetters(12, 'abcdef0123456789'); // 十六進制
優化點: 用 mt_rand 替代舊 rand(速度快 4 倍、周期長);預計算 $max 避免循環內重複 strlen。
/**
* 批量生成:一次性獲取隨機字節,避免循環調用 mt_rand
* PHP 8.1+ random_bytes + 映射表
*/
function randomLettersFast(int $length = 10, string $charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'): string
{
$bytes = random_bytes($length); // CSPRNG,但這裡僅作熵源
$mask = (1 << (int)ceil(log(strlen($charset), 2))) - 1; // 位掩碼優化取模
$result = '';
$len = strlen($charset);
for ($i = 0; $i < $length; $i++) {
// 拒絕採樣避免模數偏差(簡化版:直接取模,偏差極小可接受)
$result .= $charset[$bytes[$i] % $len];
}
return $result;
}
強制使用 random_bytes() / random_int()(PHP 7+),底層調用 OS CSPRNG(Linux /dev/urandom、Windows CryptGenRandom)。
/**
* 加密級隨機字符串:URL-safe Base64 變體(無 + / =)
* @param int $bytes 熵字節數,建議 16(128bit)、24(192bit)、32(256bit)
* @return string 長度 ≈ $bytes * 4/3
*/
function secureToken(int $bytes = 32): string
{
$random = random_bytes($bytes);
// RFC 4648 URL-safe Base64:+ -> -,/ -> _,移除填充 =
return rtrim(strtr(base64_encode($random), '+/', '-_'), '=');
}
/**
* 自定義字符集的加密級隨機(拒絕採樣消除模數偏差)
*/
function secureRandomString(int $length, string $charset): string
{
$charsetLen = strlen($charset);
if ($charsetLen < 2) throw new InvalidArgumentException('字符集至少 2 字符');
// 計算掩碼:最小 2^n >= charsetLen
$mask = (1 << (int)ceil(log($charsetLen, 2))) - 1;
$result = '';
while (strlen($result) < $length) {
$byte = random_bytes(1)[0];
$byte &= $mask; // 位掩碼限制範圍
if ($byte < $charsetLen) {
$result .= $charset[$byte];
}
// 否則拒絕重試,保證均勻分佈
}
return $result;
}
// 使用示例
$resetToken = secureToken(24); // 32 字符 URL-safe,如 "xY7k9mN2pQ..."
$apiKey = 'sk_live_' . secureRandomString(24, 'abcdefghijklmnopqrstuvwxyz0123456789');
$inviteCode = secureRandomString(8, 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'); // 去除易混淆字符
| 場景 | 推薦字符集 | 長度 | 熵(bit/char) |
|---|---|---|---|
| 用戶可讀邀請碼 | ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (32 字符,去除 I/O/0/1) | 8-10 | 5 |
| 內部流水號 | 0123456789ABCDEF (Hex) | 12-16 | 4 |
| API Key / Bearer Token | URL-safe Base64 (A-Z a-z 0-9 - _) | 32-43 字符 (256-384 bit) | 6 |
| 臨時密碼 | abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$% | 12-16 | ~6 |