微博URL短網址生成算法原理及(java版、php版實現實例)

短網址(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); 
}

}google

如下爲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 )存儲原始連接與短連接的映射關係便可。當咱們訪問短連接時,只須要從映射關係中找到原始連接,便可跳轉到原始連接。

相關文章
相關標籤/搜索