Gzip从字符串错误解压缩,GZip标头中的幻数不正确

时间:2011-11-21 07:35:51

标签: c# php .net gzip

我试图在C#中复制php函数gzuncompress 到目前为止,我参与了以下代码的工作。请参阅下面的评论和代码。

我认为在byte []和字符串转换期间发生了棘手的问题。 我怎样才能解决这个问题?我在哪里错过了?

我正在使用.Net 3.5环境

        var plaintext = Console.ReadLine();
        Console.WriteLine("string to byte[] then to string");
        byte[] buff = Encoding.UTF8.GetBytes(plaintext);

        var compress = GZip.GZipCompress(buff);
        //Uncompress working below
        try
        {
            var unpressFromByte = GZip.GZipUncompress(compress);
            Console.WriteLine("uncompress successful by uncompress byte[]");
        }catch
        {
            Console.WriteLine("uncompress failed by uncompress byte[]");
        }

        var compressString = Encoding.UTF8.GetString(compress);
        Console.WriteLine(compressString);
        var compressBuff = Encoding.UTF8.GetBytes(compressString);
        Console.WriteLine(Encoding.UTF8.GetString(compressBuff));
        //Uncompress not working below by using string
        //The magic number in GZip header is not correct
        try
        {
            var uncompressFromString = GZip.GZipUncompress(compressBuff);
            Console.WriteLine("uncompress successful by uncompress string");
        }
        catch
        {
            Console.WriteLine("uncompress failed by uncompress string");
        }

Gzip类的代码

public static class GZip
      {
        public static byte[] GZipUncompress(byte[] data)
        {
            using (var input = new MemoryStream(data))
            using (var gzip = new GZipStream(input, CompressionMode.Decompress))
            using (var output = new MemoryStream())
            {
                gzip.CopyTo(output);
                return output.ToArray();
            }
        }
        public static byte[] GZipCompress(byte[] data)
        {
            using (var input = new MemoryStream(data))
            using (var output = new MemoryStream())
            {
                using (var gzip = new GZipStream(output, CompressionMode.Compress, true))
                {
                    input.CopyTo(gzip);
                }
                return output.ToArray();
            }
        }

        public static long CopyTo(this Stream source, Stream destination)
        {
            var buffer = new byte[2048];
            int bytesRead;
            long totalBytes = 0;
            while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
            {
                destination.Write(buffer, 0, bytesRead);
                totalBytes += bytesRead;
            }
            return totalBytes;
        }
}

2 个答案:

答案 0 :(得分:6)

这是不合适的:

var compressString = Encoding.UTF8.GetString(compress);

compress 不是 UTF-8编码的文本。您应该将其视为任意二进制数据 - 适合传递到Encoding.GetString。如果您确实需要将任意二进制数据转换为文本,请使用Convert.ToBase64String(然后使用Convert.FromBase64String反转):

var compressString = Convert.ToBase64String(compress);
Console.WriteLine(compressString);
var compressBuff = Convert.FromBase64String(compressString);

这可能与PHP的作用相匹配,也可能不符合,但它是将安全方式表示为文本的任意二进制数据,不像将二进制数据视为有效的UTF-8编码文本。

答案 1 :(得分:1)

  

我试图在C#中复制php函数gzuncompress

然后使用内置于.NET框架中的GZipStreamDeflateStream类来实现此目的。