是否有比DotNetZip或LZMA更好的字符串压缩库?

时间:2011-08-20 06:05:25

标签: vb.net compression

我有一个超过800个字符的数据字符串,我正在尝试压缩以用于QR码(我想要至少50%,但如果我把它减少到少于50%可能会很高兴七百)。这是我正在尝试压缩的示例字符串,包含841个字符:

+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

我已经尝试了以下三个库:

  1. 内置的.NET GzipStream
  2. DotNetZip,包括,
    • GzipStream
    • DeflateStream
  3. 7-zip
  4. 的LZMA SDK

    我遇到的问题是压缩实际上使字符串更长。我的理解是DeflateStream的开销最小,但它仍在添加字符。使用DotNetZip,我告诉它使用最大压缩:

    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
    

    我只是认为这会变得更糟,因为我甚至会有更多的数据。对于这个长度的字符串,是否有更好的压缩算法?压缩通常只适用于较长的字符串吗?不幸的是,数据是这样的,我不能使用替代字符来存储数据。

    另外,我是否可以使用字母数字编码进行QR码,还是必须使用二进制代码?我不认为我可以,http://www.qrme.co.uk/qr-code-forum.html?func=view&catid=3&id=324,但我想确定。

    感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

这个答案与Guffa的回答有关。他说QR码可以接受二进制数据,它必须是你正在使用的库的限制。

我查看了库的源代码。你调用编码功能吗?这是编码函数的内容

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)”

答案 1 :(得分:3)

乍一看,您似乎正在尝试使用此过程获取一些数据并将其转换为QR代码:

- &GT;加密 - &gt; base64编码 - &gt;压缩 - &gt;制作二维码。

我建议改用这个过程:

- &GT;压缩 - &gt;加密 - &gt;制作二维码。

当你想要加密和压缩时,几乎每个人都建议压缩然后加密。 (因为加密与压缩数据一样,与未压缩数据一样。 但压缩通常会使明文更短,加密文件更长。 有关详细信息,请参阅: “Can I compress an encrypted file?” “Compress and then encrypt, or vice-versa?” “Composing Compression and Encryption” “Compress, then encrypt tapes” “Is it better to encrypt a message and then compress it or the other way around? Which provides more security?” “Compressing and Encrypting files on Windows” “Encryption and Compression” “Do encrypted compression containers like zip and 7z compress or encrypt first?” “When compressing and encrypting, should I compress first, or encrypt first?”, 等)

“我能为QR码使用字母数字编码,还是必须使用二进制代码?”

大多数加密算法都会生成二进制输出,因此将其直接转换为二进制编码的QR码最为简单。 我想你可以以某种方式将加密数据转换成QR字母数字编码可以处理的东西,但为什么呢?

“是否有更好的压缩算法”

对于加密数据,不可以。无论您使用何种算法,都可以(几乎可以肯定)压缩加密良好的数据。

如果你按照建议进行压缩然后加密,那么各种压缩算法的有效性取决于特定类型的输入数据,而不是你在压缩后用它做什么。

您的输入数据是什么类型的数据?

假设您的输入数据缺少ASCII文本, 也许你可以使用其中提到的压缩算法之一 “Really simple short string compression” “Best compression algorithm for short text strings” “Compression of ASCII strings in C” “Twitter text compression challenge”。

另一方面,如果您的输入数据是某种照片, 也许您可以使用“Twitter image encoding challenge”中提到的众多压缩算法之一。

答案 2 :(得分:2)

压缩的工作原理是删除数据中的冗余,但字符串似乎包含随机/加密数据,因此无需删除冗余。

但是,它的数据使用base-64编码,因此每个字符只携带6位信息。如果保留二进制数据而不是base-64编码,则只有631个字节。

答案 3 :(得分:2)

您正在比较不同的压缩机。 Zip系列通常使用统计压缩,LZ系列是Lempel-Ziv的首字母缩写,是一种字典压缩,用于删除输入文本中的冗余。因此,压缩通过删除超级信息来工作。它适用于文本文件和图像,在音频,视频和程序文件方面效果不佳。对于后者,存在有损压缩但不适用于程序文件。给定您的示例字符串,它包含太多的熵以便很好地压缩。您可以使用-log(p)+ log(2)计算信息熵,其中p是文本中出现的字符的概率。另见信息理论和shannon定理。