可能重复:
将 21 个字母数字字符压缩为 16 个字节
我有8个号码
有没有办法将其转换为长度为 4 的字符串?
例如:
输入12345678
输出AB2D
转换应该能够完全转换回来。
我试图将它转换为 32 Hex,但它仍然有 5 个数字,我不能0
1
O
I
在最终字符串中使用。有什么好的建议吗?顺便说一句,只能使用大写字母。
可能重复:
将 21 个字母数字字符压缩为 16 个字节
我有8个号码
有没有办法将其转换为长度为 4 的字符串?
例如:
输入12345678
输出AB2D
转换应该能够完全转换回来。
我试图将它转换为 32 Hex,但它仍然有 5 个数字,我不能0
1
O
I
在最终字符串中使用。有什么好的建议吗?顺便说一句,只能使用大写字母。
它归结为数学。如果您需要能够表示 10^8 个可能的数字并且需要使用 4 个符号,则每个符号必须允许 100 个不同的值。10^8^(1/4)
您可以使用 8 位字节执行此操作,但您的要求only upper case letters could be used.
表明您的选择非常有限。您必须确定可以使用的 100 个字母,或者您必须对可以使用的数字范围做出假设。
顺便说一句:如果您可以使用非 ASCII 大写字符,则没有问题。;)
有 26 个大写 ASCII 字符,30 个介于 128 和 255 之间的大写字符以及 10 个数字,因此您也必须使用 34 个符号。如果可以使用 Unicode,则有 1898 个大写和数字 Unicode 字符。
(char) 32
和之间有 163 个非小写字符(char) 255
,如果你能使用其中的大部分,你就可以做到。
手工挑选的可能字符列表将是更好的选择,但这是一个示例。
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);
}
使用此字体不可打印的字符打印:(
Encoded: -CY
Dencoded: 12345678
不,八位数字代表太多的组合。每个十进制数字都必须用单个符号表示,才能使整数成为长度为 4 的字符串。这意味着您需要使用 100 个符号。正如您所说,十六进制没有足够的字符,尽管它比十进制多。如果您不能使用小写字母,我假设也不允许使用标点符号。在这种情况下,您将没有足够的符号。