使用60进制的程序仿了一个新浪微博短链接生成器
与其说仿新浪短网址其实算是个嚼头,招引人们的眼球,对于常规的进制算法可以去参看数据结构一书
通过取模方式计算出对应的n进制数,t.cn短网址的原理大致如下:
int nv = 2; //进制
int n = 4;
List<Integer> ll = new ArrayList<Integer>();
while (n >= 1) {
ll.add(n%nv);
System.out.print(n % nv + ",");
n = n / nv;
}
System.out.println();
//排列后的值
for (int x=ll.size()-1;ll.size()>0&&x>=0;x--) {
System.out.print(ll.get(x));
}
这种方法仍是针对10进制内相互转换有用,由于你不可能使用字母和数字去取模运算
所以就有了数组代替纯数字的方法进行运算
import java.util.HashSet;
import java.util.Random;
public class ShortUrl {
private static final String[] l = {
"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"};
private static int count = 100;
private static int getCount(){
if(count>999)count = 100;
return count++;
}
//TentoN(这里是你想转换的数 ,这里是你想转换为多少进制 2-62之间)
public static String TentoN(long value, int number) {
if (number <= 1 || number > l.length) {
throw new RuntimeException("Faild");
}
//负数处理
if (value < 0) {
return "-" + TentoN(0 - value, number);
}
if (value < number) {
return l[(int)value];
} else {
long n = value % (long)number;
return (TentoN(value / number, number) + l[(int)n]);
}
}
/**
* 返回4位随机数
* @return
*/
public static Integer getRandom2(){
Integer i = new Random().nextInt(9999);
while(i<1000) i=i<<1;
return i;
}
public static void main(String[] args) throws InterruptedException {
long a = System.currentTimeMillis();
HashSet<String> hs = new HashSet<String>();
for(int i=0;i<1000;i++){
String s = TentoN((System.currentTimeMillis()-1323333000000L), 62)+TentoN((long)getCount(),62);
hs.add(s);
System.out.println(s);
}
System.out.println(hs.size());
long b = System.currentTimeMillis();
System.out.println("毫秒:"+(b-a));
}
}
2017-03-14 09:56 循环1000次后运行后得到的最终几条成果
1000次无重复,耗时47毫秒
yMV53b
yMV53c
yMV53d
1000
毫秒:47
不过没多长时刻,数据长度就涨到了8位啦~
高并发的疑问,实际运用中肯定会存在一个疑问,那就是多个用户同一时刻内进行了一个操作,成果就是多条记录返回的值是一样的,开端的时分我思考的是运用随机数的办法,不过随机数并不是一个万全的解决办法,由于随机并不表明不会一样,也许就会2个用户杯具的得到了同一个随机数,那么数据库的仅有条件就被破坏了
解决办法本来也不难,假如对于含有订单的项目可以运用流水号作为扩展字符将成果仅有化
不过订单的长度有时分也不会是短位数。
比较简略的办法就是运用一个全局仅有的计数器。
通过getCount办法咱们可以在1毫秒内最多取得900个不会重复的3位数字
当然咱们没有必要每毫秒都去重置这个计数器,由于即便2毫秒得到了1800个数据也不会重复,由于前面的体系毫秒数已经改变了
对于微博来说生成一个短链接本来不难,首要的仍是防止重复,假如运用10进制的数字办法进行保存的话数据量会非常惊人,也许起初的时分仍是百位千位或者万位,后面跟着数据量的递加,长度会越来越大,因而运用多进制的办法可以放缓数据递加的疑问
这里我思考的仍是简略的毫秒数计算办法。
运用System.currentTimeMillis()咱们可以取得一个14位的当时时刻的毫秒数,当然直接运用的话没有疑问,不过为了生成数据的长度咱们尽可能将他的开端时刻提前,比方一个项目2012年才开端运用,咱们就没有必要非从2008年那个节点开端,如上面的代码我随便减去了一个毫秒数 1323333000000L 详细是什么时分咱们没有必要去了解,这个只是为了减少时刻差及最终生成的短网址长度而做的一步操作
假如你减去了的正好的当时时刻,那么生成的短连接就只有1位了
已知存在的疑问:跟着时刻的推移,几天 几年后,毫秒数的添加肯定会使数据长度不断添加,这个仍是根据实际需要去修改吧,对于数据量较少的,比方一天的数据量远远小于百位的,运用ddMMyyyy 日 月 年 加上补位数就可以满意改变的需求了,由于年月日方向颠倒 也可以添加扰码度防猜测
好了所有相关的部分都简略介绍完了,详细的运用需要的大家再持续研究好了,也希望有非常好解决办法的童鞋们大方贴出代码来分享