【发布时间】:2020-09-10 01:17:56
【问题描述】:
这只是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);
}
如果我们添加少于 5 个字节,它就可以完美运行:
var extraBytesToAddToTheEnd = new byte[] { 1, 2, 3, 4 };
但在末尾添加 5 个或更多字节会引发“存档条目是使用不支持的压缩方法压缩的”错误。
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();
}
}
GZIP 是否可以解压缩最后带有一些垃圾字节的压缩数据? 为什么它可以使用 4 个字节或更少,但没有更多?我的实现有问题吗? 谢谢!
【问题讨论】:
-
你这里的用例是什么,为什么需要这样做?如果您需要在非常特定的文件格式的末尾对数据进行编码,为什么不添加数据,在末尾添加一个大小,当您去解压缩时,读取末尾的大小,删除数据,然后解压缩。至于为什么你可以逃脱 4 个字节,谁知道,你必须阅读 RFC,这可能有很多原因,比如填充,这实际上可能会因其他植入而失败......
-
您应该阅读规范。如果您想添加自己的数据,您可以阅读有关如何执行此操作的规范,特别是
2.3.1.1部分:tools.ietf.org/html/rfc1952#page-8
标签: c# compression gzip