关于vb.net:有没有比DotNetZip或LZMA更好的字符串压缩库?

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

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

  • 内置.NET gzipstream
  • dotnetzp,包括,
    • GZIPFISH
    • 排水井
  • 来自7-zip的LZMA SDK
  • 我遇到了一个问题,压缩实际上会使字符串变长。我的理解是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字节。