GZipStream не обнаруживает поврежденные данные (даже проходы CRC32)?

Я использую GZipStream для сжатия / распаковки данных. Я выбрал это вместо DeflateStream, так как в документации говорится, что GZipStream также добавляет CRC для обнаружения поврежденных данных, что является еще одной функцией, которую я хотел. Мои «положительные» модульные тесты работают хорошо: я могу сжать некоторые данные, сохранить сжатый байтовый массив и затем снова успешно распаковать его.Проблема сжатия и распаковки .NET GZipStream Пост помог мне понять, что мне нужно закрыть GZipStream перед доступом к сжатым или распакованным данным.

Затем я продолжил писать «отрицательный» модульный тест, чтобы убедиться, что поврежденные данные могут быть обнаружены. Я ранее использовал пример дляGZipStream класс из MSDN чтобы сжать файл, откройте сжатый файл с помощью текстового редактора, измените байт, чтобы испортить его (как будто открытие его с помощью текстового редактора было достаточно плохо!), сохраните его, а затем распакуйте, чтобы убедиться, что я получил InvalidDataException, как и ожидалось.

Когда я написал модульный тест, я выбрал произвольный байт для повреждения (например, compressDataBytes [50] = 0x99) и получил исключение InvalidDataException. Все идет нормально. Мне было любопытно, поэтому я выбрал другой байт, но, к своему удивлению, я не получил исключения. Это может быть хорошо (например, я случайно ударил неиспользованный байт в блоке данных), если данные все еще могут быть успешно восстановлены. Тем не менее, я также не получил правильные данные обратно!

Чтобы быть уверенным, что «это был не я», я взял очищенный код с нижней частиПроблема сжатия и распаковки .NET GZipStream и изменил его, чтобы последовательно повредить каждый байт сжатых данных, пока он не сможет распаковать должным образом. Вот изменения (обратите внимание, что я использую тестовую среду Visual Studio 2010):

// successful compress / decompress example code from:
//    https://stackoverflow.com/questions/1590846/net-gzipstream-compress-and-decompress-problem
[TestMethod]
public void Test_zipping_with_memorystream_and_corrupting_compressed_data()
{
   const string sample = "This is a compression test of microsoft .net gzip compression method and decompression methods";
   var encoding = new ASCIIEncoding();
   var data = encoding.GetBytes(sample);
   string sampleOut = null;
   byte[] cmpData;

   // Compress 
   using (var cmpStream = new MemoryStream())
   {
      using (var hgs = new GZipStream(cmpStream, CompressionMode.Compress))
      {
         hgs.Write(data, 0, data.Length);
      }
      cmpData = cmpStream.ToArray();
   }

   int corruptBytesNotDetected = 0;

   // corrupt data byte by byte
   for (var byteToCorrupt = 0; byteToCorrupt < cmpData.Length; byteToCorrupt++)
   {
      // corrupt the data
      cmpData[byteToCorrupt]++;

      using (var decomStream = new MemoryStream(cmpData))
      {
         using (var hgs = new GZipStream(decomStream, CompressionMode.Decompress))
         {
            using (var reader = new StreamReader(hgs))
            {
               try
               {
                  sampleOut = reader.ReadToEnd();

                  // if we get here, the corrupt data was not detected by GZipStream
                  // ... okay so long as the correct data is extracted
                  corruptBytesNotDetected++;

                  var message = string.Format("ByteCorrupted = {0}, CorruptBytesNotDetected = {1}",
                     byteToCorrupt, corruptBytesNotDetected);

                  Assert.IsNotNull(sampleOut, message);
                  Assert.AreEqual(sample, sampleOut, message);
               }
               catch(InvalidDataException)
               {
                  // data was corrupted, so we expect to get here
               }
            }
         }
      }

      // restore the data
      cmpData[byteToCorrupt]--;
   }
}

Когда я запускаю этот тест, я получаю:

Assert.AreEqual failed. Expected:<This is a compression test of microsoft .net gzip compression method and decompression methods>. Actual:<>. ByteCorrupted = 11, CorruptBytesNotDetected = 8

Таким образом, это означает, что в действительности было 7 случаев, когда повреждение данных не имело значения (строка была успешно восстановлена), но повреждение 11 байта не вызвало исключение и не восстановило данные.

Я что-то упускаю или делаю что-то не так? Кто-нибудь может понять, почему поврежденные сжатые данные не обнаруживаются?

Ответы на вопрос(1)

Ваш ответ на вопрос