Handy to store large numbers in a shorter notation. Doesn't work with negative numbers (for negative numbers you need to store an additional byte to indicate a positive or negative value, pass the absolute value).
private static final short BASE_40_RADIX = 40;
private static final short BASE_40_BASE = 48;
private static final String BASE_40_ZERO = "0";
public static long fromBase40(char[] cs) {
return fromBase(cs, BASE_40_BASE, BASE_40_RADIX);
}
public static char[] toBase40(final long i) {
return toBase(i, BASE_40_BASE, BASE_40_RADIX, BASE_40_ZERO);
}
private static final short BASE_75_RADIX = 75;
private static final short BASE_75_BASE = 48;
private static final String BASE_75_ZERO = "0";
public static long fromBase75(char[] cs) {
return fromBase(cs, BASE_75_BASE, BASE_75_RADIX);
}
public static char[] toBase75(final long i) {
return toBase(i, BASE_75_BASE, BASE_75_RADIX, BASE_75_ZERO);
}
private static final short BASE_90_RADIX = 90;
private static final short BASE_90_BASE = 33;
private static final String BASE_90_ZERO = "!";
public static long fromBase90(char[] cs) {
return fromBase(cs, BASE_90_BASE, BASE_90_RADIX);
}
public static char[] toBase90(final long i) {
return toBase(i, BASE_90_BASE, BASE_90_RADIX, BASE_90_ZERO);
}
private static char[] toBase(final long i, final short base, final short radix, String nullCharacter) {
long value = i;
if (value == 0) {
return nullCharacter.toCharArray();
}
String result = "";
while (value > 0) {
long mod = value % radix;
value -= mod;
if (value > 0) value /= radix;
result = (char)(mod + base) + result;
}
return result.toCharArray();
}
private static long fromBase(char[] cs, final short base, final short radix) {
long value = 0;
for (int i = cs.length - 1; i >= 0; i--) {
int digit = ((int)cs[i]) - base;
if (digit < 0 || digit >= radix) {
throw new IllegalArgumentException("Invalid Base" + radix + " character: " + cs[i]);
}
long digitBase = (long)Math.pow(radix, (cs.length - 1) - i);
value = (digit * digitBase) + value;
}
return value;
}
And here are some tests:
public void testFromBase40() {
assertEquals(2559999, NumberUtils.fromBase40("WWWW".toCharArray()));
assertEquals(1117580, NumberUtils.fromBase40("ABCD".toCharArray()));
assertEquals(0, NumberUtils.fromBase40("0".toCharArray()));
assertEquals(1, NumberUtils.fromBase40("1".toCharArray()));
assertEquals(40, NumberUtils.fromBase40("10".toCharArray()));
assertEquals(80, NumberUtils.fromBase40("20".toCharArray()));
assertEquals(41, NumberUtils.fromBase40("11".toCharArray()));
assertEquals(81, NumberUtils.fromBase40("21".toCharArray()));
assertEquals(81, NumberUtils.fromBase40("0021".toCharArray()));
assertEquals(3061560805L, NumberUtils.fromBase40("MSTSD5".toCharArray()));
}
public void testToBase40() {
assertEquals("0", new String(NumberUtils.toBase40(0)));
assertEquals("1", new String(NumberUtils.toBase40(1)));
assertEquals("10", new String(NumberUtils.toBase40(40)));
assertEquals("20", new String(NumberUtils.toBase40(80)));
assertEquals("11", new String(NumberUtils.toBase40(41)));
assertEquals("21", new String(NumberUtils.toBase40(81)));
assertEquals("ABCD", new String(NumberUtils.toBase40(1117580)));
assertEquals("WWWW", new String(NumberUtils.toBase40(2559999)));
assertEquals("MSTSD5", new String(NumberUtils.toBase40(3061560805L)));
}
public void testToBase90() throws Exception {
assertEquals("#Q&Y.`QY#", new String(NumberUtils.toBase90(10908158098650842L)));
}
public void testFromBase90() throws Exception {
assertEquals(10908158098650842L, NumberUtils.fromBase90("#Q&Y.`QY#".toCharArray()));
}