C# 在将一些垃圾字节添加到压缩数据字节数组的末尾之后,是否可以使用GZIP解压数据? 这只是C中的一个例子,我的意思是如何将垃圾数据添加到最后,请将其视为伪代码: [Test] public void TestGzipCompressor_WhenCompressCalledWithAddedExtraDataToTheEnd_ShouldReturnValidData() { var extraBytesToAddToTheEnd = new byte[] { 1, 2, 3, 4 }; //creating a test-byte array var bytesToPopulateArrayWith= new byte[9] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var byteList = new List<byte> { }; for (int i = 0; i < 100; i++) { inputBytes.AddRange(bytesToPopulateArrayWith); } //Getting data as a compressed byte list List<byte> compressedBytes = GzipCompressor.Compress(byteList); //adding extra garbage-bytes to the end of the compressed data byte-array compressedBytes.AddRange(extraBytesToAddToTheEnd); //Getting original data after decompression byte[] decompressedBytes = GzipCompressor.Decompress(compressedBytes.ToArray()); decompressedBytes.Should().BeEquivalentTo(stringBytes); }

C# 在将一些垃圾字节添加到压缩数据字节数组的末尾之后,是否可以使用GZIP解压数据? 这只是C中的一个例子,我的意思是如何将垃圾数据添加到最后,请将其视为伪代码: [Test] public void TestGzipCompressor_WhenCompressCalledWithAddedExtraDataToTheEnd_ShouldReturnValidData() { var extraBytesToAddToTheEnd = new byte[] { 1, 2, 3, 4 }; //creating a test-byte array var bytesToPopulateArrayWith= new byte[9] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var byteList = new List<byte> { }; for (int i = 0; i < 100; i++) { inputBytes.AddRange(bytesToPopulateArrayWith); } //Getting data as a compressed byte list List<byte> compressedBytes = GzipCompressor.Compress(byteList); //adding extra garbage-bytes to the end of the compressed data byte-array compressedBytes.AddRange(extraBytesToAddToTheEnd); //Getting original data after decompression byte[] decompressedBytes = GzipCompressor.Decompress(compressedBytes.ToArray()); decompressedBytes.Should().BeEquivalentTo(stringBytes); },c#,compression,gzip,C#,Compression,Gzip,但是在末尾添加5个或更多字节会引发“存档项是使用不受支持的压缩方法压缩的”错误 压缩机的实施如下所示: public static class GzipCompressor { [NotNull] public static byte[] Compress([NotNull] byte[] bytes) { using var memoryStream = new MemoryStream();

但是在末尾添加5个或更多字节会引发“存档项是使用不受支持的压缩方法压缩的”错误

压缩机的实施如下所示:

public static class GzipCompressor
    {
        [NotNull]
        public static byte[] Compress([NotNull] byte[] bytes)
        {
            using var memoryStream = new MemoryStream();
            using var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress);
            gzipStream.Write(bytes, 0, bytes.Length);
            gzipStream.Flush();
            return memoryStream.ToArray();
        }

        [NotNull]
        public static byte[] Decompress([NotNull] byte[] bytes)
        {
            using var memoryStream = new MemoryStream();
            using var gzipStream = new GZipStream(new MemoryStream(bytes), CompressionMode.Decompress);
            gzipStream.CopyTo(memoryStream);
            gzipStream.Flush();
            return memoryStream.ToArray();
        }
    }
GZIP是否可以在压缩数据的末尾使用一些垃圾字节解压? 为什么它只使用4字节或更少的字节,而不使用更多的字节?我的实现有什么问题吗?
谢谢

如果不深入研究GZipStream实现,我猜它正在读取附加的数据并试图将其解释为gzip帧头,当它得到意外输入时,会抛出异常

gzip文件格式在中有详细说明。它由一系列帧(RFC中称为“成员”)组成,所有帧都遵循特定格式。每个帧都有一个带有一些可选部分的标题块,后面是DEFLATE压缩数据和一个8字节的页脚。该格式支持头中可选的“额外数据”块,但大多数实现似乎忽略了它们

但是,文件格式不允许在文件中附加或添加任意数据。通过将数据附加到gzip流,可以将其更改为非gzip文件的内容。您已经创建了一个gzip变体,它不适用于兼容的实现,并且在不兼容的实现上具有未定义的行为

根据您的需要,还有其他更适合的压缩格式。如果是内部使用,那么您可能需要创建自己的格式来封装gzip或deflate数据。如果您必须生成一个gzip文件,那么您需要找到一个库,该库允许您在gzip头中读/写额外的数据


(希望我能标记人-这是这方面的最终来源。)

如果不深入研究GZipStream实现,我猜它正在读取附加的数据并试图将其解释为gzip帧头,当它得到意外输入时会抛出异常

gzip文件格式在中有详细说明。它由一系列帧(RFC中称为“成员”)组成,所有帧都遵循特定格式。每个帧都有一个带有一些可选部分的标题块,后面是DEFLATE压缩数据和一个8字节的页脚。该格式支持头中可选的“额外数据”块,但大多数实现似乎忽略了它们

但是,文件格式不允许在文件中附加或添加任意数据。通过将数据附加到gzip流,可以将其更改为非gzip文件的内容。您已经创建了一个gzip变体,它不适用于兼容的实现,并且在不兼容的实现上具有未定义的行为

根据您的需要,还有其他更适合的压缩格式。如果是内部使用,那么您可能需要创建自己的格式来封装gzip或deflate数据。如果您必须生成一个gzip文件,那么您需要找到一个库,该库允许您在gzip头中读/写额外的数据


(但愿我能给人贴上标签——这是这类东西的最终来源。)

看起来像是
GzipStream
中的一个bug。它在四个字节后才识别垃圾。正如Corey所指出的,gzip成员之后不是另一个完整的gzip成员的任何内容都表示gzip流无效。类应该识别是否有五个、四个或一个字节的垃圾


如果要在一个gzip成员之后停止解压缩,可以使用
DeflateStream
对gzip成员内部的压缩数据进行解码。然后,您只需要自己解码gzip报头和拖车,并计算解压缩数据上的CRC,以与拖车中的CRC进行比较。请参阅。

看起来像是
gzip流中的bug。它在四个字节后才识别垃圾。正如Corey所指出的,gzip成员之后不是另一个完整的gzip成员的任何内容都表示gzip流无效。类应该识别是否有五个、四个或一个字节的垃圾


如果要在一个gzip成员之后停止解压缩,可以使用
DeflateStream
对gzip成员内部的压缩数据进行解码。然后,您只需要自己解码gzip报头和拖车,并计算解压缩数据上的CRC,以与拖车中的CRC进行比较。请参阅。

这里的用例是什么,为什么需要这样做?如果您需要在非常特定的文件格式末尾对数据进行编码,为什么不添加数据,在末尾添加一个大小,当您去解压缩时,读取末尾的大小,删除数据,然后解压缩。至于为什么你可以不使用4个字节,谁知道呢,你必须阅读RFC,可能有很多原因,比如填充,而且其他植入可能会失败…你应该阅读规范。如果你想添加自己的数据,你可以阅读规范中关于如何做的内容,特别是第2.3.1.1节:这里的用例是什么,为什么需要这样做?如果您需要在非常特定的文件格式末尾对数据进行编码,为什么不添加数据,在末尾添加一个大小,当您去解压缩时,读取末尾的大小,删除数据,然后解压缩。至于为什么你可以不使用4个字节,谁知道呢,你必须阅读RFC,可能有很多原因,比如填充,也可能在其他植入中失败……你应该阅读规范。如果你想添加自己的数据,你可以阅读规范中关于如何做的部分,特别是
2.3.1.1
var extraBytesToAddToTheEnd = new byte[] { 1, 2, 3, 4, 5 };
public static class GzipCompressor
    {
        [NotNull]
        public static byte[] Compress([NotNull] byte[] bytes)
        {
            using var memoryStream = new MemoryStream();
            using var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress);
            gzipStream.Write(bytes, 0, bytes.Length);
            gzipStream.Flush();
            return memoryStream.ToArray();
        }

        [NotNull]
        public static byte[] Decompress([NotNull] byte[] bytes)
        {
            using var memoryStream = new MemoryStream();
            using var gzipStream = new GZipStream(new MemoryStream(bytes), CompressionMode.Decompress);
            gzipStream.CopyTo(memoryStream);
            gzipStream.Flush();
            return memoryStream.ToArray();
        }
    }