繁体   English   中英

Java:适用于大数据量的通用BaseN编码器/解码器

[英]Java: Universal BaseN encoder/decoder working with large data sizes

我正在寻找Java中不错的BaseN编码器(具有自定义字符集),该编码器不受输入数据大小(字节数组)的限制。

像这样:

https://github.com/mklemm/base-n-codec-java

但是对于“无限”的数据长度,没有任何不必要的内存/性能损失和“ BigInteger滥用魔术”。 可以简单地用作标准BASE64编码器的东西,但通常适用于任何基本/字符集。 任何解决方案或想法如何实现都受到欢迎。

也许,如果有人有使用Apache BaseNCodec的经验:

https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/BaseNCodec.html

它看起来很有希望,但是它是一个Abstract类,可用的实现看起来比从头开始要难。


我需要它来将二进制数据转换为自定义字符集编码器(其中字符集中的字符数是可变的, "ABCDE" = Base5 "ABCDE-+*/." = Base10"ABCDE-+*/." = Base10 ,...)。
更新: GitHub上的“ Base N Codec”(上面)似乎有问题,因此我在最后使用了以下代码:

https://dzone.com/articles/base-x-encoding

如果N为2的幂,则基本N编码非常有效,因为这样可以在固定大小的数字组和固定大小的字节之间进行转换。

BASE64:2 6 -每位6个比特,因此4位= 24个比特= 3个字节。

否则,必须在整个长度上进行学校乘法,从而导致大量的“ BigInteger”计算。

具有N的幂的数组而不是例如被基数N重复乘/除的更快。

为了字节数组编码为数字,可以使用N 0 ,N 1 ,N 2 ,N 3 ,...作为长度较小或相等的字节数组,并进行重复减法。

由于byte是有符号的,所以short可能更适合。 假设数字的最高字节为98,而N的次幂不等于12,则该数字约为7。

为了将数字解码为字节数组,可以使用相同的幂。

玩得开心。

一般回答:否。特殊情况:是,以2的幂为底。

为什么? 因为Q中的想法处于“激烈竞争”(实际上可能是“矛盾”)中。

  1. 作为输入,您希望在某个基数N中支持一个无限的整数(可以将其视为BigIntegerBaseN)。 作为输出,您希望在某个基数M中支持一个无限整数(可以将其视为BigIntegerBaseM)。
  2. 您要执行基本转换-在数学上定义为一系列(乘法和加法)和除法。 参见http://www.cut-the-knot.org/recurrence/conversion.shtmlhttps://math.stackexchange.com/questions/48968/how-to-change-from-base-n-to-m
  3. 您想找到一种无需在BigIntegers上进行乘法和除法(在任何实现的基础上)而计算此类结果的方法。

您可以在不执行乘法和除法计算的情况下确定乘法和除法运算的结果吗? 没有。 这是一个矛盾。 根据定义,当您获得结果时,便已经进行了计算。

因此,这不是可以避免计算的问题,而是如何简化计算的问题。

  • 如果N和/或M的底数为2的幂,则可以通过简单的移位=相同的计算和主要的流水线来计算乘法/除法。 可以避免BigInteger计算。
  • 否则,您可以缓存某些重复的计算,将临时结果存储在数组或HashMap中,然后通过精简获得相同的计算。 但是仍然需要BigInteger计算(但是避免重复)。

希望对您有所帮助。 :)

您提到了两种截然不同的方法。 Github实现中使用的BaseN算法使用的数学符号是在基数之间转换整数。 这等效于说10与以8为基数的算术中的12或以10为基数2的算术中的1010相同。 该算法将字节流解释为一个大数字,然后转换为指定的基数。

Base64是一种非常不同的方法,您可以在Wikipedia Base64页面上看到一个示例。 该算法基本上将输入流分成每个元素6位的数组。 2 ^ 6 = 64,因此名称为Base64。 它具有包含64个不同字符的表,并将数组(6位)中的每个元素显示到相应的转换表中。

我认为您需要选择两种方法之一,因为它们非常不同并且彼此不兼容。 至于实现细节,我认为如果选择第二种方法,这将更容易实现,因为您基本上将流分割成固定大小的部分,并根据自己的表对其进行编码。

第一种方法可能会变得非常复杂,因为任意算术运算都依赖于非常复杂的结构。 您可以看看现有的软件,再看看Wikipedia的任意精度算术软件列表

实际上,我认为您有时会很难获得转换字符(随着基数的增加或位数的增加),除非您要使用整个Unicode字母:)。

希望我能有所帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM