Is there a better compression library for strings than DotNetZip or LZMA?
我有一个超过800个字符的数据串,我正试图压缩下来用于一个二维码(我希望至少50%,但如果我得到的数据少于700个,可能会很高兴)。下面是我要压缩的一个示例字符串,包含841个字符:
1 2 3 4 5 6 7 8 9 10 11 12 | +hgoSuJm2ecydQj9mXXzmG6b951L2KIl0k9VGzIEtLztuWO2On9rt7DUlH0lXzG4iJ1yK0fA 97mDyclKSttIZXOxSPBf85LEN4PUUqj65aio5qwZttZSZ64wpnMFg/7Alt1R39IJvTmeYfBm Tuc1noMMcknlydFocwI8/sk2Sje5MR/nYNX0LPkQhzyi5vFJdrndqAgXYULsYrB3TJDAwvgs Kw9C5EJnrlqcb21zg17O2gU/C8KY0pz9RPzUl1Sb0rCP8iZCeis4YbQ5tuUppOfnO/X0Mosv SOQJ/bF9juKW8ocnQvNjsNxGV1gPkWWtiU2Old7Qm7FLDqL6kQKrq356yifs0NiMVGdvAg32 eugewuttCugoZASYOpQdwPu1jMxVO1fzF3zEy5w6tDlcfA2DZwa+un9/k8XZWAO/KVExy68q UtVRQxsIOKgpl/2tNw5DBAKbykKIkmizbsA2xtzqnYqld4kOdNMJh3YjlqWF9Bt8MZo7a+Q6 jgayr2rjpyIptc599DGtvp68ZNQ64TKNmiMnnyGMo3E+xW34G3RrsYnHGm+xJoLKoOJhacDu oZke1ycJgQv+Y61WPrvtFOVBxV5rvSzO0+8px5AWN3uCrrw1RmT5N14IVhh6BOtRjsifqIB2 dAKxzBNsvbXm1SzkuyqYiMnp5ivy3m2mPwc9GLsykx0FRIkhCYO8ins9E5ot9QvVnE155MFA 8FVwsP5uNdOF4EzQS2/h2QK3zb5Yq4Nftlo605Dd5vuVN/A7CUN38DaAKBxDKgqDzydfQnZw R0hTfMHNLgBJKNDSpz2P6almGlUJtXT6IYmzuU2Iaion8ePG |
我已经尝试了以下三个库:
- GZIPFISH
- 排水井
我遇到了一个问题,压缩实际上会使字符串变长。我的理解是deflatestream的开销最小,但它仍然在添加字符。使用dotnetzp,我告诉它使用最大压缩:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Imports Ionic.Zlib Shared Function CompressData(data As Byte()) As Array Dim msCompressed As MemoryStream = New MemoryStream ' I'm not sure if the last parameter on this next function should be ' true (for LeaveOpen), but it doesn't seem to affect it either way. Dim deflated As DeflateStream = New DeflateStream(msCompressed, _ CompressionMode.Compress, CompressionLevel.BestCompression, True) ' Write data to compression stream (which is linked to the memorystream) deflated.Write(data, 0, data.Length) deflated.Flush() deflated.Close() Return msCompressed.ToArray End Function |
我只是想这会变得更糟,因为我会有更多的数据。对于这种长度的字符串,是否有更好的压缩算法?压缩通常只在较长的字符串上工作吗?不幸的是,数据如此之大,我无法使用数据块的代表字符。
此外,我是否可以使用字母数字编码的二维码,还是我必须使用二进制?我不认为我能,根据http://www.qrme.co.uk/qr-code-forum.html?func=view&catid=3&i d=324,但我想确定一下。
谢谢你的帮助!
乍一看,您似乎正在尝试获取一些数据并通过此过程将其转换为二维码:
-->encrypt->base64 encode->compress->生成二维码。
我建议使用此过程:
-->compress(压缩)->encrypt(加密)->生成二维码。
当您同时想要加密和压缩时,几乎所有人都建议先压缩再加密。(因为加密对压缩数据和未压缩数据的效果一样好。但是压缩通常会使明文更短,加密文件更长。有关详细信息,请参阅:"我可以压缩加密文件吗?"压缩然后加密,或者相反?"组成压缩和加密"压缩,然后加密磁带"加密一条消息然后压缩它,还是用另一种方式来压缩它?哪一个更安全?""压缩和加密Windows上的文件""加密和压缩""加密的压缩容器(如zip和7z)是先压缩还是先加密?""压缩和加密时,应该先压缩还是先加密?",等)
"我是否可以使用字母数字编码的二维码,还是必须使用二进制码?"
大多数加密算法产生二进制输出,因此直接将其转换为二进制编码的二维码是最简单的。我想你可以把加密的数据转换成二维字母数字编码可以处理的东西,但是为什么呢?
"有更好的压缩算法吗?"
对于加密的数据,不可能(几乎可以肯定)压缩好的加密数据,不管使用什么算法。
如果按照建议压缩然后加密,那么各种压缩算法的有效性取决于特定类型的输入数据,而不是取决于压缩后如何处理它。
您的输入数据是什么类型的数据?
假设您的输入数据缺少ASCII文本,也许您可以使用上面提到的压缩算法之一"非常简单的短字符串压缩""短文本字符串的最佳压缩算法""压缩C中的ASCII字符串""Twitter文本压缩挑战"。
另一方面,如果你输入的数据是某种照片,也许您可以使用"Twitter图像编码挑战"中提到的众多压缩算法之一。
这个答案与盖法的答案有关。他说二维码可以接受二进制数据,这一定是您所使用的库的限制。
我看了图书馆的源代码。你调用编码函数对吗?这是编码函数的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public virtual Bitmap Encode(String content, Encoding encoding) { bool[][] matrix = calQrcode(encoding.GetBytes(content)); SolidBrush brush = new SolidBrush(qrCodeBackgroundColor); Bitmap image = new Bitmap( (matrix.Length * qrCodeScale) + 1, (matrix.Length * qrCodeScale) + 1); Graphics g = Graphics.FromImage(image); g.FillRectangle(brush, new Rectangle(0, 0, image.Width, image.Height)); brush.Color = qrCodeForegroundColor ; for (int i = 0; i < matrix.Length; i++) { for (int j = 0; j < matrix.Length; j++) { if (matrix[j][i]) { g.FillRectangle(brush, j * qrCodeScale, i * qrCodeScale, qrCodeScale, qrCodeScale); } } } return image; } |
第一行(encoding.getbytes(content))将字符串转换为字节。
获取源代码,然后将其修改为具有以下函数:"public virtual bitmap encode(bytes[]content)"。
您正在比较不同的压缩机。Zip族通常使用统计压缩,LZ族Lempel-Ziv的缩写词是字典压缩,用于消除输入文本中的冗余。因此,压缩通过删除多余的信息来工作。它适用于文本文件和图像,而不适用于音频、视频和程序文件。对于后者,存在有损压缩,但不适用于程序文件。以您的示例字符串为例,它包含的熵太多,无法很好地压缩。您可以使用-log(p)+log(2)计算信息熵,其中p是文本中出现字符的概率。另见信息论和香农定理。
压缩通过删除数据中的冗余来工作,但字符串似乎包含随机/加密数据,因此没有要删除的冗余。
但是,它的数据是使用base-64编码的,因此每个字符只携带6位信息。如果保留二进制数据而不是对其进行base-64编码,那么它只有631字节。