带基数的Java数字>;字符最大基数

带基数的Java数字>;字符最大基数,java,tostring,radix,Java,Tostring,Radix,我有一个五个字符的字符串,我想用这五个字符作为ASCII编码(可打印)的数字。实现这一点的最简单方法是使用 Long.toString(number, Character.MAX_RADIX); 这将为我提供从“0”到“zzzzz”的数字。不幸的是Long.toString(int,int)只支持小写字母,不支持大写字母。这意味着最大基数是36,我能编码的最大数字是36^5-1=60466175。如果我能同时使用小写字母和大写字母,我会得到一个最大基数62,最高可编码数字是62^5-1=916

我有一个五个字符的字符串,我想用这五个字符作为ASCII编码(可打印)的数字。实现这一点的最简单方法是使用

Long.toString(number, Character.MAX_RADIX);
这将为我提供从
“0”
“zzzzz”
的数字。不幸的是
Long.toString(int,int)
只支持小写字母,不支持大写字母。这意味着最大基数是
36
,我能编码的最大数字是
36^5-1=60466175
。如果我能同时使用小写字母和大写字母,我会得到一个最大基数
62
,最高可编码数字是
62^5-1=916132831


除了复制
Long
的源代码并扩展可能的数字之外,我还应该研究其他地方吗?首先,这是在什么地方实现的?

如果您愿意使用字母数字以外的两个字符,您可以使用编码

使用from可以得到1073741824个可能的值,如下所示:

byte bytes[] = new byte[4];
bytes[0] = (byte) ((value >> 24) & 0xFF);
bytes[1] = (byte) ((value >> 16) & 0xFF);
bytes[2] = (byte) ((value >> 8) & 0xFF);
bytes[3] = (byte) (value & 0xFF);
String encoded = Base64.encodeBase64String(bytes).substring(1, 6);

您不指定字符是否需要可打印ASCII:

  • 如果有,则可以转到
    95^5
    。从空格(SP)到波浪号(~)有95个可打印的ASCII字符

  • 如果没有,则可以转到
    128^5
    =
    2^35

无论采用哪种方法,转换的算法都很简单,并且比对
Long.toString(…)
的扩展更简单。(您可能不必担心字符映射中的符号、范围错误或漏洞。从头开始编写代码会更容易。)


但是,我不知道任何扩展基数的现有实现。

您可能需要寻找Base64编码器和解码器(例如),它们使用两个额外的符号进行编码。@subsubsub:请参阅WhiteFang的回答好主意。但是尾随的
=
=
不会占用额外的空间吗?除此之外,我没有考虑过,因为转换从<代码>字节[] /代码>到<代码>字符串< /代码>,而不是从<代码>编号<代码>到<代码>字符串< /代码>。但是我可以处理从
Number
byte[]
的额外“编码”您可以通过使用
int
的3个字节来避免后面的
=
。这将为您提供一个偶数24位编码为4个字符。3个字节是不够的:
256^3-1=16 777 215
,这比我原来的解决方案中得到的可编码值要少,不知何故,你的数字的大小没有注册,我盲目地把5个字符变成了4个:)我用一种方法更新了答案,以获得更多。对于4个字节,您可以安全地修剪尾部的
==
。然后还删除第一个字符,即
int
中不适合您的5个字符的位。谢谢您的努力。对我来说,这听起来比复制
Long.toString(int,int)
并在算法中添加两个允许的数字更复杂。:-)此外,我对base64算法的理解还不够透彻,无法确保修剪不会意外地产生“冲突”,即几个数字被编码为相同的值,这对我来说是致命的。它们需要是“可打印的”。我会更新问题的,谢谢。除了
[0-9a-zA-Z]
之外,一些特殊字符也可以(例如
/
-
\uu
等),谢谢您的更新。我知道这很简单。我可以从
java.lang.Long
复制它。我只是想知道我是否忽略了
字符。MAX_RADIX
不是限制。。。