在程序中使用zlib并注意到"foo"在Windows 1F8B080000000000000A4BCBCF07002165738C03000000和Linux 上压缩的方式有一点差异1F8B08000000000000034BCBCF07002165738C03000000.两者都解压缩回"foo"
我决定在我们的代码外部检查以确定实现是否正确并使用zlib存储库中的测试程序进行双重检查.我得到了相同的结果:
Linux的: echo -n foo| ./minigzip64 > text.txt'
视窗: echo|set /p="foo" | minigzip > text.txt
什么能解释这种差异?这是个问题吗?
1F8B 0800 0000 0000 000 *3/A* 4BCB CF07 0021 6573 8C03 0000 00
首先,如果它解压缩到压缩的内容,那么这不是问题.不同的压缩机,或不同设置的相同压缩机,或者具有相同设置但不同版本的相同压缩机,可以从相同的输入产生不同的压缩输出.
其次,这种情况下的压缩数据是相同的.只有压缩数据之前的gzip头的最后一个字节是不同的.该字节标识原始操作系统.因此,它在Linux和Windows之间有所不同.
即使在相同的操作系统上,标头也可以变化,因为它带有修改日期和时间.但是,在您的两种情况下,修改日期和时间都被省略(设置为零).
只是为了在这里添加已接受的答案。我很好奇,自己尝试了一下,保存原始数据并用 7zip 打开:
您可以立即注意到唯一不同的字段是Host OS。
Header Data Footer
1F8B080000000000000A | 4BCBCF0700 | 2165738C03000000
Run Code Online (Sandbox Code Playgroud)
让我们来分解一下。
首先,从这个答案我意识到它实际上是一个gzip而不是zlib标头:
Level ZLIB GZIP
1 | 78 01 | 1F 8B
9 | 78 DA | 1F 8B
Run Code Online (Sandbox Code Playgroud)
进一步搜索让我在取证 wiki 上找到了一篇有关Gzip的文章。本例中的值为:
Offset Size Value Description
0 | 2 | 1f8b | Signature (or identification byte 1 and 2)
2 | 1 | 08 | Compression Method (deflate)
3 | 1 | | Flags
4 | 4 | | Last modification time
8 | 1 | | Compression flags (or extra flags)
9 | 1 | 0A | Operating system (TOPS-20)
Run Code Online (Sandbox Code Playgroud)
Offset Size Value Description
0 | 4 | 2165738C | Checksum (CRC-32) (Little endian)
4 | 4 | 03 | Uncompressed data size Value in bytes.
Run Code Online (Sandbox Code Playgroud)
这里需要注意的有趣的事情是,即使标头中的上次修改时间 和操作系统不同,它也会压缩为相同的数据,并在页脚中具有相同的校验和。
IETF RFC有更详细的格式摘要