It comes down to maths. If you need to be able to represent 10^8 possible numbers and you need to use 4 symbols, each symbol must allow 100 different values. 10^8^(1/4)
You can do this using an 8-bit byte but your requirement of only upper case letters could be used.
suggests your options are rather limited. You have to determine 100 letters you can use or you have to make assumptions about the range of numbers you can have.
BTW: If you can use non-ASCII upper case characters you don't have a problem. ;)
There are 26 upper case ASCII characters, 30 upper case characters between 128 and 255 and 10 digits so you would have to use 34 symbols as well. If you can use Unicode, there are 1898 upper-case and digit Unicode characters.
There is 163 non lower-case characters between (char) 32
and (char) 255
and if you can use most of these you can do it.
A hand picked list of possible characters will be a better choice but this is an example.
static final char[] ENCODE = new char[100];
static {
int x = 0;
for (char i = ' ' + 1; i < 256 && x < 100; i++)
if (!Character.isLowerCase(i) && !Character.isWhitespace(i))
ENCODE[x++] = i;
assert x == ENCODE.length;
}
public static char[] encode(int n) {
assert n >= 0 && n < 100000000;
char[] ret = new char[4];
for (int i = ret.length - 1; i >= 0; i--) {
ret[i] = ENCODE[n % 100];
n /= 100;
}
return ret;
}
public static int decode(char[] chars) {
int n = 0;
for (char ch : chars) {
int x = Arrays.binarySearch(ENCODE, ch);
assert x >= 0;
n = n * 100 + x;
}
return n;
}
public static void main(String... args) {
char[] chars = encode(12345678);
System.out.println("Encoded: " + new String(chars));
int n = decode(chars);
System.out.println("Dencoded: " + n);
}
prints using a character which is non-printable in this font :(
Encoded: -CY
Dencoded: 12345678