gpt4 book ai didi

compression - GZipStream无法检测到损坏的数据(甚至CRC32传递)?

转载 作者:行者123 更新时间:2023-12-04 18:48:48 25 4
gpt4 key购买 nike

我正在使用GZipStream压缩/解压缩数据。我在DeflateStream上选择了此选项,因为文档指出GZipStream还添加了CRC以检测损坏的数据,这是我想要的另一个功能。我的“正”单元测试运行良好,因为我可以压缩一些数据,保存压缩的字节数组,然后再次成功对其进行解压缩。 .NET GZipStream compress and decompress problem帖子使我意识到,在访问压缩或解压缩的数据之前,我需要关闭GZipStream。

接下来,我继续编写“负”单元测试,以确保可以检测到损坏的数据。我以前曾使用GZipStream class from MSDN的示例来压缩文件,使用文本编辑器打开压缩的文件,更改字节以破坏它(好像使用文本编辑器打开它还不错!),保存它然后解压缩它,以确保我按预期得到了InvalidDataException。

当我编写单元测试时,我选择了一个任意字节进行破坏(例如,compressedDataBytes [50] = 0x99)并获得了InvalidDataException。到现在为止还挺好。我很好奇,所以我选择了另一个字节,但令我惊讶的是我没有遇到异常。可能没关系(例如,我巧合地命中了数据块中未使用的字节),只要仍然可以成功恢复数据即可。但是,我也没有获得正确的数据!

为确保“不是我”,我从.NET GZipStream compress and decompress problem的底部获取了清理后的代码,并对其进行了修改,以顺序破坏压缩数据的每个字节,直到无法正确解压缩为止。这是更改(请注意,我是
使用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既没有引发异常,也没有恢复数据。

我是否缺少某些东西或做错了什么?谁能看到为什么未检测到损坏的压缩数据?

最佳答案

gzip格式有一个10字节的 header ,可以更改其最后七个字节而不会导致解压缩错误。因此,预计您注意到的7个案件均未损坏。

在流中其他任何地方都不会检测到带有损坏的错误,这几乎是稀有的了。在大多数情况下,解压缩器会检测到压缩数据格式的错误,甚至从未到达检查crc的地步。如果确实到达了检查crc的地步,则该检查几乎总是会因输入流损坏而失败。 (“几乎所有时间”表示大约1-2 ^ -32的概率。)

我只是使用您的示例字符串(在带有zlib的C语言中)进行了尝试,它产生了一个84字节的gzip流。递增84个字节中的每个字节而使其余部分保持不变,结果是:两次错误的 header 检查,一种无效的压缩方法,七次成功,一种无效的块类型,四个无效的距离集,七个无效的代码长度集,四个缺失块结尾,11个无效位长重复,3个无效位长重复,两个无效位长重复,两个流的意外结束,36个不正确的数据检查(这是实际的CRC错误)和四个不正确的长度检查(另一个检查)以gzip格式获取正确的未压缩数据长度)。在任何情况下都不会检测到损坏的压缩流。

因此,无论是在代码中还是在类中,都必须在某个位置存在错误。

更新:

似乎该类中有错误。

微软显着(或也许不显着)得出的结论是,他们won't fix这个错误!

关于compression - GZipStream无法检测到损坏的数据(甚至CRC32传递)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9456563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com