Java:通用 BaseN encoder/decoder 处理大数据
Java: Universal BaseN encoder/decoder working with large data sizes
我正在 Java 中寻找一个不错的 BaseN 编码器(带有自定义字符集),它不受输入数据大小(字节数组)的限制。
像这样:
但对于 "unlimited" 数据长度没有任何不必要的 memory/performance 惩罚和 "BigInteger abuse magic"。只是作为标准 BASE64 编码器工作的东西,但普遍适用于任何 base/charset。欢迎任何解决方案或实现方法的想法。
也许,如果有人有使用 apache BaseNCodec 的经验:
它看起来很有前途,但它是一个抽象 class,并且可用的实现看起来比从头开始更难实现。
我需要它来将二进制数据用于自定义字符集编码器(其中字符集中的字符数是可变的,"ABCDE" = Base5
、"ABCDE-+*/." = Base10
、...)。
更新:
GitHub(上图)中的 "Base N Codec" 似乎有问题,所以我在最后使用了以下代码:
如果 N 是 2 的幂,则基于 N 的编码非常有效,因为这样可以在固定大小的数字组和固定大小的字节之间进行转换。
Base64: 26 - 6 bits per digit, hence 4 digits = 24 bits = 3 bytes.
否则学校乘法必须在整个长度上发生,导致很多"BigInteger"计算。
比起以 N 为基数重复 multiplying/dividing 快一点,就是有一个 N 的幂数组。
对于字节数组到数字的编码,您可以使用 N0, N1, N2, N3, ... 等长字节数组,重复减法
由于 byte
已签名,short
可能更适合。假设数字的最高字节是 98 而次等的 N 次幂是 12 那么大约 7 就是那个数字。
对于将数字解码 为字节数组,可能会使用相同的幂。
玩得开心。
一般答案:否。特殊情况:是,对于基数 2 的幂。
为什么?因为Q里面的想法都在"strong competition"(其实很可能是"contradiction")。
- 作为输入,您希望在某个基数 N 中支持无限整数(将其视为 BigIntegerBaseN)。作为输出,您需要支持某个基数 M 中的无限整数(将其视为 BigIntegerBaseM)。
- 您想进行基数转换 - 这在数学上定义为一系列(乘法和加法)和除法。参见 http://www.cut-the-knot.org/recurrence/conversion.shtml and https://math.stackexchange.com/questions/48968/how-to-change-from-base-n-to-m。
- 您想找到一种无需对 BigIntegers 进行乘法和除法(在任何实现基础上)即可计算此类结果的方法。
你能不进行乘除运算就判断乘除运算的结果吗?不。这是一个矛盾。当你得到结果时,根据定义,你已经进行了计算。
所以这不是你能不能避免计算的问题,而是如何简化它们的问题。
- 如果 N and/or M 是 2 的幂,那么 multiplication/division 可以通过简单的位移计算 = 与主要流线计算相同的计算。这可以通过避免 BigInteger 计算来完成。
- 否则,你可以缓存某些重复的计算,将中间结果存储在数组或HashMap中,然后你得到与精简相同的计算。但是仍然需要 BigInteger 计算(但避免了冗余重复)。
希望对您的方法有所帮助。 :)
您提到了两种截然不同的方法。 Github implementation 中使用的 BaseN 算法是使用整数在基数之间转换的数学符号。这相当于说 10 与 base-8 算术中的 12 或 base-2 算术中的 1010 相同。该算法将字节流解释为一个大数字并转换为指定的基数。
Base64 是一种非常不同的方法,您可以在 Wikipedia Base64 page 中查看示例。该算法基本上将输入流拆分为每个元素的 6 位数组。 2^6 = 64,因此得名 Base64。它有一个 table 和 64 个不同的字符,并将数组(6 位)中的每个元素显示为相应的转换 table.
我认为您需要 select 这两种方法中的一种,因为它们非常不同并且彼此不兼容。至于实现细节,如果选择第二种方法,我认为这会更容易实现,因为你基本上将流分成固定大小的部分并根据你自己的 table.
进行编码。
第一种方法可能会变得非常复杂,因为任意算术运算都依赖于非常复杂的结构。您可以再次查看现有软件@ Wikipedia' s list of arbitrary-precision arithmetic software.
实际上,我认为在某些时候您会发现很难为您的转换获取字符(随着基数增加或位数增加),除非您将使用整个 Unicode 字母表:)。
希望我有所帮助
我正在 Java 中寻找一个不错的 BaseN 编码器(带有自定义字符集),它不受输入数据大小(字节数组)的限制。
像这样:
但对于 "unlimited" 数据长度没有任何不必要的 memory/performance 惩罚和 "BigInteger abuse magic"。只是作为标准 BASE64 编码器工作的东西,但普遍适用于任何 base/charset。欢迎任何解决方案或实现方法的想法。
也许,如果有人有使用 apache BaseNCodec 的经验:
它看起来很有前途,但它是一个抽象 class,并且可用的实现看起来比从头开始更难实现。
我需要它来将二进制数据用于自定义字符集编码器(其中字符集中的字符数是可变的,
"ABCDE" = Base5
、"ABCDE-+*/." = Base10
、...)。
更新: GitHub(上图)中的 "Base N Codec" 似乎有问题,所以我在最后使用了以下代码:
如果 N 是 2 的幂,则基于 N 的编码非常有效,因为这样可以在固定大小的数字组和固定大小的字节之间进行转换。
Base64: 26 - 6 bits per digit, hence 4 digits = 24 bits = 3 bytes.
否则学校乘法必须在整个长度上发生,导致很多"BigInteger"计算。
比起以 N 为基数重复 multiplying/dividing 快一点,就是有一个 N 的幂数组。
对于字节数组到数字的编码,您可以使用 N0, N1, N2, N3, ... 等长字节数组,重复减法
由于 byte
已签名,short
可能更适合。假设数字的最高字节是 98 而次等的 N 次幂是 12 那么大约 7 就是那个数字。
对于将数字解码 为字节数组,可能会使用相同的幂。
玩得开心。
一般答案:否。特殊情况:是,对于基数 2 的幂。
为什么?因为Q里面的想法都在"strong competition"(其实很可能是"contradiction")。
- 作为输入,您希望在某个基数 N 中支持无限整数(将其视为 BigIntegerBaseN)。作为输出,您需要支持某个基数 M 中的无限整数(将其视为 BigIntegerBaseM)。
- 您想进行基数转换 - 这在数学上定义为一系列(乘法和加法)和除法。参见 http://www.cut-the-knot.org/recurrence/conversion.shtml and https://math.stackexchange.com/questions/48968/how-to-change-from-base-n-to-m。
- 您想找到一种无需对 BigIntegers 进行乘法和除法(在任何实现基础上)即可计算此类结果的方法。
你能不进行乘除运算就判断乘除运算的结果吗?不。这是一个矛盾。当你得到结果时,根据定义,你已经进行了计算。
所以这不是你能不能避免计算的问题,而是如何简化它们的问题。
- 如果 N and/or M 是 2 的幂,那么 multiplication/division 可以通过简单的位移计算 = 与主要流线计算相同的计算。这可以通过避免 BigInteger 计算来完成。
- 否则,你可以缓存某些重复的计算,将中间结果存储在数组或HashMap中,然后你得到与精简相同的计算。但是仍然需要 BigInteger 计算(但避免了冗余重复)。
希望对您的方法有所帮助。 :)
您提到了两种截然不同的方法。 Github implementation 中使用的 BaseN 算法是使用整数在基数之间转换的数学符号。这相当于说 10 与 base-8 算术中的 12 或 base-2 算术中的 1010 相同。该算法将字节流解释为一个大数字并转换为指定的基数。
Base64 是一种非常不同的方法,您可以在 Wikipedia Base64 page 中查看示例。该算法基本上将输入流拆分为每个元素的 6 位数组。 2^6 = 64,因此得名 Base64。它有一个 table 和 64 个不同的字符,并将数组(6 位)中的每个元素显示为相应的转换 table.
我认为您需要 select 这两种方法中的一种,因为它们非常不同并且彼此不兼容。至于实现细节,如果选择第二种方法,我认为这会更容易实现,因为你基本上将流分成固定大小的部分并根据你自己的 table.
进行编码。第一种方法可能会变得非常复杂,因为任意算术运算都依赖于非常复杂的结构。您可以再次查看现有软件@ Wikipedia' s list of arbitrary-precision arithmetic software.
实际上,我认为在某些时候您会发现很难为您的转换获取字符(随着基数增加或位数增加),除非您将使用整个 Unicode 字母表:)。
希望我有所帮助