zlib标题是什么样的?

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)

  • 当使用Java Inflator(使用ZLIB)时,我看到标头值为120,-100.这相当于78 9C.备份你上面说的话. (4认同)
  • 有四个可能的“78”答案 - 该答案省略了“78 5E” - 介于无/默认之间。其他 28 个值不太可能出现,但仍然有效。 (4认同)
  • 这帮助我弄清楚我正在处理什么类型的压缩。我知道该文件已被压缩,但正在搜索一些标头字节,结果出现了。谢谢! (2认同)
  • 这只是 64 个可能的 zlib 标头中的三个。请参阅 mwfearnley 的回答。 (2认同)

0xb*_*0de 70

链接到RFC

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)

  • 好吧,所以**这里的较低位数指的是较低有效位**,而不是 MSB。当你说“bit #0”时我很困惑。 (2认同)

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没有通用标头

  • gzip 流的前三个字节是常量:“1f 8b 08”,用于更强的区分。此外,您仅显示 64 个可能的 zlib 标头中的四个。请参阅 mwfearnley 的回答。 (4认同)

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个字节.

没有字典的标题值(CMFFLG)定义如下.

 CMF |  FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression 
Run Code Online (Sandbox Code Playgroud)

更多在ZLIB RFC

  • 此摘要仅显示 64 个可能的 zlib 标头中的三个。请参阅 mwfearnley 的回答。 (2认同)

mwf*_*ley 7

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,没有余数。

通常,只有CINFOFLEVEL字段可以自由更改,并且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?但实际上,发生这种情况时没有任何有效的标头,所以我们不必担心。)

  • 感谢您提供详尽的信息。这应该是这个问题的公认答案。 (2认同)

Tar*_*aro 5

这里的所有答案很可能都是正确的,但是 - 如果你想直接操作 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)

  • 这些是 gzip 流,而不是 zlib 流。两种不同的东西。 (4认同)