演算法思路
- 長網址 MD5 產生 32 位簽名串,分 4 段,每段 8 字節
- 對四段循環處理:取 8 字節視為 16 進制串與
0x3fffffff (30 位 1) 做 AND 運算,忽略超過 30 位
- 30 位分 6 段,每 5 位作為字母表索引取得特定字元,依序得 6 位字串
- 總 MD5 可得 4 個 6 位串,任取一個作為短網址
PHP 代碼實作
function shorturl($url='', $prefix='', $suffix='') {
$base32 = array(
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5'
);
$hex = md5($prefix.$url.$suffix);
$hexLen = strlen($hex);
$subHexLen = $hexLen / 8;
$output = array();
for ($i = 0; $i < $subHexLen; $i++) {
$subHex = substr($hex, $i * 8, 8);
$int = 0x3FFFFFFF & (1 * ('0x'.$subHex));
$out = '';
for ($j = 0; $j < 6; $j++) {
$val = 0x0000001F & $int;
$out .= $base32[$val];
$int = $int >> 5;
}
$output[] = $out;
}
return $output;
}
$urls = shorturl('https://www.bianceng.cn');
var_dump($urls);