5

我将使用一种算法对从 XML 文件中检索到的可变长度但非常长的字符串字段进行编码,然后该编码数据应保存在数据库中。

稍后,当我收到第二个文件时,我需要从数据库(以前存储的)中获取编码数据,然后对其进行解码并使用新数据进行验证以进行重复。

我试过org.apache.commons.codec.binary.Base64类它有2种方法:

  1. encodeBase64(Byte[] barray)
  2. decodeBase64(String str)

它工作得很好,解决了我的问题。但它将 55 个字符字符串转换为 6 个字符字符串。

所以我想知道这些算法是否会在任何情况下将 2 个非常大且只有 1 个字符不匹配(例如)的字符串编码到相同的编码字节数组中。

我不太了解这Base64门课,但如果有人可以帮助我,那将非常有帮助。

如果您可以建议任何其他使大字符串短于固定长度并解决我的目的的算法,我将很乐意使用它。

提前致谢。

4

2 回答 2

13

效率不是很高。

此外,使用sun.misc类提供了一个不可移植的应用程序。

查看MiGBase64的以下性能比较:

在此处输入图像描述


所以我想知道这些算法是否会在任何情况下将 2 个非常大且只有 1 个字符不匹配(例如)的字符串编码到相同的编码字节数组中。

Base64 不是散列算法,它是一种编码,因此必须是双向的。必要时不能允许碰撞 - 否则解码将是不确定的。Base64 旨在表示 ASCII 字符串中的任意二进制数据。将 Unicode 字符串编码为 Base64 通常会增加所需的代码点数,因为 Unicode 字符集需要多个字节。Unicode 字符串的 Base64 表示将根据使用的编码(UTF-8、UTF-16)而有所不同。例如:

Base64( UTF8( "test" ) ) => "dGVzdA=="
Base64( UTF16( "test" ) ) => "/v8AdABlAHMAdA=="

解决方案 1

使用无损压缩

GZip( UTF8( "test" ) )

在这里,您将字符串转换为字节数组并使用无损压缩来减少您必须存储的字节数。您可以根据要存储的字符串改变字符编码和压缩算法以减少字节数(即,如果它主要是 ASCII,那么 UTF-8 可能是最好的。

优点:没有冲突,能够恢复原始字符串
缺点:存储值所需的字节数是可变的;存储值所需的字节数更大

解决方案 2

使用散列算法

SHA256( UTF8( "test" ) )

在这里,您使用散列函数将字符串转换为固定长度的字节集。散列是单向的,就其本质而言,冲突是可能的。但是,根据您希望处理的字符串的配置文件和数量,您可以选择一个哈希函数来最大程度地减少冲突的可能性

优点:存储值所需的字节数是固定的;存储值所需的字节很小
缺点:可能发生冲突,无法恢复原始字符串

于 2011-06-15T10:01:38.850 回答
1

我刚刚看到您的评论-您似乎实际上是在寻找压缩而不是像我最初想的那样进行散列。虽然在那种情况下,您将无法获得任意输入的固定长度输出(想想看,无限数量的输入不能双射映射到有限数量的输出),所以我希望这不是一个强烈的要求.

在任何情况下,您选择的压缩算法的性能将取决于输入文本的特征。在没有进一步信息的情况下,DEFLATE 压缩(Zip 输入流使用,IIRC)是一个很好的通用算法,至少可以用作比较的基础。不过,为了便于实施,您可以使用JDK 中内置的Deflator类,该类使用 ZLib 压缩。

如果您的输入字符串具有特定的模式,那么不同的压缩算法可能或多或少有效。在一方面,你使用哪一个并不重要,如果你不打算让任何其他进程读取压缩数据 - 只要你可以自己压缩和解压缩,它对你的客户是透明的。

这些其他问题可能很有趣:

于 2011-06-15T10:02:51.643 回答