【问题标题】:how to get back the compressed string back from uncompressed string using zlib python?如何使用zlib python从未压缩的字符串中取回压缩字符串?
【发布时间】:2020-11-24 10:34:50
【问题描述】:

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

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

上述代码sn-p的输出为: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));
    }
}

【问题讨论】:

  • 您的代码在我这边返回 s h a n t h ac.decode("utf-16") 但返回 shantha
  • 我很难尝试将字符串编码回正确的压缩格式。您自己没有创建压缩字符串的代码吗?
  • 我有。但它是在 C# 中。
  • 张贴。如果代码是链接的,您可以在同一个问题中询问两种语言,就像这样。
  • @Hampus Laarsson - 已发布!

标签: c# python-3.x zlib


【解决方案1】:

这不是“shantha”。 Base-64 编码的 zlib 流解码为b"s\0h\0a\0n\0t\0h\0a\0"。有一堆空值散布在打印时不显示的字符。 (根据 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 标头可能会略有不同,就像这里一样,取决于您运行的操作系统和压缩级别。同样对于较大的输入和其他压缩级别或软件版本,压缩数据也可能会有所不同。但这没关系。重要的是你在解压时能取回原始数据。

【讨论】:

  • 16 + zlib.MAX_WBITS 不是已经 31 了吗?此外,“空值”在那里是因为它是一个utf-16le 字符串,而不是他试图将其解码为的“utf-8”。
  • 是的,但这是在他们的 decompression 示例中,有趣的是甚至不需要它。 (decompress 将检测 gzip 格式并在没有该选项的情况下将其解压缩。)如果他们想制作这样的压缩流,他们需要使用31(或16 + zlib.MAX_WBITS)。但是,Python 中的compress 没有该选项! (不知道为什么不。)所以他们必须使用答案中提到的compressobj 接口。
  • 啊,我不明白为什么里面有那么多空值。谢谢。
  • @MarkAdler - 请在此处添加 wbits=31 的 zlib.compressobj 示例以生成 zlib 格式?
  • 使用 gzip,我们应该能够找回这个字符串,对吧? - “H4sIAAAAAAAEActmyGBIZMhjKAHTALXiaIAOAAAA”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多