如何使用 zlib python 从未压缩的字符串中取回压缩的字符串?

how to get back the compressed string back from uncompressed string using zlib python?

我有一个由 C# 代码生成的压缩字符串 "H4sIAAAAAAAEACtmyGBIZMhjKAHTALXiaIAOAAAA"。我尝试使用 zlib 解压缩相同的内容,如下所示:

c = zlib.decompress(base64.b64decode("H4sIAAAAAAAEACtmyGBIZMhjKAHTALXiaIAOAAAA"), 16 + zlib.MAX_WBITS)
print(c)
print(c.decode('utf-8'))

以上代码片段的输出是:shantha

现在,如何使用 zlib 从原始字符串 "shantha" 中取回压缩字符串 "H4sIAAAAAAAEACtmyGBIZMhjKAHTALXiaIAOAAAA"

编辑: 创建压缩字符串的 C# 代码:

using System.IO;
using System;
using System.IO.Compression;
using System.Text;

public class Program
{
    public static void Main(string[] args)
    {

        string plainText = "shantha";
        byte[] buffer = Encoding.UTF8.GetBytes(plainText);  
        var memoryStream = new MemoryStream();

        using (var gZipStream = new GZipStream(memoryStream, compressionMode.Compress, true))
        {
            gZipStream.Write(buffer, 0, buffer.Length);
        }
        memoryStream.Position = 0;
        var compressedData = new byte[memoryStream.Length];
        memoryStream.Read(compressedData, 0, compressedData.Length);
        var gZipBuffer = new byte[compressedData.Length];
        Buffer.BlockCopy(compressedData, 0, gZipBuffer, 0, compressedData.Length);
        Console.WriteLine(Convert.ToBase64String(gZipBuffer));
    }
}

这不是“shantha”。 Base-64 编码的 zlib 流解码为 b"s[=11=]h[=11=]a[=11=]n[=11=]t[=11=]h[=11=]a[=11=]"。有一堆空值散布在打印时不显示的字符中。 (根据 Hampus 的评论,这可能是由于在压缩之前将字符串编码为 UTF-16。)

您的原始字符串是 gzip 编码的,而不是 zlib。所以你需要使用 zlib.compressobjwbits=31 来生成 zlib 格式。示例,包括编码为 UTF-16,little-endian,键入交互式 Python:

>>> import zlib
>>> import base64
>>> s = "shantha".encode('utf-16le')
>>> z = zlib.compressobj(wbits=31)
>>> c = z.compress(s)
>>> c += z.flush(zlib.Z_FINISH)
>>> base64.b64encode(c)
b'H4sIAAAAAAAAEytmyGBIZMhjKAHTALXiaIAOAAAA'

生成的 gzip header 可能会略有不同,正如此处所示,这取决于您 运行 使用的操作系统以及压缩级别。同样对于更大的输入和其他压缩级别或软件版本,压缩数据也可能有所不同。但这没关系。重要的是当你解压时你会得到原始数据。