我试图用python压缩字符串,就像一个特定的C#代码,但得到的结果不同。似乎我必须向压缩结果添加一个头,但我不知道如何在python中向压缩字符串添加头。这是C#行,我不知道在python中会是什么:
memoryStream.Read(compressedBytes, CompressedMessageHeaderLength, (int)memoryStream.Length);
这是整个可运行的C代码
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
namespace Rextester
{
/// <summary>Handles compressing and decompressing API requests and responses.</summary>
public class Compression
{
#region Member Variables
/// <summary>The compressed message header length.</summary>
private const int CompressedMessageHeaderLength = 4;
#endregion
#region Methods
/// <summary>Compresses the XML string.</summary>
/// <param name="documentToCompress">The XML string to compress.</param>
public static string CompressData(string data)
{
using (MemoryStream memoryStream = new MemoryStream())
{
byte[] plainBytes = Encoding.UTF8.GetBytes(data);
using (GZipStream zipStream = new GZipStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
{
zipStream.Write(plainBytes, 0, plainBytes.Length);
}
memoryStream.Position = 0;
byte[] compressedBytes = new byte[memoryStream.Length + CompressedMessageHeaderLength];
Buffer.BlockCopy(
BitConverter.GetBytes(plainBytes.Length),
0,
compressedBytes,
0,
CompressedMessageHeaderLength
);
// Add the header, which is the length of the compressed message.
memoryStream.Read(compressedBytes, CompressedMessageHeaderLength, (int)memoryStream.Length);
string compressedXml = Convert.ToBase64String(compressedBytes);
return compressedXml;
}
}
#endregion
}
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
string data = "Hello World!";
Console.WriteLine( Compression.CompressData(data) );
// result would be DAAAAB+LCAAAAAAABADzSM3JyVcIzy/KSVEEAKMcKRwMAAAA
}
}
}
这是我写的Python代码:
data = 'Hello World!'
import gzip
import base64
print(base64.b64encode(gzip.compress(data.encode('utf-8'))))
# I expect DAAAAB+LCAAAAAAABADzSM3JyVcIzy/KSVEEAKMcKRwMAAAA
# but I get H4sIACwuuWAC//NIzcnJVwjPL8pJUQQAoxwpHAwAAAA=
正如其他人所提到的,在c#版本中添加该标题是一个不同的事实
同样,请注意,gzip过程可以通过多种方式完成。例如,在C#中,可以指定
CompressionLevel
的Optimal
、Fastest
或NoCompression
。见:https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.compressionlevel?view=net-5.0我对Python还不太熟悉,无法说明默认情况下它将如何处理gzip压缩(也许C#中的
Fastest
提供了比Python更具攻击性的算法)这是您的C#代码,标题值设置为“0”,并使用3
CompressionLevels
进行输出。请注意,它输出的字符串值“非常接近”Python中的值您还应该问,值的不同是否真的很重要。只要你能编解码就够了吗
输出:
及在:https://dotnetfiddle.net/TI8gwM
您可以使用
to_bytes
转换编码字符串的长度:另外,似乎
gzip.compress(enc)
产生的结果与C#对应的结果略有不同(因此总体结果也会有所不同),但这不应该是一个问题,因此解压缩应该正确处理所有问题首先,我要说的是C代码不适合跨平台使用。长度头的字节顺序取决于基础架构,因为
BitConverter.GetBytes
以架构的任何顺序返回字节但是,对于C#,我们可能指的是windows,也可能指的是Intel,所以很可能是Little Endian
所以,您需要做的是将原始数据的长度以小的Endian顺序预先添加到压缩数据中。正好是4个字节
然后,您需要连接并转换为base64:
相关问题 更多 >
编程相关推荐