相信不少人手機上都收到過一些營銷短信,短信裏面有時候會附帶一些網址,以下圖 git
短網址通常是採用一個很是短域名下,路徑參數通常只有3-6個字符組成,很是簡潔!github
使用短網址的前提是先生成短網址,主要是採用某種算法讓一段短的字符對應一個長的字符,好比說從經常使用的0-九、a-z、A-Z共62個字符中選擇6個字符,那意味着有62的6次方種組合,大概有568億不重複的短網址可用!golang
服務器經過路徑參數查詢到真實的長網址,而後使用301/302跳轉到真實的網址便可!算法
關於跳轉,301 是永久重定向,302 是臨時重定向。短地址一經生成就不會變化,因此用 301 是符合 http 語義的,瀏覽器會記錄跳轉地址,同時對服務器壓力也會有必定減小。可是若是使用了 301,咱們就沒法統計到短地址被點擊的次數了,若是對數據統計有要求的話,使用302跳轉可能比較好一些!數據庫
短網址的主要好處是方便傳輸記憶,特別是在短信裏面使用的時候,短信對內容字數有限制,還有好比說微博分享也使用了短網址!數組
目前市面上有不少免費的短連接服務,功能基本上都同樣,也沒有什麼限制!瀏覽器
(1)百度的短連接(dwz.cn/),百度不只僅提供了網頁入口,也提供了接口和開發文檔,簡單易用!安全
(2)新浪的短連接(sina.lt/),目前僅提供網頁入口,未發現接口服務!bash
(3)淘寶的短連接(tb.am/),目前僅提供網頁入口,未發現接口服務!服務器
市面還有不少其它的小的公司提供短連接服務,有些是部分免費,有些短連接是有效期的,這裏不一一介紹!
網上比較流行的算法有進制算法、摘要(Hash)算法、隨機數算法,下面簡單介紹一下:
這個算法網上也有叫做自增序列算法,特色就是永不重複,設置 id 自增,一個 10進制 id 對應一個62進制的數值,1對1,也就不會出現重複的狀況,這個利用的就是低進制轉化爲高進制時,字符數會減小的特性。
計算機中常見的進制有2進制,8進制,10進制,16進制,進制越大,可以表示的數越大,佔用的字數也越少。下面舉個例:
10進制的1000,在8進制裏面是1750,在16進制裏面就是3E8,那在62進制裏面呢?有人說,計算機裏面沒有62進制。。。雖然沒有,可是咱們能夠造一個,進制的轉換算法是固定的,最多見的就是「除基取餘法」!
咱們假設62進制的字符序列爲 0-9a-zA-Z,順序能夠打亂,可是應該固定下來,是一個從0角標開始的到61的數組,咱們暫且稱之爲字母表!
====> 1000/62 = 16,餘8
====> 16/62 = 0,餘16
餘數獲得的數字是1六、8,而後找到字母表裏面角標爲16和8的字符拼起來,就是g8,很是短,只有2位數!假如說咱們想至少產生6位字符,那麼咱們能夠從一個比較大的數字開始,具體能夠看下圖:
1位 62 0 - 61
2位 3844 62 - 3843
3位 約 23萬 3844 - 238327
4位 約 1400萬 238328 - 14776335
5位 約 9.1億 14776336 - 916132831
6位 約 568億 916132832 - 56800235583
複製代碼
簡單的對長連接進行加鹽md5,會生成一個32位的字符串,隨機從裏面取6個字符,或者簡單粗暴取最後6位,可是md5只包含0-9A-Fa-f,比字母表的裏面字符還少,衝突概率更大!
1.將長網址 md5 生成 32 位簽名串,分爲 4 段, 每段 8 個字節
2.對這四段循環處理, 取 8 個字節, 將他當作 16 進制串與 0x3fffffff(30位1) 與操做, 即超過 30 位的忽略處理
3.這 30 位分紅 6 段, 每 5 位的數字做爲字母表的索引取得特定字符, 依次進行得到 6 位字符串
4.總的 md5 串能夠得到 4 個 6 位串,取裏面的任意一個就可做爲這個長 url 的短 url 地址
生成的方式更加複雜,重複的概率低,可是依然會出現衝突!
這個更簡單,直接對這個62個字符數組作隨機選擇,選擇其中6個字符看成短連接碼,簡單易用,可是不免會出現重複衝突!
第一種算法只要解決自增id問題就能夠避免衝突,自增id能夠採用數據庫自增主鍵,每次生成短碼只需一次數據庫操做(insert操做,獲取主鍵id,而後算出短碼便可)
第二種和第三種算法其實都差很少,都是依賴於程序隨機,容易出現衝突,這就須要每次在插入數據庫的時候判重,效率低一些!
短連接雖然方便了傳輸和記憶,可是因爲連接組成的字符個數少,更容易被爆破、猜想攻擊,攻擊者能夠輕鬆遍歷全部字符組成的連接!
因此不建議使用短連接發送具備私密性的網址,好比說重置密碼連接,對一些權限、敏感信息的連接要作好二次鑑權!
最後,推薦一個使用golang寫的短網址項目,能夠做爲一個單獨服務部署使用: github.com/praglody/sh…