内容目录
背景
最近在用tousocket http client时候发现它的getbody没有实现解压代码,不知道最新版本实现没有,我自己扩展一个新的函数GetBodyEx 用来进行解压,但直接用c# DeflateStream 解压Node js服务器的压缩数据会异常,但其他一些服务器却没有问题,于是我goole好久,整理资料然后解决这个问题
原因
deflate 算法有3种标准,DeflateStream 用的是原始数据没有额外的头,而其他会2个字节头,所以要用 DeflateStream 解压其他2种标准实现时候要跳2个字节。下面函数里面判断是否其他2种,如果是就跳2个字节,我开始实现通过异常判断,如果异常跳2个字节,但感觉没有下面性能高。
具体资料可以看这2篇文章
https://blog.ianli.xyz/2021/07/dotnet-deflate-vs-zlib/
https://my.oschina.net/unicloud/blog/1933043
实现
public static byte[] MicrosoftDecompress(byte[] data)
{
byte[] new_data = data;
if ((data.Length > 2) &&
((data[0] & 0xF) == 0x8) && // Low 4-bits must be 8
((data[0] & 0x80) == 0) && // High-bit must be clear
((((data[0] << 8) + data[1]) % 31) == 0)) // Validate checksum
{
new_data = new byte[data.Length - 2];
Array.Copy(data, 2, new_data, 0, new_data.Length);
}
try
{
using (MemoryStream compressed = new MemoryStream(new_data))
{
using (MemoryStream decompressed = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(compressed, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressed);
byte[] result = decompressed.ToArray();
return result;
}
}
}
}
catch (Exception)
{
return new byte[0];
}
}
题外话
网页压缩我们可以gzip而不用deflate这样子就没有兼容性问题了,网上说用第三方解压,但我发现我用第三方一样也解压不了,也会有兼容性问题。