短网址(Short URL) ,顾名思义就是看起来很短的网址。自从twitter推出短网址服务以后,各大互联网公司都推出了自己的短网
址服务。个人感觉短网址最大的优点就是短,字符少,便于发布、传播、复制和存储。
通过网上的搜索,感觉流传了2种短网址算法,一种是基于MD5码的,一种是基于自增序列的。
1、基于MD5码 : 这种算法计算的短网址长度一般是5位或者6位,计算过程中可能出现碰撞(概率很小),可表达的url数量为62
的5次方或6次方。感觉google(http://goo.gl),微博用的是类似这种的算法(猜的),可能看起来比较美观。
2、基于自增序列 : 这种算法实现比较简单,碰撞的可能性为0,可表达的URL可达无穷大,长度从1开始。貌似百度的短网址服
务(
http://dwz.cn/)是这种算法.
具体算法
1、MD5码 :假设url的长度为N
a.计算长地址的MD5码,将32位的MD码分成4段,每段8个字符
b.将a得到的8个字符串看成一个16进制的数,与N * 6个1表示的二进制数进行&操作
得到一个N * 6长的二进制数
c.将b得到的数分成N段,每段6位,然后将这N个6位数分别与61进行&操作,将得到的
数作为INDEX去字母表取相应的字母或数字,拼接就是一个长度为N的短网址。
static final char[] DIGITS =
{ '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', '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' };
public String shorten(String longUrl, int urlLength) {
if (urlLength < 0 || urlLength > 6) {
throw new IllegalArgumentException("the length of url must be between 0 and 6");
}
String md5Hex = DigestUtils.md5Hex(longUrl);
// 6 digit binary can indicate 62 letter & number from 0-9a-zA-Z
int binaryLength = urlLength * 6;
long binaryLengthFixer = Long.valueOf(StringUtils.repeat("1", binaryLength), BINARY);
for (int i = 0; i < 4; i++) {
String subString = StringUtils.substring(md5Hex, i * 8, (i + 1) * 8);
subString = Long.toBinaryString(Long.valueOf(subString, 16) & binaryLengthFixer);
subString = StringUtils.leftPad(subString, binaryLength, "0");
StringBuilder sbBuilder = new StringBuilder();
for (int j = 0; j < urlLength; j++) {
String subString2 = StringUtils.substring(subString, j * 6, (j + 1) * 6);
int charIndex = Integer.valueOf(subString2, BINARY) & NUMBER_61;
sbBuilder.append(DIGITS[charIndex]);
}
String shortUrl = sbBuilder.toString();
if (lookupLong(shortUrl) != null) {
continue;
} else {
return shortUrl;
}
}
// if all 4 possibilities are already exists
return null;
}
2、自增序列:
a. 或者序列的自增值,将值用62进制表示。
private AtomicLong sequence = new AtomicLong(0);
@Override
protected String shorten(String longUrl) {
long myseq = sequence.incrementAndGet();
String shortUrl = to62RadixString(myseq);
return shortUrl;
}
private String to62RadixString(long seq) {
StringBuilder sBuilder = new StringBuilder();
while (true) {
int remainder = (int) (seq % 62);
sBuilder.append(DIGITS[remainder]);
seq = seq / 62;
if (seq == 0) {
break;
}
}
return sBuilder.toString();
}
MAVEN工程中的代码用2个MAP来模拟存放长-短网址的互相映射,实际使用中可能是基于数据库表配合索引或者一些分布式KV系统来实现。
分享到:
相关推荐
各种算法 java和c语言两种实现各种算法 java和c语言两种实现各种算法 java和c语言两种实现各种算法 java和c语言两种实现
数据结构算法 java和c语言两种实现 数据结构算法 java和c语言两种实现
进程调度的两种算法JAVA实现----FCFS(先来先服务)和SJF(最短作业优先) 直接能运行,完整版本,jdk 1.6就行
经典常用算法 Java和C语言两种实现,一些常用算法的java与c语言的实现.
JAVA下使用两种方法(计算法、查表法)实现CRC(XMODEM)算法,以及验证代码
常见算法(C,java两种实现代码) 一些常见的算法了,用C及java实现。
binpacking java 近似算法 不同策略比较 高级算法 研究生算法课程作业
面试面多了冒泡也写的多了,这个里面有两种方式,相互学习下哦!
并用java实现。代码拿去即可用,不需做任何修改! 部分内容: /** * 快排:O(n*logn);如果是从小到大排序; * 思想:选一个关键数据,将数组分成以关键数据分割的独立两个子数组;比关键数据小的在左边,大的在...
河内塔 费式数列 巴斯卡三角形 三色棋 老鼠走迷官(一) 老鼠走迷官(二) 骑士走棋盘 八个皇后 八枚银币 生命游戏 字串核对 双色、三色河内塔 背包问题(Knapsack Problem)
java基础试验,求最大公约数的两种算法实现等。
各种经典算法+Java和C语言的两种实现
算法(资源中包括数据结构的经典实现,用c语言和java语言两种语言实现)编程必备的资料
介绍了两种JAVA实现短网址服务算法,一种是基于MD5码的,一种是基于自增序列的,需要的朋友可以参考下
该算法在 Java 中以两种方式实现。第一个实现使用 Java 并行流和 lambda 表达式。该解决方案利用能够提供有竞争力的加速的内置多线程组织。第二个实现是在Theatre actor系统之上实现的,该系统通过细粒度的资源控制...
这是一个用Java实现的关于N皇后问题的算法 其中包括回溯和迭代两种算法
Java实现分词(正向最大匹配和逆向最大匹配)两种方法实现
主要是一些常见的,很好的、经典的算法。分别用JAVA和C两种语言实现。可以借此培养自己算法程序的逻辑感!
包括RSA算法的两种语言实现,原理正确,可以正常运行,对应博客为:https://blog.csdn.net/qq_41112170/article/details/104904340