在我的项目中,我需要知道zlib
标题是什么样的。我听说它很简单,但我找不到zlib头的任何描述。
例如,它是否包含幻数?
答案 0 :(得分:90)
zlib魔术标题
78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression
答案 1 :(得分:66)
0 1
+---+---+
|CMF|FLG|
+---+---+
CMF(压缩方法和标志) 这个字节分为4位压缩方法和4位 位信息字段取决于压缩方法。
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
CM(压缩方法)
这标识了文件中使用的压缩方法。 CM = 8
表示窗口大小上升的“deflate”压缩方法
到32K。这是gzip和PNG 以及几乎所有其他方法使用的方法。
CM = 15保留。
CINFO(压缩信息) 对于CM = 8,CINFO是LZ77窗口的基数2对数 大小,减去8(CINFO = 7表示32K窗口大小)。值 在这个版本的版本中不允许超过7的CINFO 规格。 CINFO未在本规范中定义 CM不等于8。
实际上,这意味着第一个字节几乎总是78
(十六进制)
FLG(FLaGs) 该标志字节分为:
bits 0 to 4 FCHECK (check bits for CMF and FLG)
bit 5 FDICT (preset dictionary)
bits 6 to 7 FLEVEL (compression level)
当被视为时,FCHECK值必须是CMF和FLG 以MSB顺序存储的16位无符号整数(CMF * 256 + FLG), 是31的倍数。
FLEVEL(压缩等级)
这些标志可供特定压缩使用
方法。 “deflate”方法(CM = 8
)将这些标志设置为
如下:
0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm
答案 2 :(得分:14)
以下是Zlib压缩数据格式。
+---+---+
|CMF|FLG| (2 bytes - Defines the compression mode - More details below)
+---+---+
+---+---+---+---+
| DICTID | (4 bytes. Present only when FLG.FDICT is set.) - Mostly not set
+---+---+---+---+
+=====================+
|...compressed data...| (variable size of data)
+=====================+
+---+---+---+---+
| ADLER32 | (4 bytes of checksum)
+---+---+---+---+
大多数情况下,FLG.FDICT
(字典标志)未设置。在这种情况下,DICTID
根本就不存在。因此,总听觉只有2个字节。
没有字典的标题值(CMF
和FLG
)定义如下。
CMF | FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression
更多ZLIB RFC
答案 3 :(得分:13)
ZLIB / GZIP标题
Level | ZLIB | GZIP
1 | 78 01 | 1F 8B
2 | 78 5E | 1F 8B
3 | 78 5E | 1F 8B
4 | 78 5E | 1F 8B
5 | 78 5E | 1F 8B
6 | 78 9C | 1F 8B
7 | 78 DA | 1F 8B
8 | 78 DA | 1F 8B
9 | 78 DA | 1F 8B
Deflate没有通用标题
答案 4 :(得分:1)
ZLIB标头(在RFC1950中定义)是一个16位的big-endian值。它包含从最高到最低的以下字段:
CINFO
(第12-15位)
指示窗口大小为2的幂,从0(256)到7(32768)。通常是7。不允许更高的值。
CM
(第8-11位)
压缩方法。仅允许放气(8)。
FLEVEL
(第6-7位)
大致表示压缩级别,从快/低(0)到慢/高(3)
FDICT
(第5位)
指示是否使用预设字典。通常为0。从技术上讲,允许1,但我不知道定义预设词典的Deflate格式。
FCHECK
(位0-4)
计算其值的校验和,以使整个值被31除而没有余数。 *
通常,只能自由更改CINFO
和FLEVEL
字段。其他字段中没有包含任何内容,因此总共只有32个可能的标头有效。他们在这里:
FLEVEL: 0 1 2 3
CINFO:
0 08 1D 08 5B 08 99 08 D7
1 18 19 18 57 18 95 18 D3
2 28 15 28 53 28 91 28 CF
3 38 11 38 4F 38 8D 38 CB
4 48 0D 48 4B 48 89 48 C7
5 58 09 58 47 58 85 58 C3
6 68 05 68 43 68 81 68 DE
7 78 01 78 5E 78 9C 78 DA
CINFO
字段很少被压缩器设置为7以外的任何值(表示最大32KB窗口),因此,您可能会在野外看到的唯一值是最底行(从78
开始)。
*(您可能会怀疑FCHECK
的值上是否有少量余地-如果两者都通过校验和,可以将其设置为0还是31?实际上,实际上不会出现这种情况的任何有效标题,因此我们不必担心。)
答案 5 :(得分:0)
这里的所有答案都可能是正确的,但是 - 如果你想直接操作ZLib压缩流,并且它是使用gz_open, gzwrite, gzclose
函数生成的 - 那么在zlib压缩蒸汽到来之前还有额外的10个前导字节标题 - 这些是由函数gz_open生成的 - 标题如下所示:
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
并导致以下十六进制转储:1F 8B 08 00 00 00 00 00 00 0B
接下来是zlib压缩流。
但是还有8个字节 - 它们是uLong
- 整个文件的crc,uLong
- 未压缩的文件大小 - 在流的末尾查找后续字节:
putLong (s->file, s->crc);
putLong (s->file, (uLong)(s->in & 0xffffffff));