短網址(Short URL),顧名思義就是在形式上比較短的網址。一般用的是asp或者php轉向,在Web 2.0的今天,不得不說,這是一個潮流。目前已經有許多相似服務,藉助短網址您能夠用簡短的網址替代原來冗長的網址,讓使用者能夠更容易的分享連接。 例如:http://t.cn/SzjPjAphp
短網址服務,可能不少朋友都已經再也不陌生,如今大部分微博、手機郵件提醒等地方已經有不少應用模式了,並佔據了必定的市場。估計不少朋友如今也正在使用。 看過新浪的短鏈接服務,發現後面主要有6個字符串組成,因而第一個想到的就是原來公司寫的一個遊戲激活碼規則,也就是下面的算法2, 26個大寫字母 26小寫字母,10個數字,隨機生成6個而後插入數據庫對應一個id,短鏈接跳轉的時候,根據字符串查詢到對應id,便可實現相應的跳轉!不過2的62次方,不知道有沒有重複的,小几率能夠,可是對應不是很大的網站應該足夠了 自從twitter推出短網址(shorturl),繼之國內各大微博跟風,google公開goo.gl使用API,短網址之風愈演愈烈.不得不說這是一個新興又一大熱門web2.0服務.現整理一下,包括完整短網址網站,短網址生成原理,算法舉例,以及優劣比較,同時還介紹幾個phper我的實現的。java
短連接的好處:git
一、內容須要;二、用戶友好;三、便於管理。web
爲何要這樣作的,緣由我想有這樣幾點: 微博限制字數爲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地址; 這種算法,雖然會生成4個,可是仍然存在重複概率,下面的算法一和三,就是這種的實現. 算法二 a-zA-Z0-9 這64位取6位組合,可產生500多億個組合數量.把數字和字符組合作必定的映射,就能夠產生惟一的字符串,如第62個組合就是aaaaa9,第63個組合就是aaaaba,再利用洗牌算法,把原字符串打亂後保存,那麼對應位置的組合字符串就會是無序的組合。 把長網址存入數據庫,取返回的id,找出對應的字符串,例如返回ID爲1,那麼對應上面的字符串組合就是bbb,同理 ID爲2時,字符串組合爲bba,依次類推,直至到達64種組合後纔會出現重複的可能,因此若是用上面的62個字符,任意取6個字符組合成字符串的話,你的數據存量達到500多億後纔會出現重複的可能。 具體參看這裏完全完善新浪微博接口和超短URL算法,算法四能夠算做是此算法的一種實現,此算法通常不會重複,可是若是是統計的話,就有很大問題,特別是對域名相關的統計,就抓瞎了。數據庫
java語言實現: Java代碼 package com.test;app
import java.security.MessageDigest;dom
public class ShortURL { private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};網站
public static String byteArrayToHexString(byte[] b){ StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++){ resultSb.append(byteToHexString(b[i])); } return resultSb.toString(); } private static String byteToHexString(byte b){ int n = b; if (n < 0) n = 256 + n; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } public static String MD5Encode(String origin){ String resultString = null; try { resultString=new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); resultString.trim(); resultString=byteArrayToHexString(md.digest(resultString.getBytes("UTF-8"))); }catch (Exception ex){} return resultString; } public static void main(String[] args) { String url = "http://www.bai.com"; for (String string : ShortText(url)) { print(string); } } public static String[] ShortText(String string){ String key = "XuLiang"; //自定義生成MD5加密字符串前的混合KEY String[] chars = new String[]{ //要使用生成URL的字符 "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", "6","7","8","9","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" }; String hex = MD5Encode(key + string); int hexLen = hex.length(); int subHexLen = hexLen / 8; String[] ShortStr = new String[4]; for (int i = 0; i < subHexLen; i++) { String outChars = ""; int j = i + 1; String subHex = hex.substring(i * 8, j * 8); long idx = Long.valueOf("3FFFFFFF", 16) & Long.valueOf(subHex, 16); for (int k = 0; k < 6; k++) { int index = (int) (Long.valueOf("0000003D", 16) & idx); outChars += chars[index]; idx = idx >> 5; } ShortStr[i] = outChars; } return ShortStr; } public static void print(Object messagr){ System.out.println(messagr); }
如下爲php語言實現: 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++) { $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; } ?>
Php代碼
<?php function random($length, $pool = '') { $random = ''; if (emptyempty($pool)) { $pool = 'abcdefghkmnpqrstuvwxyz'; $pool .= '23456789'; } srand ((double)microtime()*1000000); for($i = 0; $i < $length; $i++) { $random .= substr($pool,(rand()%(strlen ($pool))), 1); } return $random; } ?>
跳轉原理 當咱們生成短連接以後,只須要在表中(數據庫或者NoSql )存儲原始連接與短連接的映射關係便可。當咱們訪問短連接時,只須要從映射關係中找到原始連接,便可跳轉到原始連接。