稍稍参(复)考(制)了 《10进制与62进制互相转换_Heartsuit的博客》之后,我将两个方法改写成Java,惊讶于Java与C#语法、接口之近似,基本上改改API名称的首字母大小写就能兼容。kotlin那种六亲不认的语法还是丢给小朋友玩吧。
可以将Long转换为String,支持的数字范围是Long.MIN_VALUE~Long.MAX_VALUE,支持负数。不过生成的字符串是小端版本:
2147483647 ==> “1bcKL2”
9223372036854775807 ==> “7m85Y0n8LzA”
-9223372036854775808 ==> “8m85Y0n8LzA-”
代码如下:
/** 将数字转为62进制。小端,个位数在前。 */
public static String NumberToText_SIXTWO_LE(long number)
{
final char[] NumberToText_SIXTWO_ARR = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
final int scale = 62;
StringBuilder sb = new StringBuilder(12);
boolean negative=number<0;
if(negative) number=-number;
if(number<0) return "8m85Y0n8LzA-";
//SU.Log("NumberToText_SIXTWO_LE", number, -(number+1));
long remainder;
while (number != 0) {
remainder = number % scale;
sb.append(NumberToText_SIXTWO_ARR[(int) remainder]);
number = number / scale;
}
if(negative) sb.append('-');
return sb.toString();
}
/** 62进制字符串转为数字。小端,个位数在前。 */
public static long TextToNumber_SIXTWO_LE(String text)
{
if("8m85Y0n8LzA-".equals(text)) return Long.MIN_VALUE;
final int scale = 62;
long num = 0;
int len=text.length(),i=len-1;
if(len>0) {
boolean negative=text.charAt(0)=='-';
if(negative) i--;
int index;
char c;
for(; i >= 0; i--)
{
c = text.charAt(i);
if(c>='A'&&c<='Z' || c>='a'&&c<='z') {
if (c>='a') {
index = c-'a'+36;
} else {
index = c-'A'+10;
}
} else {
index = (c-'0')%10;
}
num += (long)(index * (Math.pow(scale, i)));
}
if(negative) num=-num;
}
return num;
}
Java原生最小的负数是Long.MIN_VALUE,取负值后仍然是负数,即Long.MIN_VALUE==-Long.MIN_VALUE,所以需要当作特例处理,不知有无更好的算法。