Decompress string в С#, которые были сжаты php gzcompress()

Я запрашиваю webservice в С# 4.0, который предоставляет мне строку, сжатую php gzcompress(). Теперь мне нужно распаковать эту строку в С#. Я пробовал несколько способов, включая

но каждый раз я получаю исключение "Отсутствующий магический номер".

Может кто-нибудь дать мне некоторые подсказки?

Спасибо

Изменить 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();
}

Ответ 1

Ну, вот и вы, с небольшой помощью @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.
 }

Ответ 2

Я хочу расширить ответ питера. PHP также может сжимать с помощью алгоритма Deflate. В этом случае вы должны использовать DeflateStream вместо GZipStream и удалить первые 2 байта (HEX: 78 9C) DeflateStream не работает с буфером, обработанным из реализации PHP

 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();
  }
}