在c#中解压缩由php的gzcompress()压缩的字符串

时间:2010-11-02 17:24:00

标签: c# php .net compression

我在c#4.0中查询一个web服务,它为我提供了一个由php gzcompress()压缩的字符串。现在我需要在c#中解压缩这个字符串。我试过几种方法,包括

但每次我都会收到“遗失魔法数字”的例外情况。

有人能给我提供一些提示吗?

谢谢

修改1:

我的最新尝试:

public static string Decompress(string compressed) {
    byte[] compressedBytes = Encoding.ASCII.GetBytes(compressed);
    MemoryStream mem = new MemoryStream(compressedBytes);
    GZipStream gzip = new GZipStream(mem, CompressionMode.Decompress);
    StreamReader reader = new StreamReader(gzip);
    return reader.ReadToEnd();
}

2 个答案:

答案 0 :(得分:11)

嗯,你去了@boas.anthro.mnsu.edu的一点帮助:

using (var mem = new MemoryStream())
{
    mem.Write(new byte[] { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 8);
    mem.Write(inputBytes, 0, inputBytes.Length);

    mem.Position = 0;

    using (var gzip = new GZipStream(mem, CompressionMode.Decompress))
    using (var reader = new StreamReader(gzip))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}

诀窍是添加魔术头。请注意,使用SharpZipLib时,无效。它抱怨说没有页脚。但是,.NET解压缩程序运行得很好。

还有一件事。有关ASCII.GetBytes()的注释是正确的:您的输入不是ASCII。我用以下方法实现了这个结果:

// From PHP:

<?php echo base64_encode(gzcompress("Hello world!")); ?>

// In C#:

string input = "eJzzSM3JyVcozy/KSVEEAB0JBF4=";

byte[] inputBytes = Convert.FromBase64String(input);

使用额外的base64编码和解码,这非常有效。

如果您不能使用base64编码,则需要PHP页面中的原始流。您可以使用GetResponseStream()

来获取此信息
 var request = WebRequest.Create("http://localhost/page.php");

 using (var response = request.GetResponse())
 using (var mem = response.GetResponseStream())
 {
     // Decompression code from above.
 }

答案 1 :(得分:0)

我想扩大彼得的回答。 PHP也可以使用Deflate算法压缩。在这种情况下,您应该使用DeflateStream而不是GZipStream并删除前2个字节(HEX:78 9C)DeflateStream not working with buffer processed from PHP implementation

 private static byte[] Decompress(byte[] data)
{
  using (var compressedStream = new MemoryStream(data.Skip(2).ToArray()))
  using (var zipStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
  using (var resultStream = new MemoryStream())
  {
    zipStream.CopyTo(resultStream);
    return resultStream.ToArray();
  }
}