0

我需要将20-40字符大小的数字压缩为6字符大小的数字。到目前为止,我已经尝试了Huffman和一些Zip算法,但没有得到想要的结果。

有人可以为 Java 中的这项工作提供任何其他算法/API 建议吗?

例子:

Input: 98765432101234567890
Desired Output: 123456

请注意:我并不是说给定输入的输出必须为 12345。我的意思是,如果我指定 20 字节的数字,它应该被压缩为 6 字节的数字。

用法:压缩后的数字将被提供给设备(最多只能占用 6 个数字字符)。设备会将号码解码回原始号码。

假设/限制:

  1. 如果需要,客户端和设备(服务器)都可以共享编码/解码数字所需的一些通用属性。

  2. 只能向设备发出一个请求,即所有数据都应在一个请求中提供,没有小数据包块

谢谢。

4

2 回答 2

7

假设任何数字组合都是合法输入,这将是您可以获得的最佳结果:

final String s = "98765432101234567890";
for (byte b : new BigInteger('0'+s).toByteArray()) 
  System.out.format("%02x ", b & 0xff);

印刷

05 5a a5 4d 36 e2 0c 6a d2

以二进制形式存储一个数字在理论上是最有效的方式,因为每个位组合都是一个不同的合法值。

只有当您的输入中有更多冗余时,您才可能有其他选择,即对合法数字组合有一些限制。

于 2012-06-25T10:40:20.657 回答
2

按照您指定的方式,这是不可能的。20 位数字比 6 位数字多,所以如果将 20 位数字映射到只有 6 位数字,则必须将一些 20 位数字映射到相同的 6 位数字。如果您知道并非所有数字都有效甚至具有相同的可能性,则可以将其用于压缩,否则这是不可能的。

尽管从 20 位数字到 6 位数字的可逆(双射)映射是不可能的,但仍然可以将长数字映射到较短的输出。这通过减少输出需要是数字的要求来起作用。唯一重要的考虑是输出序列需要与输入具有相同数量的可能性。这是一个例子:

  • 有 10^20 个可能的 20 位数字
  • 如果您使用长度为 x 的完整 8 位 ASCII(256 个字符)序列,您将有 256^x 个可能的输出。如果你为 x 解决这个问题,你会注意到 256^9 > 10^20 所以 9 个 ASCII 字符足以编码 20^10 个可能的数字输入。

Marko 对同一问题的回答将告诉您如何将数字转换为可用作输入的字节表示。但请注意,此输入不会是数字,并且可能包含许多奇怪的符号。

于 2012-06-25T10:58:06.783 回答