48

简单聊聊 GZIP 的压缩原理与日常应用

 5 years ago
source link: https://github.com/rccoder/blog/issues/32?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

在基于 HTTP 协议的网络传输中 GZip 经常被使用,Nginx 中也可以使用半行代码开启 GZip。GZip 压缩的原理是什么呢?本篇文章是我在网上阅读了一些文档后做的简单总结。

从 RFC 1952 看起

RFC 1952GZIP file format specification version 4.3 。该规范主要定义了 GZip 压缩的在数据格式方面的规范,以方便不同的操作系统、CPU、文件系统等之间进行文件传输交换。下面挑有意思的几个点说,感兴趣的可以阅读 RFC 1952 的原文。

GZIP 的文件格式在设计上其实是可以允许一个文件里有多个压缩数据集(compressed data sets)—— GZIP 压缩后的片段拼接而成的。但就我们大多数应用场景来说,基本上都是一个文件一个压缩数据集,如果是多个文件一起打包的话,也往往是将多个包合并成一个 tar 文件。

每个压缩数据集都是下面的结构:

| ID1 | ID2 | CM | FLG | MTIME(4字节) | XFL | OS | ---> more

|| 之间是 1 byte,都是大端字节(Big Edian)

  • 其中 ID1 和 ID2 分别是 0x1f 和 0x8b,用来标识文件格式是 gzip

  • CM 标识 加密算法,目前 0-7是保留字,8 指的是 deflate 算法

  • FLG 从低地址到高地址分别是 FTEXT、FHCRC、FEXTRA、FNAME、FCOMMENT、reserved、 reserved、reserved,这里每个 bit 被设置了之后有什么意义感兴趣的话可以详细参考 RFC 1952。比较有意思的是 FEXTRA,如果它被设置了表示存在额外的拓展字段。拓展字段的结构如下:

    <[email protected]>
    
  • MTIME 指的是源文件最近一次修改时间,存的是 Unix 时间戳

  • XFL 是给压缩算法传的一些参数,用来标识如何解压。defalte 算法中 2 表示使用压缩率最高的算法,4 表示使用压缩速度最快的算法

  • OS 标识压缩程序运行的文件系统,以处理 EOF 等的问题

  • more 后面是根据 FLG 的开启情况决定的,可能会有 循环冗余校验码、源文件长度、附加信息等多种其他信息

压缩核心之 Deflate

GZIP 的核心是 Deflate,在 RFC 1951 中被标准化,并且在当时作为 LZW 的替代品有了非常广泛的使用。

Deflate 是一个同时使用 LZ77 与 Huffman Coding 的算法,这里简单介绍下这两种算法的大致思路:

LZ77

LZ77 的核心思路是如果一个串中有两个重复的串, 那么只需要知道第一个串和后面串相对于第一个串起始位置的距离 + 串的长度

Huffman Coding

简单

网站中的使用

Nginx 开启

相关探测

-- 未完、待续 #32 ---

参考文档


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK