GZIP源代码分析(一)

时间:2021-11-15 19:59:43

GzipLinux下的压缩软件,.gz后缀的文件就是经gzip压缩后的文件。Gzip的源码当然由压缩和解压缩两部分构成,但本文只打算介绍其压缩部分,这部分的代码风格良好,且注释充分,并能很好的体现所用到的算法,而解压的代码完全是没有注释的一坨,其解压思路我们大致可以根据压缩过程反向推理出来,所以就不管它了。

目录

一、算法介绍

二、实现介绍

……


一、Gzip中涉及的压缩算法简介:

1、游程编码(run length encoding

这是一种非常直观的编码。一个例子就能说明:

一串数字5555557777733322221111111

经游程编码后变为(56)(75)(33)(24)(17

不难发现,在一个括号中,第二个数字表示第一个数字重复的次数。

显然,这种编码方式,对字符连续出现次数很多的串,压缩效果很好。但对于字符不连续出现的串,哪怕出现的频率非常高,也无能为力。

2LZ77编码

这是由名叫Lempel和Ziv的两个人在1977年提出的算法,所以被叫做LZ77算法。这种编码也很简单。一个例子:

这样一个字符串2B or not 2B, that is the Q.

经LZ77编码后变为2B or not (10, 2), that is the Q.

发现第二个2B被(10, 2)替换掉了,(10, 2)是一个距离-长度二元组,代表的意思是重复10个字符之前长度为2的串,数一下,发现果然就是2B。

显然,这种编码方式,对文本的压缩效果会很好,因为像英文中the啊and啊这些词经常出现。

3、哈弗曼编码

这个算法教科书中都有介绍。网上找了一篇很不错的介绍文章http://www.thecodeway.com/blog/?p=870

简单的说就是,根据字符在串中出现的频率,对字符的进行重新编码,在原编码和新编码之间建立一种一一映射,使出现频率较高的字符新编码较短,而出现频率低的字符新编码较长,这样就使得用新编码构成的串比原来短了。

不同于上面两种编码,经哈弗曼编码后的串,已经完全脱胎换骨,需要额外地保存新旧编码的一一映射关系,才能还原原字符串,即解压缩。  


至于gzip如何把这几种算法融合起来,且听下文分解。