微博短鏈接生成算法與簡單實現

自從twitter推出短網址(shorturl),國內也有很多互聯網公司推出短網址鏈接,比如微博等。
下面是從網上找到了一些算法總結:

算法一:

最容易想到的算法可能是利用md5類的加密算法,然後針對加密後的字符串進行處理。

1)將長網址md5生成32位簽名串,分爲4段, 每段8個字節;
2)對這四段循環處理, 取8個字節, 將他看成16進制串與0x3fffffff(30位1)與操作, 即超過30位的忽略處理;
3)這30位分成6段, 每5位的數字作爲字母表的索引取得特定字符, 依次進行獲得6位字符串;
4)總的md5串可以獲得4個6位串; 取裏面的任意一個就可作爲這個長url的短url地址。

算法二:
a-zA-Z0-9 這64位取6位組合,可產生500多億個組合數量。把數字和字符組合做一定的映射,就可以產生唯一的字符串,如第62個組合就是aaaaa9,第63個組合就是aaaaba,再利用洗牌算法,把原字符串打亂後保存,那麼對應位置的組合字符串就會是無序的組合。
把長網址存入數據庫,取返回的id,找出對應的字符串,例如返回ID爲1,那麼對應上面的字符串組合就是bbb,同理 ID爲2時,字符串組合爲bba,依次類推,直至到達64種組合後纔會出現重複的可能,所以如果用上面的62個字符,任意取6個字符組合成字符串的話,你的數據存量達到500多億後纔會出現重複的可能。

下面自己簡單模擬了一個返回8位隨即碼的短網址算法,算法實現基於算法一。
public class ShortUrlUtil {

	static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
			'9', 'a', 'b', 'c', 'd', 'e', 'f' };

	public static String shortUrl(String url) throws Exception {
		MessageDigest messagedigest = MessageDigest.getInstance("MD5");
		messagedigest.update(url.getBytes());
		String result = bufferToHex(messagedigest.digest());
		String resUrl = new String("");
		for (int i = 0; i < 8; i++) {
			String tmpString = result.substring(i * 4, i * 4 + 4);
			long hexLong = 0x3FFFFFFF & Long.parseLong(tmpString, 16);
			resUrl += hexDigits[Integer.valueOf((hexLong % 16) + "")] + "";
		}
		return resUrl;
	}

	private static String bufferToHex(byte bytes[]) {
		return bufferToHex(bytes, 0, bytes.length);
	}

	private static String bufferToHex(byte bytes[], int m, int n) {
		StringBuffer stringbuffer = new StringBuffer(2 * n);
		int k = m + n;
		for (int l = m; l < k; l++) {
			appendHexPair(bytes[l], stringbuffer);
		}
		return stringbuffer.toString();
	}

	private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
		char c0 = hexDigits[(bt & 0xf0) >> 4];
		char c1 = hexDigits[bt & 0xf];
		stringbuffer.append(c0);
		stringbuffer.append(c1);
	}
	
	public static void main(String[] args) {
		String sLongUrl = "http://weibo.com/taobaotianshui?wvr=5&wvr=5&lf=reg";
		String shortUrl;
		try {
			shortUrl = shortUrl(sLongUrl);
			System.out.println(sLongUrl + " ===> " + shortUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

當生成短網址鏈接之後,只需要在表中(數據庫或者類NoSql的K-V存儲)存儲原始鏈接與短鏈接的映射關係即可。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章