(转)gzip⽂件格式详解
⼀、⽂件头
⽂件头由固定长度的部分和扩展部分组成,扩展部分不⼀定存在,尤其是⽹络传输使⽤的HTTP压缩,如果使⽤了gzip格式,那么对应的压缩报⽂⼀般都不带扩展部分。gzip⽂件格式通过将头部中定长部分的某些⽐特位置位来标识头部是否带有扩展部分,我们⼀⼀来看。
1、 ⽂件以10字节的定长部分开始
+——+——+——+——-+—+—+—+—+——+—–+
| ID1 | ID2 | CM | FLG | MTIME | XFL | OS |
+——+——+——+——-+—+—+—+—+——+—–+
上⾯两个“+”之间的内容代表⼀个字节,所以上⾯除了MTIME使⽤四个字节之外,其他只占⽤⼀个字节。
ID1和ID2(IDentification):这两个字节⽤于标识gzip⽂件,其中,ID1 = 31(0x1f,\037),ID2 = 139(0x8b,\213),如果判断某⽂件以这两个字节开头,那么可以初步认为这是gzip⽂件,但具体是不是,必须该⽂件格式完全符合gzip⽂件格式才⾏;
CM(CompressionMethod):该字段⽤于标识当前gzip压缩⽂件内部的压缩结果所使⽤的压缩⽅法,取值范围[0,8](提⽰,这是⼀个闭区间),其中,[0,7]保留,⽬前只⽤8,即gzip使⽤deflate压缩⽅法;
FLG(FLaGs):标记位,该标记位中的每⼀⽐特分别代表后⾯对应扩展位是否存在,各⽐特位含义如下,
Bit 0 FTEXT
Bit 1 FHCRC
Bit 2 FEXTRA
Bit 3 FNAME
Bit 4 FCOMMENT
Bit 5~7 预留,必须全0
Bit 0 FTEXT,如果置位,则表明⽂件(应该是指被压缩⽂件)是ASCII⽂本⽂件。这⼀位是否置位是
可选的,压缩⼯具通过检查少量输⼊数据中是否含有⾮ASCII字符来将其置位。⼀旦怀疑有⾮ASCII字符,就不置位,表⽰这是⼆进制⽂件。那些对ASCII⽂本⽂件和⼆进制⽂件使⽤不同⽂件格式的系统,解压缩⼯具会通过这⼀位是否置位来决定合适的⽂件格式。我们故意不让压缩所使⽤的算法来设置这⼀位,因为压缩⼯具本⾝可以选择是否将其置位,⽽且解压缩⼯具通常也可以选择忽略这⼀位并将数据转换的问题抛给其他程序。
Bit 1 FHCRC,如果置位,表⽰会对gzip⽂件头部进⾏CRC16校验,校验结果会放在实际的压缩数据之前,紧挨着实际的压缩数据。CRC16由CRC32的两个低有效字节组成,CRC32⽤于计算整个gzip头的校验和,但计算时不包括CRC16所占的这两个字节。这⼀位⼀般不会被置上。(注意:这⾥说的这个CRC32与我们后⾯要说的位于gzip⽂件尾的那个CRC32不是同⼀个CRC32但都是⽤32位循环冗余校验码算法计算得到的,只是作⽤对象不同。这⾥的CRC32作⽤对象是gzip头,完成计算后只取两个低有效字节,构成CRC16;⽽我们后⾯要说的位于gzip⽂件尾的CRC32的作⽤对象是全部的原始待压缩数据,这两个概念⼀定要理清)。
Bit 2 FEXTRA,如果置位,表⽰带着扩展gzip头部部分。扩展部分后续介绍。
Bit 3 FNAME,如果置位,表⽰携带被压缩⽂件的⽂件名(没被压缩),该⽂件名会以’\0’结束(就是个字符串)。该⽂件名必须由ISO 8859-1 (LATIN-1) 中的字符组成;在那些使⽤EBCDIC或其他字符
集组成名称的系统中,⽂件名称必须被转换为ISO LATIN-1 字符集才能让gzip⽂件携带。这个⽂件名是被压缩⽂件的原始⽂件名,不携带任何的路径信息,只是个⽂件名⽽已。如果被压缩⽂件在⼀个对名称字母⼤⼩写不敏感的⽂件系统上,则⽂件名称必须全部⼩写。如果被压缩数据不是来⾃⼀个有⽂件名称的⽂件,则不携带⽂件名称(⽐如使⽤gzip压缩HTTP应答报⽂);例如,被压缩数据来⾃Unix系统的标准输⼊,则gzip⽂件不携带⽂件名。
Bit 4 FCOMMENT,如果置位,表⽰携带以‘\0’结尾的⽂件说明(这个⽂件说明也是个字符串)。这个说明只是给⼈们去使⽤的,类似HTTP应答报⽂头部中的状态码原因短语。这个⽂件说明也必须使⽤ISO 8859-1 (LATIN-1)中的字符。换⾏时应该⽤⼀个⼗进制换⾏符。
MTIME(ModificationTIME):该字段给出了那个被压缩的原始⽂件最近被修改的时间。该时间使⽤Unix格式,即,⾃1970年1⽉1⽇0时起到现在的秒数。注意,对于MS-DOS或其他使⽤本地时间⽽不是使⽤通⽤时间的系统,这种⽅式可能会引起问题。如果不是压缩⼀个⽂件,那么该字段就是压缩⼯作开始的那个时间。如果该字段为0,则表⽰没有可⽤的时间戳(这种情况在使⽤gzip的HTTP压缩报⽂中很常见)。
XFL(eXtraFLags):这个字段是专门给gzip⽂件中使⽤的压缩⽅法⽤的,由于当前gzip只使⽤⼀种压缩⽅法,或压缩算法,即deflate,所以针对deflate,该字段有如下含义,
XFL= 2 – 压缩率最⼤但是压缩速度最慢(的那个压缩级别);
XFL= 4 – 最快的压缩(级别);
(注:deflate 是分0~9种压缩级别的,后续分析压缩源码的章节会专门分析压缩级别)
OS(OperatingSystem):这个字段表⽰⼲压缩这件事⼉的那个⽂件系统。这个字段对于确定⽂本⽂件的⾏结束标志是⾮常有⽤的。这个字段的当前值分别代表如下系统,
0- FAT filesystem (MS-DOS, OS/2, NT/Win32)
1- Amiga
2- VMS (or OpenVMS)
3- Unix
4- VM/CMS
5- Atari TOS
6- HPFS filesystem (OS/2, NT)
7- Macintosh
8- Z-System
9- CP/M
10- TOPS-20
11- NTFS filesystem (NT)
12- QDOS
13- Acorn RISCOS
255– unknown
2、 头部扩展字段
上⾯10个字节是⽆论如何都会存在的,⽽这⾥所描述的扩展字段,就是根据上⾯那10个字节来决定是否存在的。共分为四个部分,
按照顺序依次是:FEXTRA+FNAME+FCOMMENT+FHCRC,
不⼀定都会存在,但是只要存在,不论存在⼏个,⼀定要按照顺序来,例如,FHCRC 和FNAME都存在,那么FNAME ⼀定要在FHCRC 前⾯下⾯我们逐个分析。
FEXTRA:
+—–+—–+===============================================+
| XLEN |…………………………XLEN bytes of “extra field”…| (more–>)
+—–+—–+===============================================+
XLEN⽤两个字节记录,表⽰extra field部分的⼤⼩。⽽extra field部分⼜细分为如下结构,
+--------+--------+--------+--------+========================+
gzip是什么文件夹|    SI1    |    SI2    |          LEN          |…………... LEN bytes ofsubfield data ...|
+--------+--------+--------+--------+========================+
(我将这个部分翻译为次级域)SI1和SI2为这个次级域提供⼀个ID,这个ID通常由两个便于记忆的ASCII字母表⽰(这句话不知道是不是应该这么翻译)。Jean-Loup Gaillygzip@prep.ai.mit.edu(gzip
源码作者)维护了⼀张次级域表,你可以将⾃⼰的次级域ID发送给他。SI2 = 0 的次级域ID⽬前保留,未来再⽤。现在的次级域ID是这样定义的,
SI1      |        SI2      |        Data
———- ———- ————-
0x41(‘A’) 0x70 (‘P’) Apollo file typeinformation(这个真不知道这么翻译)
LEN给出了次级域数据部分的长度,但是不包括SI1、SI2和LEN这四个字节。
FNAME:
+=========================================+
|…originalfile name, zero-terminated…| (more–>)
+=========================================+
以‘\0’结束,就是个字符串
FCOMMENT:
+===================================+
|…filecomment, zero-terminated…| (more–>)
+===================================+
以‘\0’结束,就是个字符串
FHCRC:
+——-+——-+
| CRC16 |
+——-+——-+
⼆、⽂件尾
相⽐gzip⽂件头,gzip⽂件尾较简单,只由四个字节构成,
0 1 2 3 4 5 6 7
+———+———+———+———+———+———+———+———+
| CRC32 | ISIZE |
+———+———+———+———+———+———+———+———+
CRC32(Cyclic Redundancy Check):⽤标准循环冗余校验算法对原始数据进⾏计算的结果。
ISIZE(InputSIZE):将原始数据⼤⼩对2^32取模的结果(因为只能⽤四个字节存结果,所以只能对2^32取模)。
三、⽂件体
上⾯已经将整个gzip⽂件的基本⽂件格式分析完毕,这⾥简单说下gzip⽂件的⽂件体。该⽂件体本⾝与gzip没多⼤关系了,因为只要⽤到deflate的⽂件格式,这部分都是⼀样的,⽐如gzip的⽂件体和PKzip的⽂件体“基本”是⼀样的,因为它们都使⽤了deflate。换句话说,这部分的格式就全部由deflate算法(或格式)决定了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。