uni*_*n83 60 structure header zlib
在我的项目中,我需要知道zlib标题是什么样的.我听说它很简单,但我找不到任何zlib标头的描述.
例如,它是否包含幻数?
Vah*_*idN 95
zlib魔术头
78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression
Run Code Online (Sandbox Code Playgroud)
0xb*_*0de 70
0 1
+---+---+
|CMF|FLG|
+---+---+
Run Code Online (Sandbox Code Playgroud)
CMF(压缩方法和标志)根据压缩方法,该字节分为4位压缩方法和4位信息字段.
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
Run Code Online (Sandbox Code Playgroud)
CM(压缩方法)这标识文件中使用的压缩方法.CM = 8
表示"deflate"压缩方法,窗口大小最大为32K.这是gzip和PNG 以及几乎所有其他方法使用的方法.
保留CM = 15.
CINFO(压缩信息)对于CM = 8,CINFO是LZ77窗口大小的基数2对数,减去8(CINFO = 7表示32K窗口大小).在此版本的规范中不允许CINFO的值高于7.对于CM不等于8,本规范中未定义CINFO.
实际上,这意味着第一个字节几乎总是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)
Run Code Online (Sandbox Code Playgroud)
FCHECK值必须使得CMF和FLG在被视为以MSB顺序(CMF*256 + FLG)存储的16位无符号整数时,是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
Run Code Online (Sandbox Code Playgroud)
Ctt*_*ttr 21
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
Run Code Online (Sandbox Code Playgroud)
Deflate没有通用标头
mk.*_*k.. 15
以下是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)
+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)
大多数情况下,FLG.FDICT(字典标志)未设置.在这种情况下,DICTID根本就不存在.因此,总听觉只有2个字节.
没有字典的标题值(CMF和FLG)定义如下.
CMF | FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression
Run Code Online (Sandbox Code Playgroud)
更多在ZLIB RFC
ZLIB 标头(在RFC1950 中定义)是一个 16 位的大端值。它包含从最重要到最不重要的这些字段:
CINFO (位 12-15)
表示窗口大小为 2 的幂,从0(256 字节)到7(32768 字节)。这通常是7. 不允许更高的值。
CM (位 8-11)
压缩方法。只8允许放气 ( )。
FLEVEL(第 6-7 位)
粗略表示压缩级别,从0(快/低)到3(慢/高)
FDICT (bit 5)
指示是否使用预设字典。这通常是0. 1在技术上是允许的,但我不知道任何定义预设词典的 Deflate 格式。
FCHECK(位 0-4)
一个校验和(5 位,0.. 31),其值的计算使得整个值除以 31,没有余数。
通常,只有CINFO和FLEVEL字段可以自由更改,并且FCHECK必须根据最终值计算。* 假设没有预设字典,其他字段包含的内容没有选择,因此总共有 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
Run Code Online (Sandbox Code Playgroud)
该CINFO字段很少(如果有的话)由压缩器设置为7(指示最大 32KB 窗口)以外的任何值,因此您可能在野外看到的唯一值是底行中的四个(以 开头78)。
*(您可能想知道FCHECK-的值是否有少量余地- 如果两者都通过校验和,是否可以将其设置为 0 或 31?但实际上,发生这种情况时没有任何有效的标头,所以我们不必担心。)
这里的所有答案很可能都是正确的,但是 - 如果你想直接操作 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);
Run Code Online (Sandbox Code Playgroud)
并产生以下十六进制转储: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));
Run Code Online (Sandbox Code Playgroud)