一般咱們生成惟一序列號的時候喜歡把時間做爲序列號的其中,但時間序列號的長度爲15,加上其餘諸如userid,商戶merchantid等長度達到50~60位,這樣致使咱們的序列號就很是長致使。git
1,存放時佔用空間大,ide
2,查詢時效率慢測試
咱們是否是能夠把時間序列號變短呢?編碼
咱們知道:code
根據ascII編碼表:blog
小寫字符a(97) 使用不一樣存儲時的編碼長度ci
二進制:01100001字符串
八進制:141string
十進制:97it
十六進制:61
能夠看出,隨着進制的增高,字符的長度也會愈來愈短,若是咱們拿咱們經常使用的0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ這個62個字符做爲編碼,那麼62進制就能夠表示了。
再進行編碼前,我搜了一下git,上面已經有代碼實現了(base62),我就再也不實現一遍了,代碼以下:
1.編碼,將long型轉換爲62進制字符串 /** * Encodes a decimal value to a Base62 <code>String</code>. * * @param b10 * the decimal value to encode, must be nonnegative. * @return the number encoded as a Base62 <code>String</code>. */ public String encodeBase10(long b10) { if (b10 < 0) { throw new IllegalArgumentException("b10 must be nonnegative"); } String ret = ""; while (b10 > 0) { ret = characters.charAt((int) (b10 % 62)) + ret; b10 /= 62; } return ret; }
2.解碼,逆過程
/** * Decodes a Base62 <code>String</code> returning a <code>long</code>. * * @param b62 * the Base62 <code>String</code> to decode. * @return the decoded number as a <code>long</code>. * @throws IllegalArgumentException * if the given <code>String</code> contains characters not * specified in the constructor. */ public long decodeBase62(String b62) { for (char character : b62.toCharArray()) { if (!characters.contains(String.valueOf(character))) { throw new IllegalArgumentException("Invalid character(s) in string: " + character); } } long ret = 0; b62 = new StringBuffer(b62).reverse().toString(); long count = 1; for (char character : b62.toCharArray()) { ret += characters.indexOf(character) * count; count *= 62; } return ret; }
測試用例(以15位的時間戳爲例):
public static void main(String[] args) { Base62 encoder=new Base62(); Long time=System.nanoTime(); String timeStr=encoder.encodeBase10(time); System.out.println(timeStr); System.out.println(time); System.out.println(encoder.decodeBase62(timeStr)); }
console輸出結果以下:
2OdCqJOH8 613534552694770 613534552694770
長度由15位變爲9位,減小了40%的長度,當前查詢效率也獲得相應的提高了。
是否是蠻有趣的?