如何使用 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.compressobj
和 wbits=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 可能会略有不同,正如此处所示,这取决于您 运行 使用的操作系统以及压缩级别。同样对于更大的输入和其他压缩级别或软件版本,压缩数据也可能有所不同。但这没关系。重要的是当你解压时你会得到原始数据。
我有一个由 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.compressobj
和 wbits=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 可能会略有不同,正如此处所示,这取决于您 运行 使用的操作系统以及压缩级别。同样对于更大的输入和其他压缩级别或软件版本,压缩数据也可能有所不同。但这没关系。重要的是当你解压时你会得到原始数据。