公司要求实现短链接的功能,整理了实现的思路。
基本思路就是行记录的主键(唯一标识)和N(包含连接中允许的字符数)进制互相转换。
例如短链接内容允许包含数组和大小写字母,则N=62(数字0~9【10位】、字母a~z【26位】、大写字母A~Z【26位】)。
该方案是最佳方案。如果没有行记录的主键进行参考,可以考虑使用redis缓存实现ID发号器,来生成唯一标识。
网上也有用hash等方法来实现,但这肯定会有碰撞率,可以直接pass。
代码如下:
public class ShortUrlUtil {
private static Logger logger = Logger.getLogger(ShortUrlUtil.class);
private static char[] charSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
/**
* 将10进制转化为62进制
*/
public static String _10_to_62(long number, int length) {
Long rest = number;
Stack<Character> stack = new Stack<Character>();
StringBuilder result = new StringBuilder(0);
while (rest != 0) {
stack.add(charSet[new Long((rest - (rest / 62) * 62)).intValue()]);
rest = rest / 62;
}
for (; !stack.isEmpty(); ) {
result.append(stack.pop());
}
int result_length = result.length();
StringBuilder temp0 = new StringBuilder();
for (int i = 0; i < length - result_length; i++) {
temp0.append('0');
}
return temp0.toString() + result.toString();
}
/**
* 将62进制转换成10进制数
*/
private static String convertBase62ToDecimal(String ident62) {
int decimal = 0;
int base = 62;
int keisu = 0;
int cnt = 0;
byte ident[] = ident62.getBytes();
for (int i = ident.length - 1; i >= 0; i--) {
int num = 0;
if (ident[i] > 48 && ident[i] <= 57) {
num = ident[i] - 48;
} else if (ident[i] >= 65 && ident[i] <= 90) {
num = ident[i] - 65 + 10;
} else if (ident[i] >= 97 && ident[i] <= 122) {
num = ident[i] - 97 + 10 + 26;
}
keisu = (int) java.lang.Math.pow((double) base, (double) cnt);
decimal += num * keisu;
cnt++;
}
return String.format("%08d", decimal);
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("62System=" + _10_to_62(Integer.parseInt("30051"), 6));
System.out.println("10System=" + convertBase62ToDecimal("0007oh"));
}
}