使用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 日 月 年 加上補位數就可以滿意改變的需求了,由于年月日方向顛倒 也可以添加擾碼度防猜測
好了所有相關的部分都簡略介紹完了,詳細的運用需要的大家再持續研究好了,也希望有非常好解決辦法的童鞋們大方貼出代碼來分享
掃描二維碼推送至手機訪問。
版權聲明:本文由短鏈接發布,如需轉載請注明出處。
本文鏈接:http://www.virginiabusinesslawupdate.com/article_189.html