GZIP源码分析。

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于GZIP1.2.4的分析

葛伟

(南京航空航天大学信息学院计算机系学号:040130520)

摘要:简要的分析了GZIP的文件格式,基本的压缩使用的算法和实现,以及对GZIP 1.2.4的源码的主要函数进行了分析说明,阐述了对其中算法的一些自己的看法。

关键词:GZIP 1.2.4,GZIP分析

1.GZIP文件的基本格式说明

由于下面的分析会用到GZIP文件的格式中的内容,所以先对GZIP文件的格式进行一下简要的介绍。GZIP文件由1到多个“块”组成,实际上通常只有1个块。每个块包含头部、数据和尾部三部分。

| ID1 | ID2 | CM | FLG | MTIME | XFL | OS | 额外的头字段| 压缩的数据| CRC32 | ISIZE | 其中,头部分包括ID1,ID2,CM,FLG,MTIME,XFL,OS,以及额外的头字段。

∙ID1与ID2:各1字节。固定值,ID1 = 31 (0x1F),ID2 = 139(0x8B),表示GZIP格式。∙CM:1字节。压缩方法。目前只有一种:CM = 8,表示使用DEFLATE方法。

∙FLG:1字节。标志。

bit 0 FTEXT - 指示文本数据

bit 1 FHCRC - 指示存在CRC16头校验字段

bit 2 FEXTRA - 指示存在可选项字段

bit 3 FNAME - 指示存在原文件名字段

bit 4 FCOMMENT - 指示存在注释字段

bit 5-7 保留

∙MTIME:4字节。更改时间。UINX格式。

∙XFL:1字节。附加的标志。

当CM = 8时,XFL = 2 - 最大压缩但最慢的算法;XFL = 4 - 最快但最小压缩的算法

∙OS:1字节。操作系统,确切地说应该是文件系统。有下列定义:

0 - FAT文件系统(MS-DOS, OS/2, NT/Win32)

1 – Amiga

2 - VMS/OpenVMS

3 – Unix

4 - VM/CMS

5 - Atari TOS

6 - HPFS文件系统(OS/2, NT)

7 – Macintosh

8 - Z-System

9 - CP/M

10 - TOPS-20

11 - NTFS文件系统(NT)

12 – QDOS

13 - Acorn RISCOS

255 - 未知

额外的头字段:

(若FLG.FEXTRA = 1)

|SI1|SI2| XLEN | 长度为XLEN字节的可选项 |

(若FLG.FNAME = 1)

| 原文件名(以NULL结尾)|

(若FLG.FCOMMENT = 1)

| 注释文字(只能使用iso-8859-1字符,以NULL结尾) |

(若FLG.FHCRC = 1)

| CRC16 |

存在额外的可选项时,SI1与SI2指示可选项ID,XLEN指示可选项字节数。数据部分:

DE FLATE数据格式,包含一系列子数据块。子块概貌如下:|BFINAL| BTYPE | 数……据|

BFINAL:1bit位。

0 - 还有后续子块;

1 - 该子块是最后一块。

BTYPE:2bit位。

00 - 不压缩;

01 - 静态Huffman编码压缩;

10 - 动态Huffman编码压缩;

11 - 保留。

尾部分:

∙CRC32:4字节,保存原始数据的32位校验和。

∙ISIZE:4字节,用来保存原始数据长度的低32位。

2.GZIP所使用压缩算法的实现

下面将gzip的实现分块,一部分一部分来说明。对应的gzip 中所使用的各种实现技巧的出处或者灵感,gzip 的作者在源码的注释中分别进行了说明。

(1)寻找匹配串

算法概述:

Gzip 算法对遇到的每一个串,首先会把它插入到一个“字典”中。这样当以后有和它可以匹配的串,都可以直接从“字典”中查出这个串。

在插入的时候,使用这个插入串的前三个字节,计算出插入的“字典”位置,然后把插入串的开始位置保存在这个“字典”位置中。查出的时候,使用查出串的前三个字节,计算出“字典”位置,由于插入和查出使用的是同一种计算方法,所以如果两个串的前三个字节相同的话,计算出的“字典”位置肯定是相同的,所以就可以直接在该“字典”位置中,取出以前插入时,保存进去的那个串的开始位置。于是查出串,就找到了一个串,而这个串的前三个字节和自己的一样,所以就找到了一个匹配串。

但是会有多个串,他们的前三个字节都相同,那么他们在“字典”里的位置相同,他们将由一条链相连,放在对应的“字典”计算的位置的链上。所以,查到了一个相应在“字典”位置,也就查到了对应的一个链。所有和它前三个字节相同的串,都在这个链上。所以要找最长的匹配,就要遍历这个链上的每一个串,比较看和哪个串的匹配长度能获得最大值。

寻找匹配串的实现在源码中的的具体实现说明:

我们前面所说的“字典”,是用数组head[]表示的。

我们前面所说的“字典”位置,放在一个叫做ins_h的变量中。

我们前面所说的链,是在一个叫做prev[]的数组中。

插入head[ins_h]:

当前字节用strstart 标记。利用第strstart,strstart+1,strstart+2,这三个字节的值,使用一个哈希函数算出ins_h(在head[]表中的插入位置)。然后将当前字节的位置,即strstart,填到在head[ins_h]中。

相关文档
最新文档