81进制,用多进制方式把一个长长的整数变短
最近在做项目有些资源要用到唯一的标识code,这个code要全局唯一,因此比较长,有25位,long只能处理到19位。另外25位长的一个整数阅读显示都不是很理想,因此开发了一个多进制的转换类。思想接近把一个域名用几个字符代替。下面就是实现的具体java代码,目前支持到81进制。
1 import java.math.BigInteger; 2 import java.util.Arrays; 3 import java.util.Date; 4 5 /** 6 * 7 * @author 程序员老刘@2015-07-28 8 * @Description 把十进制的数字转换成36、62或者81进制,使表达的长度变短,例如99999转成62进制是Q0t 9 */ 10 public class MultiNumberation { 11 12 private final static char[] flag = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 13 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 14 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 15 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 16 '!', '#', '%', '&', '$', '*', '(', ')', '[', ']', '{', '}', '^', '~', '?', '@', '>', 17 '<', '=' }; 18 19 public static int getDeep() { 20 return flag.length; 21 } 22 23 public static int findInFlag(String f) { 24 char c = (char) f.getBytes()[0]; 25 for (int i = 0; i < flag.length; i++) { 26 if (flag[i] == c) 27 return i; 28 } 29 return -1; 30 } 31 32 public static BigInteger toDecimal(String multi, int deep) { 33 BigInteger result = new BigInteger("0"); 34 if (deep < 1 || deep > flag.length || deep == 10) 35 return result; 36 37 BigInteger d = BigInteger.valueOf(deep); 38 for (int i = 0; i < multi.length(); i++) { 39 int pos = findInFlag(multi.substring(i, i + 1)); 40 // Arrays.binarySearch(flag, (char) (multi.substring(i, i + 41 // 1).getBytes()[0])); 42 43 result = result.add(d.pow(multi.length() - i - 1).multiply(BigInteger.valueOf(pos))); 44 } 45 return result; 46 } 47 48 /** 49 * 50 * @Title: 51 * @Description:将十进制整数转为指定进制的数 52 * @param decimal 53 * --十进制整数 54 * @param deep 55 * --选择进制,从2~81 56 * @return 57 */ 58 public static String toMulti(BigInteger decimal, int deep) { 59 if (deep < 1 || deep > flag.length || deep == 10) 60 return ""; 61 // 取余数 62 BigInteger d = BigInteger.valueOf(deep); 63 BigInteger[] bigDivide = decimal.divideAndRemainder(d); 64 int remainder = bigDivide[1].intValue(); 65 String result = "" + flag[(int) remainder]; 66 67 // 取商 68 BigInteger quotient = bigDivide[0]; 69 // 商数下雨指定的进制数则继续 70 if (quotient.compareTo(d) >= 0) { 71 result = toMulti(quotient, deep) + result; 72 } else { 73 result = "" + flag[(int) quotient.intValue()] + result; 74 } 75 76 return result; 77 } 78 79 public static void main(String[] args) { 80 int deep = MultiNumberation.getDeep(); 81 // System.out.println("deep=" + deep); 82 long s = new Date().getTime(); 83 // MultiNumeration.toMulti(238328L, deep); 84 for (long i = 1000000; i < 1000002; i++) { 85 String code = String.valueOf(i); 86 // String code = 87 // CreateCodeHelper.createCode(SeqObjectName.ServiceGroup_Category); 88 // System.out.println("code=" + code); 89 BigInteger big = new BigInteger(code); 90 91 String ret = MultiNumberation.toMulti(big, deep); 92 System.out.println(code + ">>" + ret + "===>" + MultiNumberation.toDecimal(ret, deep)); 93 } 94 System.out.println("deep=" + deep + ",timeout:" + (new Date().getTime() - s)); 95 } 96 }