Java程式設計:10進位制數、62進位制數進行相互轉換
阿新 • • 發佈:2018-12-30
場景:要求隨機生成長度較短的使用者名稱,保證使用者名稱唯一,同時保證使用者名稱不易被推測出。
解決思路:按序生成唯一序列號,通過演算法將序列號進行混淆,之後將其轉化為 62 進位制的 11 位字串。通過以上的策略可以保證生成的使用者名稱唯一,通過混淆演算法使使用者名稱不易被推測出,並且最大可以支援 2^62 - 1 個使用者名稱。
以下程式碼是將10進位制、62進位制互轉的方法,後續會寫一篇關於混淆演算法的文章。文章僅代表個人觀點,如有不正之處,歡迎批評指正。
package org.learn.id;
import org.apache.commons.lang.StringUtils;
/**
* 10進位制、62進位制互轉
* edited by zhibo on 2015/05/21.
*/
public class ConversionUtil {
/**
* 初始化 62 進位制資料,索引位置代表字元的數值,比如 A代表10,z代表61等
*/
private static String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static int scale = 62;
/**
* 將數字轉為62進位制
*
* @param num Long 型數字
* @param length 轉換後的字串長度,不足則左側補0
* @return 62進位制字串
*/
public static String encode(long num, int length) {
StringBuilder sb = new StringBuilder();
int remainder = 0;
while (num > scale - 1) {
/**
* 對 scale 進行求餘,然後將餘數追加至 sb 中,由於是從末位開始追加的,因此最後需要反轉(reverse)字串
*/
remainder = Long.valueOf(num % scale).intValue();
sb.append(chars.charAt(remainder));
num = num / scale;
}
sb.append(chars.charAt(Long.valueOf(num).intValue()));
String value = sb.reverse().toString();
return StringUtils.leftPad(value, length, '0');
}
/**
* 62進位制字串轉為數字
*
* @param str 編碼後的62進位制字串
* @return 解碼後的 10 進位制字串
*/
public static long decode(String str) {
/**
* 將 0 開頭的字串進行替換
*/
str = str.replace("^0*", "");
long num = 0;
int index = 0;
for (int i = 0; i < str.length(); i++) {
/**
* 查詢字元的索引位置
*/
index = chars.indexOf(str.charAt(i));
/**
* 索引位置代表字元的數值
*/
num += (long) (index * (Math.pow(scale, str.length() - i - 1)));
}
return num;
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("62進位制:" + encode(2576460752303423487L, 11));
System.out.println("10進位制:" + decode("34KDUNMZwuV"));
}
}