⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 网络 「网络」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

最近,项目中需要用到短网址(ShortUrl)的算法,于是在网上搜索一番,发现有C#的算法,有 .Net 的算法,有 PHP 的算法,就是没有找到Java版的短网址(ShortUrl)的算法,很是郁闷。同时还发现有不少网友在发帖求助,怎么实现Java版的短网址(ShortUrl)的算法。干脆一不做,二不休,参考了一下网上比较流行的PHP版短网址(ShortUrl)算法:

再根据自己的理解,用Java实现了该短网址(ShortUrl)的算法。目前企业内部能凑合着用,“毫无压力”!

先来废话一下,是在别人的帖子上看到的,主要是让大家了解一下短网址(ShortUrl)。

短链转长链

时下,短网址应用已经在全国各大微博上开始流行了起来。例如QQ微博的url.cn,新郎的t.cn等。

进制转换

我们在新浪微博上发布网址的时候,微博会自动判别网址,并将其转换,例如: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地址。

很简单的理论,我们并不一定说得到的URL是唯一的,但是我们能够取出4组URL,这样几乎不会出现太大的重复。

首先,请大家了解在Java中如何用MD5来加密字符串得到32位的加密后的字符串,下面是我已经封装好的Java MD5算法:

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 data = "189022881112011111118:09sz0000123456789987654321";
System.out.println(MD5Encode(data));
}
public class ShortUrl {
public static void main(String[] args) {
String url = "http://www.sunchis.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;
}

private static void print(Object messagr){
System.out.println(messagr);
}
}

下面来看看程序部分:现在可以直接使用ShortText(url)方法,可以等到下面四组值:

ShortText("http://www.xttblog.com")[0];  //得到值:Jzyqma 
ShortText("http://www.xttblog.com")[1]; //得到值:QBrMzm
ShortText("http://www.xttblog.com")[2]; //得到值:bQreM3
ShortText("http://www.xttblog.com")[3]; //得到值:VNBRna

选取结果中四个值的任何一个值即可作为URL对应生成的短网址了。

目前公司内部的链接还不是特别多,访问也不大。花1天时间,搞个破系统,先上线了完成业务需求。后面再参考网上的一些优秀算法来改进!

文章目录