短網址ShortUrl的算法


場景:

我們在新浪微博上公布網址的時候。微博會自己主動判別網址。並將其轉換。比如:http://t.cn/hrYnr0。

為什么要這樣做的,原因我想有這樣幾點: 


1、微博限制字數為140字一條,那么假設我們須要發一些連接上去,可是這個連接很的長。以至於將近要占用我們內容的一半篇幅。這肯定是不能被同意的。所以短網址應運而生了。 

2、短網址能夠在我們項目里能夠非常好的對開放級URL進行管理。

有一部分網址能夠會涵蓋性、暴力、廣告等信息。這樣我們能夠通過用戶的舉報,全然管理這個連接將不出如今我們的應用中,應為相同的URL通過加密算法之后,得到的地址是一樣的。 

3、我們能夠對一系列的網址進行流量,點擊等統計,挖掘出大多數用戶的關注點。這樣有利於我們對項目的興許工作更好的作出決策。

 

以下先來看看短網址映射算法的理論(網上找到的資料): 

① 將長網址用md5算法生成32位簽名串,分為4段,,每段8個字符; 

② 對這4段循環處理,取每段的8個字符, 將他看成16進制字符串與0x3fffffff(30位1)的位與操作。超過30位的忽略處理。 

③ 將每段得到的這30位又分成6段,每5位的數字作為字母表的索引取得特定字符,依次進行獲得6位字符串; 

④ 這樣一個md5字符串能夠獲得4個6位串。取里面的隨意一個就可作為這個長url的短url地址。 

非常easy的理論,我們並不一定說得到的URL是唯一的。可是我們可以取出4組URL,這樣差點兒不會出現太大的反復。 

三、  跳轉原理

當我們生成短鏈接之后。僅僅須要在表中(數據庫或者NoSql )存儲原始鏈接與短鏈接的映射關系就可以。當我們訪問短鏈接時,僅僅須要從映射關系中找到原始鏈接。就可以跳轉到原始鏈接。


Java代碼   收藏代碼
  1.    
  2. import util.Encript;   
  3.    
  4. public class ShortUrl {   
  5.     public static void main(String[] args) {   
  6.         String url = "http://www.sunchis.com";   
  7.         for (String string : ShortText(url)) {   
  8.             print(string);   
  9.         }   
  10.     }   
  11.        
  12.     public static String[] ShortText(String string){   
  13.         String key = "XuLiang";                 //自己定義生成MD5加密字符串前的混合KEY   
  14.         String[] chars = new String[]{          //要使用生成URL的字符   
  15.             "a","b","c","d","e","f","g","h",   
  16.             "i","j","k","l","m","n","o","p",   
  17.             "q","r","s","t","u","v","w","x",   
  18.             "y","z","0","1","2","3","4","5",   
  19.             "6","7","8","9","A","B","C","D",   
  20.             "E","F","G","H","I","J","K","L",   
  21.             "M","N","O","P","Q","R","S","T",   
  22.             "U","V","W","X","Y","Z"   
  23.         };   
  24.            
  25.         String hex = Encript.md5(key + string);   
  26.         int hexLen = hex.length();   
  27.         int subHexLen = hexLen / 8;   
  28.         String[] ShortStr = new String[4];   
  29.            
  30.         for (int i = 0; i < subHexLen; i++) {   
  31.             String outChars = "";   
  32.             int j = i + 1;   
  33.             String subHex = hex.substring(i * 8, j * 8);   
  34.             long idx = Long.valueOf("3FFFFFFF"16) & Long.valueOf(subHex, 16);   
  35.                
  36.             for (int k = 0; k < 6; k++) {   
  37.                 int index = (int) (Long.valueOf("0000003D"16) & idx);   
  38.                 outChars += chars[index];   
  39.                 idx = idx >> 5;   
  40.             }   
  41.             ShortStr[i] = outChars;   
  42.         }   
  43.            
  44.         return ShortStr;   
  45.     }   
  46.        
  47.     private static void print(Object messagr){   
  48.         System.out.println(messagr);   
  49.     }   
  50. }   


Java代碼   收藏代碼
  1. public class Encript {   
  2.     //十六進制下數字到字符的映射數組   
  3.     private final static String[] hexDigits = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};   
  4.    
  5.     /**把inputString加密*/   
  6.     public static String md5(String inputStr){   
  7.         return encodeByMD5(inputStr);   
  8.     }   
  9.    
  10.     /**  
  11.     * 驗證輸入的password是否正確  
  12.     * @param password 真正的password(加密后的真password)  
  13.     * @param inputString 輸入的字符串  
  14.     * @return 驗證結果,boolean類型  
  15.     */   
  16.     public static boolean authenticatePassword(String password,String inputString){   
  17.         if(password.equals(encodeByMD5(inputString))){   
  18.             return true;   
  19.         }else{   
  20.             return false;   
  21.         }   
  22.     }   
  23.    
  24.     /**對字符串進行MD5編碼*/   
  25.     private static String encodeByMD5(String originString){   
  26.         if (originString!=null) {   
  27.             try {   
  28.                 //創建具有指定算法名稱的信息摘要   
  29.                 MessageDigest md5 = MessageDigest.getInstance("MD5");   
  30.                 //使用指定的字節數組對摘要進行最后更新,然后完畢摘要計算   
  31.                 byte[] results = md5.digest(originString.getBytes());   
  32.                 //將得到的字節數組變成字符串返回    
  33.                 String result = byteArrayToHexString(results);   
  34.                 return result;   
  35.             } catch (Exception e) {   
  36.                 e.printStackTrace();   
  37.             }   
  38.         }   
  39.         return null;   
  40.     }   
  41.    
  42.     /**  
  43.     * 輪換字節數組為十六進制字符串  
  44.     * @param b 字節數組  
  45.     * @return 十六進制字符串  
  46.     */   
  47.     private static String byteArrayToHexString(byte[] b){   
  48.         StringBuffer resultSb = new StringBuffer();   
  49.         for(int i=0;i<b.length;i++){   
  50.             resultSb.append(byteToHexString(b[i]));   
  51.         }   
  52.         return resultSb.toString();   
  53.     }   
  54.    
  55.     //將一個字節轉化成十六進制形式的字符串   
  56.     private static String byteToHexString(byte b){   
  57.         int n = b;   
  58.         if(n<0)   
  59.         n=256+n;   
  60.         int d1 = n/16;   
  61.         int d2 = n%16;   
  62.         return hexDigits[d1] + hexDigits[d2];   
  63.     }   
  64. }   



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM