短網址(Short URL),顧名思義就是在形式上比較短的網址。
短鏈接的好處:
1、內容需要;2、用戶友好;3、便於管理
為什么要這樣做的,原因我想有這樣幾點:
微博限制字數為140字一條,那么如果我們需要發一些連接上去,但是這個連接非常的長,以至於將近要占用我們內容的一半篇幅,這肯定是不能被允許的,所以短網址應運而生了。
短網址可以在我們項目里可以很好的對開放級URL進行管理。有一部分網址可以會涵蓋暴力,廣告等信息,這樣我們可以通過用戶的舉報,完全管理這個連接將不出現在我們的應用中,應為同樣的URL通過加密算法之后,得到的地址是一樣的。
我們可以對一系列的網址進行流量,點擊等統計,挖掘出大多數用戶的關注點,這樣有利於我們對項目的后續工作更好的作出決策。
算法原理
1)將長網址md5生成32位簽名串,分為4段, 每段8個字節;
2)對這四段循環處理, 取8個字節, 將他看成16進制串與0x3fffffff(30位1)與操作, 即超過30位的忽略處理;
3)這30位分成6段, 每5位的數字作為字母表的索引取得特定字符, 依次進行獲得6位字符串;
4)總的md5串可以獲得4個6位串; 取里面的任意一個就可作為這個長url的短url地址;
整理一下進制的轉換
二進制轉換十進制:
10101轉換成十進制如下:
從右邊數分別標注為0,1,2,3,4即:2^0*1 + 2^1*0 + 2^2*1 + 2^3*0 + 2^4*1 = 1 + 0 + 4 + 0 + 16 = 21;
十進制轉換成二進制:
21轉換成二進制如下:
21對2取余分別是10余1, 5余0, 2余1, 1余0即:最后一個余數是1不能再除2 因此:10101
十六進制:
它由0-9,A-F組成,字母不區分大小寫,A-F對應10-15;
一般為了區分十六進制我們習慣在前面加個‘0x’例如十六進制 32和0x32 其實是一樣的
十六進制轉換成十進制:
0x32轉換成十進制如下:
從右邊數分別標注為0,1 即:16^0*2 + 16^1*3 = 2 + 48 = 50;
十進制轉換成十六進制:
50轉換成十六進制如下:
50對16取余是3余2 最后一個余數是3不能再除16 因此:32 習慣變成0x32
位運算:
程序中的所有數在計算機內存中都是以二進制的形式儲存的,位運算說穿了,就是直接對整數在內存中的二進制位進行操作。
舉個例子,6的二進制是110,11的二進制是1011,那么6 and (&)11的結果就是2,它是二進制對應位進行邏輯運算的結果(0表示False,1表示True,空位都當0處理)。
6可以看成是0110 11是1011 位運算得到的就是10 即:2
位運算中還有個 >> 移位(從右邊移位) 例如:6 >> 1 & 11
6可以看成是0110 >> 移1位 變成0011 然后再& 11(1011)就得到11 即:3
備注: x & y 將得到的數是0 ~ x的值
php版的短鏈接生成方法
<?php function shorturl($input) { $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($input); $hexLen = strlen($hex); $subHexLen = $hexLen / 8; $output = array(); for ($i = 0; $i < $subHexLen; $i++) { //把加密字符按照8位一組16進制與0x3FFFFFFF(30位1)進行位與運算 $subHex = substr ($hex, $i * 8, 8); $int = 0x3FFFFFFF & (1 * ('0x'.$subHex)); $out = ''; for ($j = 0; $j < 6; $j++) { //把得到的值與0x0000001F進行位與運算,取得字符數組chars索引 $val = 0x0000001F & $int; $out .= $base32[$val]; $int = $int >> 5; } $output[] = $out; } return $output; } ?>
用戶訪問短網址 時的過程:
1、瀏覽器訪問短網址http://short.cn/Xvdf23,經過DNS解析會指向到http://short.cn的服務器。
2、服務器根據短網址中的ID字段查找數據庫,返回原始網址。
3、重定向到上面返回的原始網址