算法原理
- 對長 URL 計算 MD5 雜湊 (128bit, 32十六進制字符)。
- 將 32 字符分為 4 段,每段 8 字符 (32bit)。
- 每段轉為無符號整數,掩碼
0x3FFFFFFF 取低 30 位。
- 循環 6 次,每次取低 5 位 (
& 0x1F) 作為索引,查 Base32 字符表,右移 5 位。
- 得到 4 個 6 字符的候選短碼,可按需選用,衝突時備用。
PHP 完整實現
> 5; // 右移 5 位
}
$output[] = $out;
}
return $output; // 返回 4 個候選碼
}
// 測試
$urls = [
'https://www.snippetit.com/1',
'https://www.snippetit.com/2'
];
foreach ($urls as $url) {
$codes = shorturl($url);
echo "Input : $url\n";
foreach ($codes as $idx => $code) {
echo ($idx === 0 ? "Output : " : " ") . "$code\n";
}
echo "\n";
}
?>
運行輸出示例
Input : https://www.snippetit.com/1
Output : h0xg4r
bdr3tw
osk2d3
4azfqa
Input : https://www.snippetit.com/2
Output : tm5kxb
ceoj2s
yw3dvl
nrmrxl
碰撞概率與應對
- 碼空間:
32^6 = 1,073,741,824 (約 10 億)。
- 碰撞機率 ≈
n / 10^9 (n 為已存記錄數)。百萬級數據碰撞率 ~0.1%。
- 策略:資料庫唯一索引檢測衝突 → 依次嘗試備用碼 → 仍衝突則重新生成 (如加鹽重新 MD5)。
增強安全性/不可預測性
- 打亂字符表:自定義
$base32 順序。
- 加入私鑰:
md5('secret_prefix' . $input . 'secret_suffix')。
- XOR 擾動:
$val ^ 18 等固定值異或。
適用場景
- 短鏈接服務、邀請碼、分享碼、臨時文件下載鏈接。
- 純算法無狀態,易於分布式部署,無需協調 ID 分配器。