短网址的原理和实现

微博上经常会看到类似 http://t.cn/Afafhe 这样的短地址 
那么实现原理是什么呢 

其实很简单 ,系统把一个长的地址 如 http://www.xxx.com/ddd/xxx/a.html?dsada 
首先用一个算法转换成 短地址 http://t.cn/Afafhe 
然后把  Afafhe-->http://www.xxx.com/ddd/xxx/a.html?dsada 的关系保存到数据库中 

当用户访问 http://t.cn/Afafhe网址时,系统到数据库找到对应的URL地址,实现跳转 

那么我们要知道的1、算法 2、系统的存储方式 

首先看算法吧,网上搜索了下,大致是用MD5什么的生成的 ,其实这个算法主要是把长字符串变小 ,这个算法是不可逆的,所以别想着去直接反转短地址 
要详细看算法的 可以到网上搜索资料 

2、系统的存储方式 ,如果我们自己写着玩,那直接找个SQL Server 或者MySql 之类的就可以,但是想新浪微博之类的大型网站,那个数据量是非常巨大的,我想他们应该用的NoSql 非关系型数据库(应该也就是人们说的分布式数据库 ),一些开源的  如Facebook 的Cassandra, Apache 的HBase,也得到了广泛认同。从这些NoSQL项目的名字上看不出什么相同之处:Hadoop、Voldemort、Dynomite,还有其它很多。、 
http://baike.baidu.com/view/2677528.htm 

Java的短地址算法 

Java代码  收藏代码
  1. package work13;  
  2.   
  3. import java.security.MessageDigest;  
  4.   
  5. public class CMyEncrypt  
  6. {  
  7.     // 十六进制下数字到字符的映射数组  
  8.     private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",  
  9.             "E", "F" };  
  10.   
  11.     /** 把inputString加密 */  
  12.     public static String md5(String inputStr)  
  13.     {  
  14.         return encodeByMD5(inputStr);  
  15.     }  
  16.   
  17.     /** 
  18.      * 验证输入的密码是否正确 
  19.      *  
  20.      * @param password 
  21.      *            真正的密码(加密后的真密码) 
  22.      * @param inputString 
  23.      *            输入的字符串 
  24.      * @return 验证结果,boolean类型 
  25.      */  
  26.     public static boolean authenticatePassword(String password, String inputString)  
  27.     {  
  28.         if (password.equals(encodeByMD5(inputString)))  
  29.         {  
  30.             return true;  
  31.         } else  
  32.         {  
  33.             return false;  
  34.         }  
  35.     }  
  36.   
  37.     /** 对字符串进行MD5编码 */  
  38.     private static String encodeByMD5(String originString)  
  39.     {  
  40.         if (originString != null)  
  41.         {  
  42.             try  
  43.             {  
  44.                 // 创建具有指定算法名称的信息摘要  
  45.                 MessageDigest md5 = MessageDigest.getInstance("MD5");  
  46.                 // 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算  
  47.                 byte[] results = md5.digest(originString.getBytes());  
  48.                 // 将得到的字节数组变成字符串返回  
  49.                 String result = byteArrayToHexString(results);  
  50.                 return result;  
  51.             } catch (Exception e)  
  52.             {  
  53.                 e.printStackTrace();  
  54.             }  
  55.         }  
  56.         return null;  
  57.     }  
  58.   
  59.     /** 
  60.      * 轮换字节数组为十六进制字符串 
  61.      *  
  62.      * @param b 
  63.      *            字节数组 
  64.      * @return 十六进制字符串 
  65.      */  
  66.     private static String byteArrayToHexString(byte[] b)  
  67.     {  
  68.         StringBuffer resultSb = new StringBuffer();  
  69.         for (int i = 0; i < b.length; i++)  
  70.         {  
  71.             resultSb.append(byteToHexString(b[i]));  
  72.         }  
  73.         return resultSb.toString();  
  74.     }  
  75.   
  76.     // 将一个字节转化成十六进制形式的字符串  
  77.     private static String byteToHexString(byte b)  
  78.     {  
  79.         int n = b;  
  80.         if (n < 0)  
  81.             n = 256 + n;  
  82.         int d1 = n / 16;  
  83.         int d2 = n % 16;  
  84.         return hexDigits[d1] + hexDigits[d2];  
  85.     }  
  86.   
  87.     public static void main(String[] args)  
  88.     {  
  89.         CMyEncrypt.md5("http://tech.sina.com.cn/i/2011-03-23/11285321288.shtml");  
  90.     }  
  91. }  



Java代码  收藏代码
  1. package work13;  
  2.   
  3. public class ShortUrlGenerator  
  4. {  
  5.   
  6.     /** 
  7.      * @param args 
  8.      */  
  9.     public static void main(String[] args)  
  10.     {  
  11.   
  12.         String sLongUrl = "http://xxx.qzone.qq.com/dsa/fds/gf/hgf/hgf?dsada=dsada"; // 长链接  
  13.         String[] aResult = shortUrl(sLongUrl);  
  14.         // 打印出结果  
  15.         for (int i = 0; i < aResult.length; i++)  
  16.         {  
  17.             System.out.println("[" + i + "]:::" + aResult[i]);  
  18.         }  
  19.     }  
  20.   
  21.     public static String[] shortUrl(String url)  
  22.     {  
  23.         // 可以自定义生成 MD5 加密字符传前的混合 KEY  
  24.         String key = "mengdelong";  
  25.         // 要使用生成 URL 的字符  
  26.         String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",  
  27.                 "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",  
  28.                 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",  
  29.                 "U", "V", "W", "X", "Y", "Z"  
  30.   
  31.         };  
  32.         // 对传入网址进行 MD5 加密  
  33.         String sMD5EncryptResult = (new CMyEncrypt()).md5(key + url);  
  34.         String hex = sMD5EncryptResult;  
  35.   
  36.         String[] resUrl = new String[4];  
  37.         for (int i = 0; i < 4; i++)  
  38.         {  
  39.   
  40.             // 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算  
  41.             String sTempSubString = hex.substring(i * 8, i * 8 + 8);  
  42.   
  43.             // 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用  
  44.             // long ,则会越界  
  45.             long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);  
  46.             String outChars = "";  
  47.             for (int j = 0; j < 6; j++)  
  48.             {  
  49.                 // 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引  
  50.                 long index = 0x0000003D & lHexLong;  
  51.                 // 把取得的字符相加  
  52.                 outChars += chars[(int) index];  
  53.                 // 每次循环按位右移 5 位  
  54.                 lHexLong = lHexLong >> 5;  
  55.             }  
  56.             // 把字符串存入对应索引的输出数组  
  57.             resUrl[i] = outChars;  
  58.         }  
  59.         return resUrl;  
  60.     }  
  61. }  





参考:http://iteye.blog.163.com/blog/static/1863080962012111223141936/

原文地址:https://www.cnblogs.com/kenshinobiy/p/4685512.html