1. 程式人生 > 實用技巧 >字符集編碼與資料壓縮

字符集編碼與資料壓縮

1.字符集與編碼

字符集:表示多個字元的集合,如符號,序號、數字,其它等等。

字元編碼:把字元編碼為指定集合中的某一物件,變成一種特定的位元組或位元組序列,在計算機中便於儲存,傳輸。

通常字符集都採用對應的編碼方式,如ASCII、IOS-8859-1、GB2312、GBK,即表示了字符集又表示了對應的字元編碼,但是Unicode例外,它採用的現代模型。

2.字符集編碼的發展

字符集編碼的發展,從單位元組,發展到雙位元組,最終到多位元組。

(1)單位元組

ASCII,用 7 位二進位制表示(00000000-01111111 即 0x00-0x7F)。EASCII(Extended ASCII),256 個字元,用 8 位二進位制表示(00000000-11111111 即 0x00-0xFF)。

(2)雙位元組

當計算機傳到了亞洲,256 個碼位就不夠用了。於是乎繼續擴大二維表,單位元組改雙位元組,16 位二進位制數,65536 個碼位。在不同國家和地區又出現了很多編碼,大陸的 GB2312、港臺的 BIG5、日本的 Shift JIS 等等。

雙位元組編碼是可以變長,主要是為了相容ASCII碼和節省儲存容量,但是可能會損失一部分碼位。

UNICODE 字符集國際標準字符集,它將世界各種語言的每個字元定義一個唯一的編碼,以滿足跨語言、跨平臺的文字資訊轉換。有多個編碼方式,分別是 UTF-8,UTF-16,UTF-32 編碼。

(3)多位元組

UTF表示Unicode Transformation Format的縮寫,是一種Unicode轉換格式,後面的數字表示至少用多少個位元位來儲存字元。

UTF-8表示一種變長編碼方案,使用1-6個位元組來儲存;

UTF-16使用2個或4個位元組來儲存,長度固定又可變。

UTF-32表示一種固定長度編碼方案,使用4個位元組來儲存。

Utf8字首編碼格式如下:

當Unicode 編號範圍在 0~FFFF 之間的字元,UTF-16 使用兩個位元組儲存,並且直接儲存 Unicode 編號,不用進行編碼轉換,這跟 UTF-32 非常類似。當Unicode 編號範圍在 10000~10FFFF 之間的字元,UTF-16 使用四個位元組儲存。實際就把較高的一些位元位用D800~DBFF 之間的雙位元組儲存,較低的位元位用DC00~DFFF之間的雙位元組儲存。

UTF-32 是固定長度的編碼,始終佔用 4 個位元組,足以容納所有的 Unicode 字元,所以直接儲存 Unicode 編號即可,不需要任何編碼轉換。浪費了空間,提高了效率。

UTF大小端問題

BOM實際就是使用大端(BE)還是小端(LE)問題。

UTF-16BE,大端:就是把高位位元組放在低地址表示。

UTF-16LE,小端:就是把低位元組放在低地址表示。

UTF在檔案的儲存。UTF格式在檔案中總有固定檔案頭。UTF-8預設不帶BOM。

當開啟一個檔案時,怎麼識別使用的是UTF-8還是UTF-16.在檔案的開頭就是標誌。

EF BB BF 表示 UTF-8

FE FF 表示 UTF-16BE

FF FE 表示 UTF-16LE

00 00 FE FF 表示 UTF32-BE

FF FE 00 00 表示 UTF32-LE

注意:只有UTF-8相容ASCII,UTF-32和UTF-16都不相容ASCII,因為這連個沒有單位元組編碼。

iconv

iconv命令用來轉換檔案的編碼,如將UTF8編碼轉換成GB18030的編碼,Linux下的iconv開發庫包括iconv_open,iconv_close,iconv等C函式,實現快速轉換。

格式:

iconv -f encoding [-t encoding] [inputfile] ....

選項:

-f encoding :字元從encoding編碼開始轉換

-t encoding :字元轉換到encoding編碼

-l:已知的編碼字元集合

-o file :指定輸出檔案

-c :忽略輸出的非法字元

-s :禁止警告資訊,但不是錯誤資訊

--verbose :顯示進度資訊

檢視支援的格式:iconv -l

UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, UTF-32LE, UTF8, UTF16, UTF16BE, UTF16LE, UTF32, UTF32BE, UTF32LE GB2312 ,GBK ISO-8859-1。

轉換各種格式:

字符集轉換程式設計:

#include <iconv.h>

函式:iconv_t iconv_open (const char* tocode, const char* fromcode);

範例:iconv_t cd = iconv_open(“UTF−8”, “UTF−16”);

函式:int iconv_close (iconv_t cd);

範例:iconv_close(cd);

函式:size_t iconv (iconv_t cd, const char* * inbuf, size_t * inbytesleft, char* * outbuf,

size_t * outbytesleft);

返回值:返回-1 則說明出現異常,錯誤碼

E2BIG:outbuf 沒有足夠的空間

EILSEQ:遇到無效的多位元組序列

EINVAL:遇到不完整的多位元組序列

字符集線上工具集合

GBK 內碼查詢:

http://www.mytju.com/classcode/tools/encode_gb2312.a

完整的 Unicode 字符集:

https://unicode-table.com/c

Unicode 和 UTF 編碼轉換:

https://www.qqxiuzi.cn/bianma/Unicode-UTF.p

漢字字符集編碼查詢:

https://www.qqxiuzi.cn/bianma/zifuji.p

3.壓縮原理

壓縮原理就是找到重複出現的字串,然後用更短的符號代替,從而達到縮短字串的目的。本質上,所謂就是找出檔案內容的概率分佈,將出現概率高的部分代替為更短的形式。內容越重複的檔案,可以壓縮的越小。如,"ABABABABABABAB"可以壓縮成"7AB"。反之內容毫無重複,就很難壓縮,極端情況就是,均勻分佈的隨機字串,往往一個字元都無法壓縮,如任意排列的10個阿拉伯陣列(123456789),就無法壓縮,再如π,也很難。

夏農極限

∑ log2(1/pn) / n = log2(1/p1)/n + log2(1/p2)/n + ... + log2(1/pn)/n;

(1)如果兩個檔案都包含了1024個符號,在ASCII 碼情況下,長度是相等,A檔案(只包含abc)的內容50%是 a,30%b,20%是 c,則平均每個符號要佔用1.49個二進位制位。

0.5*log2(1/0.5) + 0.3*log2(1/0.3) + 0.2*log2(1/0.2) = 1.49

(2)假如B檔案的每個位元組出現的概率是0-255,均勻分佈的出現概率是1/256,則 pn = 1/256,計算出極限為 8。

Log21/(1/256) = Log2256 = 8

4.Deflate 壓縮演算法

deflate是一種壓縮資料流的演算法,任何需要流式壓縮的地方都可以,deflate是zip壓縮檔案的預設演算法,除了zip檔案,還有7z,xz等其他壓縮檔案,也是用。

deflate 演算法下的壓縮器有三種壓縮模型:

(1)不壓縮資料,對於已經壓縮的資料,不再壓縮,這樣的資料會稍微增加,但會小於其它應用的一種壓縮演算法。

(2)先用L7zz,再用huffman 編碼。壓縮的樹是Deflate規範定義,所以不需要額外的空間來儲存這個樹。

(3)先用LZ77,然後再用huffman 編碼。壓縮樹由壓縮器生成,並與資料一起儲存。

如果資料被分割成不同塊,必須使用單一的壓縮模式,如果要在這三種壓縮模式中相互切換,必須先結束當前塊,重新開始一個新的塊。

5.LZ77 演算法原理

採用字典的方式進行壓縮,是一個簡單高效的資料壓縮演算法。把資料中的一些可以組織成短語的字元加入字典,然後再有相同字元出現採用畢節來代替字典中的短語,如此通過標記代替多數重複出現的方式以進行壓縮。需先了解 3 個關鍵詞:短語字典,滑動視窗和向前緩衝區。

(1)前向緩衝區

每次讀取資料的時候,先把一部分資料預載入前向緩衝區。為移入滑動視窗做準備

(2)一旦資料通過緩衝區,那麼它將移動到滑動視窗中,並變成字典的一部分。滑動視窗需要預設一個定值。

(3) 比如字元(A,B,D) ,可以組合的短語為{(A),(A,B),(A,B,D),(B),(B,D),(D)},如果這些字元在滑動窗口裡面,可以標記為當前的短語字典,滑動視窗不斷向前滑動,短語字典也不斷變化。

注意:先通過前向緩衝區預讀資料,然後再向滑動視窗移入(滑動視窗有一定長度),在這個過程中,不斷尋找與字典中短語匹配的最長短語,最終通過標記符標記,以ABD為例子。這裡滑動視窗 和前向緩衝區可以匹配的最長短語是(A,B),然後向前移動的時候再次遇到(A,B)的時候採用標記符代替。

當壓縮資料的時候,前向緩衝區與移動視窗之間在做短語匹配的是後會存在 2 種情況:

(1)找不到匹配時:將未匹配的符號編碼成符號標記(多數都是字元本身)

(2)找到匹配時:將其最長的匹配編碼成短語標記。

短語標記包含三部分資訊:

(1)滑動視窗中的偏移量(從匹配開始的地方計算);

(2)匹配中的符號個數;

(3)匹配結束後的前向緩衝區中的第一個符號。

一旦把 n 個符號編碼並生成相應的標記,就將這 n 個符號從滑動視窗的一端移出,並用前向緩衝區中同樣數量的符號來代替它們,如此,滑動視窗中始終有最新的短語。

(1)開始

(2) 滑動視窗中沒有資料,所以沒有匹配到短語,將字元 A 標記為 A

(3)滑動視窗中有 A,沒有從緩衝區中字元(BABC)中匹配到短語,依然把 B 標記為

B

(4)緩衝區字元(ABCB)在滑動視窗的位移 6 位置找到 AB,成功匹配到短語 AB,將AB 編碼為(6,2,C),之所以是 6,是因為視窗的 A 在滑動視窗的索引[6]位置。

(5)緩衝區字元(BABA)在滑動視窗位移 4 的位置匹配到短語 BAB,將 BAB 編碼為

(4,3,A)。

(6) 緩衝區字元(BCAD)在滑動視窗位移 2 的位置匹配到短語 BC,將 BC 編碼為

(2,2,A)

(7) 緩衝區字元 D,在滑動視窗中沒有找到匹配短語,標記為 D

(8)緩衝區中沒有資料進入了,結束

6.LZ77解壓

解壓就是壓縮的逆向過程,當解碼字元標記:將標記編碼成字元拷貝到滑動視窗中,解碼短語標記:在滑動視窗中查詢相應變數,同時找到指定長短的短語進行替換。

(1)開始

(2)符號標記 A 解碼

(3)符號標記 B 解碼

(4)短語標記(6,2,C)解碼。根據 3 中的索引[6]開始,得到 AB,就是重複 AB 再加入上 C,就成了 ABABC,並且滑動視窗滑到最右邊的位置。

(5)短語標記(4,3,A)解碼

根據4中的進行標記。

(6)短語標記(2,2,A)解碼

根據5中進行標記。

(7) 符號標記 D 解碼

LZ77 壓縮演算法優點:

壓縮比相當高。也和你選擇滑動視窗大小,以及前向緩衝區大小,以及資料熵有關係。

解壓很快,每個標記都明確告知在哪個位置可以讀取。

缺點:

壓縮過程是比較耗時的,因為要花費很多時間尋找滑動視窗中的短語匹配。

6.Huffman 演算法原理

哈夫曼設計了一個貪心演算法來構造最優字首碼,被稱為哈夫曼編碼(Huffman code),其正確性證明依賴於貪心選擇性質和最優子結構。哈夫曼編碼可以很有效的壓縮資料,具體壓縮率依賴於資料本身的特性。

先介紹幾個概念:碼字、碼字長度、定長編碼與變長編碼。

碼字:每個字元可以用一個唯一的二進位制串表示,這個二進位制串稱為這個字元的碼字。

碼字長度:這個二進位制串的長度稱為碼字長度。碼字長度不變就是固定編碼,否則就是變長編碼。變長編碼可以達到比定長編碼好得多的壓縮率。其核心思想就是賦予高頻字元(出現頻率高的字元)短(碼字長度較短)碼字,賦予低頻字元長碼字。

如果一個文件中,每個字元出現的頻率基本一樣,那變長編碼的優勢在壓縮方面的優勢就不存在了。

哈弗曼會自底向上構造出一棵對應最優編碼的二叉樹,下面舉例來說明。某個檔案中有如下字元及其概率。

字元 a b c d e f

概率 45 13 12 16 9 5

構造過程如下圖所示:

每個字元都已

經按照出現頻率大小排好順序,在後續的步驟中,每次都將頻率最低的兩棵樹合併,然後用合併後的結果再次排序。注意,排序不是目的,目的是找到這時出現頻率最低的兩項,以便下次合併,gzip 原始碼中並沒有專門去“排序”,而是使用專門的資料結構把頻率最低的兩項找到即可。

在葉子節點用矩形表示,每個葉子節點包含一個字元及其頻率。中間節點用圓圈表示,包含其孩子節點的頻率之和。中間節點指向左孩子的邊標記為 0,指向右孩子的邊標記為 1。第6步驟的每個字元的編碼都是字首碼。

(1) 按照頻率大小先排序

(2)把f和e拿出來組成一個子樹,並相加,再把子樹相加的結果,再次進行排序

(3)在重複前面的排序和最小的兩個概率相加操作

(4)依次重複之前的操作

(5)依次重複之前的操作

(6)依次重複之前的操作

程式碼思想:

利用庫中的優先順序佇列實現哈夫曼樹,最後基於哈夫曼樹最終實現檔案壓縮。

(1)統計檔案中字元出現的次數,利用優先順序佇列構建 Haffman 樹,生成 Huffman 編碼。構造過程中可以使用priority_queue 輔助,每次 pq.top()都可以取出權值(頻數)最小的節點。每取出兩個最小權值的節點,就 new 出一個新的節點,左右孩子分別指向它們。然後把這個新節點 push 進優先佇列。

(2)壓縮,實際就是存入壓縮編碼。利用 Haffman 編碼對檔案進行壓縮,即在壓縮檔案中按順序存入每個字元的 Haffman 編碼。

(3)將檔案中出現的字元以及它們出現的次數寫入配置檔案中,以便後續壓縮使用。

(4)解壓縮:利用配置檔案重構 Haffman 樹,對檔案進行減壓縮

後面的文章會來詳細分析程式碼:

7.deflate 採用的改進版 LZ77 演算法

三個位元組以上的重複串才進行編碼,否則不進行編碼:

為什麼最小匹配3個位元組?

gzip 中,<匹配長度,到匹配串開頭的距離>對中,"匹配長度"的範圍為 3-258,也就是 256 種可能值,需要 8bit來儲存。"到匹配串開頭的距離"的範圍為 0-32K,需要 15bit 來儲存。所以一個<匹配長度,到匹配串開頭的距離>對需要 23 位,差一位 3 個位元組。如果匹配串小於 3 個位元組的話,使用<匹配長度,到匹配串開頭的距離>對進行替換,不但沒有壓縮,反而還會增大。所以儲存<匹配長度,到匹配串開頭的距離>對所需要的位數,決定了最小匹配長度至少要為 3 個位元組。

deflate 無失真壓縮解壓演算法

先 LZ77 壓縮,再用huaffman編碼。

deflate 中的 huffman 編碼:

對 LZ77 得到的壓縮後結果,需要統計字元生成編碼表 huffmantree(指示每個編碼代表什麼字元),根據碼錶對內容進行編碼,具體的壓縮大小在於精細分配結構體的位域來實現 Huffman 編碼的壓縮效果的。編碼表huffmantree和編碼後的data都一起放置在檔案中。

deflate 中的解壓:

讀取二進位制檔案,構建huffmantree 表,讀取資料根據huffmantree 生成字元。LZ77 解碼需要對視窗生成雜湊表(陣列+連結串列),對解壓的資料,進行搜尋匹配拷貝替換為相應的串即可。

8.gzip 格式分析

GZIP 本身只是一種檔案格式,其內部通常採用 DEFLATE 資料格式,而 DEFLATE 採用 LZ77 壓縮演算法來壓縮資料。GZIP 檔案由 1 到多個“塊”組成,實際上通常只有 1 塊。每個塊包含頭、資料和尾三部分。塊的概貌如下:

gzip = gzip 頭 + deflate 編碼的實際內容 + gzip 尾

zlib = zlib 頭 + deflate 編碼的實際內容 + zlib 尾

(1)頭部分

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 位元組。更改時間。

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)

(2)資料部分

DEFLATE 資料格式,包含了一系列子資料塊。結構如下:

BFINAL:1 位元。0 - 還有後續子塊;1 - 該子塊是最後一塊。BTYPE:2 位元。00 -- 不壓縮,01--靜態Huffman編碼壓縮。10--動態Huffman 編碼壓縮。11--保留。

(3)尾部分

CRC32:4 位元組。原始資料的32位校驗和。ISIZE:4 位元組。原始資料長度的低32位。

GZIP 中位元組排列順序是 LSB 方式,即 Little-Endian,與 ZLIB 中的相反。

9.zlib 庫 API 分析

(1)下載原始碼包

下載 http://www.zlib.net/,選擇 zlib-1.2.11.tar.gz

(2)下載

wget http://www.zlib.net/zlib-1.2.11.tar.gz

(3)解壓

tar -zxvf zlib-1.2.11.tar.gz

(3)進入目錄

cd zlib-1.2.11

(4)配置

./configure

(5)編譯

make

(6)檢查,要全部為 yes

make check

(4)安裝

sudo make install

基礎資料結構:

壓縮函式:

deflateInit :引數比較少,裡面實際就是呼叫deflateInit2

deflateInit2:

deflate : 壓縮函式。

deflateEnd :壓縮完成後,釋放空間,注意,僅僅釋放deflateInit 中申請的空間,自己申請的空間還是要自己釋放。

compress :全部附加選項預設壓縮,內部呼叫 compress2。

compress2 : 帶 level 的壓縮方式。

deflateInit2 : 初始化函式

功能:壓縮初始化內部流狀態,zalloc,zfree和opaque欄位必須在呼叫之前初始化,若zalloc 和 zfree 被初始化為 Z_NULL,deflateInit會更新它們而使用預設的分配函式。

壓縮級別為Z_DEFAULT_COMPRESSION,使用0到9之間的數,1表示最快速度的壓縮,9表示最優壓縮,0表示不做任何壓縮,Z_DEFAULT_COMPRESSION是速度和最優壓縮的折衷。

level: 壓縮的等級,目前有四個值

#define Z_NO_COMPRESSION 0 //不壓縮

#define Z_BEST_SPEED 1 //速度優先,可以理解為最低限度的壓縮.

#define Z_BEST_COMPRESSION 9 //壓縮優先,但是速度會有些慢

#define Z_DEFAULT_COMPRESSION (-1) //預設選項,compress 裡面用的就是這個選

返回值:

成功返回Z_OK,沒有足夠的記憶體則返回 Z_MEM_ERROR,若壓縮級別無效,返回Z_STREAM_ERROR,版本不相容則返回 Z_VERSION_ERROR。如果沒有錯誤資訊則 msg 被設定為 0。

z_stream:這個是壓縮上下文。

strm.zalloc = NULL;

strm.zfree = NULL;

strm.opaque = NULL;

strm.next_in = 你的待壓縮資料

strm.next_out = 壓縮以後資料儲存的 buffer

strm.avail_in = 待壓縮資料的長度

strm.avail_out = 壓縮資料儲存 buffer 的長度.

method: 值只有一個,當前唯一的 defalte 壓縮方法,用於以後擴充套件

#define Z_DEFLATED 8

/* The deflate compression method (the only one supported in this version)

*/

windowBits: 視窗位元數

-(15 ~ 8) : 純 deflate 壓縮

+(15 ~ 8) : 帶 zlib 頭和尾

> 16 : 帶 gzip 頭和尾

memLevel: 目前只有一個選項,MAX_MEM_LEVEL,無非是執行過程中對記憶體使用的限制.

/* Maximum value for memLevel in deflateInit2 */

#ifndef MAX_MEM_LEVEL

# ifdef MAXSEG_64K

# define MAX_MEM_LEVEL 8

# else

# define MAX_MEM_LEVEL 9

# endif

#endif

strategy :用於調整壓縮演算法,直接給預設就行 Z_DEFAULT_STRATEGY

#define Z_FILTERED 1 //用於由 filter(或者稱為 predictor)生成的資料

#define Z_HUFFMAN_ONLY 2 //用於強制哈夫曼編碼(不做字元匹配)

#define Z_RLE 3 //限制匹配長度為 1

#define Z_FIXED 4 //阻止使用動態哈夫曼編碼,從而允許獲得更簡單的解碼

#define Z_DEFAULT_STRATEGY 0 //用於普通資料

Z_FILTERED,用於由 filter(或者稱為 predictor)生成的資料.過濾的資料包含很多小的隨機資料。這種情況下,壓縮演算法能夠獲得更好的壓縮效果。該選項可以強制更多的哈夫 曼 編 碼 和 更 少 的 字 符 匹 配 。 有 時 候 可 以 作 為 Z_DEFAULT_STRATEGY 和

Z_HUFFMAN_ONLY 的折衷。

Z_FIXED,阻止使用動態哈夫曼編碼,從而允許獲得更簡單的解碼。

strategy 引數隻影響壓縮比,而不會影響到壓縮輸出的正確性,因此沒有正確的設定也不要緊

deflate函式儘可能壓縮資料,當輸入快取為空或輸出緩衝滿了就會停止,帶來輸出延遲,除非強行重新整理緩衝區。

deflate 會執行下面的一個或者兩個動作都執行,avail_in或avail_out 被設定,使用提供更多輸入資料和消耗更多輸出資料的方式,

(1)從 next_in 開始壓縮輸入資料,進而更新next_in 和 avail_in。如果不是所有輸入資料可以被處理(緩衝沒有足夠的空間),next_in和avail_in會更新,當再次呼叫deflate()函式時輸入資料會從這一點開始被處理。從而更新avail_in 或 avail_out;avail_out 在函式呼叫之前千萬不能為 0。應用程式可以隨時消耗被壓縮的輸出資料。如輸出快取滿或每次呼叫deflate()之後,若deflate返回Z_OK並avail_out 為 0 時,deflate()必須再次被呼叫(說明輸出快取區還有資料應該被讀取)

(2)next_out 開始提供更多輸出資料從而更新 next_out 和 avail_out,如果 flush引數不是為 0 的化這個動作是強制性的,經常性的強制重新整理快取會降低壓縮比率,只有必要的時候去設定這個引數。

Int flush 的引數:

Z_NO_FLUSH:允許壓縮演算法累計產生多少資料再輸出,以達到壓縮率最高。

Z_SYNC_FLUSH:將所有等待輸出的資料重新整理到輸出緩衝區,以位元組為邊界進行對齊。這個可能會降低壓縮演算法的效率,只用於必要的時候。

Z_FINISH:輸入和待輸出的資料都被處理完,則返回 Z_STREAM_END。如果返回 Z_OK or Z_BUF_ERROR 則需要再次呼叫 Z_FINISH 直到返回 Z_STREAM_END。

deflateEnd:資源釋放

壓縮完成後,釋放空間,僅僅釋放deflateInit 中申請的空間,自己申請的空間還是要自己釋放。

解壓函式

inflateInit :解壓初始化函式,內部呼叫的inflateInit2。

inflateInit2 :解壓初始化的基礎函式

infalte :解壓函式

inflateEnd :同deflateEnd作用類似

uncompress :解壓縮

解壓初始化:

strm:和deflate 一樣,初始化三個回撥。

windownBits :含義和deflateInit2 一樣

解壓函式:

z_streamp : 四個引數

strm.next_in = 待解壓資料

strm.next_out = 解壓以後資料儲存的 buffer

strm.avail_in = 待解壓資料的長度

strm.avail_out = 解壓資料儲存 buffer 的長度

flush :如果是 Z_NO_FLUSH,說明還有資料沒有解壓。

如果是Z_FINISH說明這是最後一包待解壓的資料

資源釋放:

10.gzip 壓縮提升網站速度

講講對於Nginx而言,怎樣去優化。

# 開啟 gzip
gzip on

# 啟用 gzip 壓縮的最小檔案,小於設定值的檔案將不會壓縮
gzip_min_length 1k;

# gzip 壓縮級別,1-9,數字越大壓縮的越好,也越佔用 CPU 時間,後面會有詳細說明
gzip_comp_level 1;

# 進行壓縮的檔案型別。javascript 有多種形式。其中的值可以在 mime.types 檔案中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml
text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject
font/ttf font/opentype font/x-woff image/svg+xml;

# 是否在 http header 中新增 Vary: Accept-Encoding,建議開啟

gzip_vary on;

# 禁用 IE 6 gzip

gzip_disable "MSIE [1-6]\.";

#設定壓縮所需要的緩衝區大小
gzip_buffers 32 4k;

# 設定 gzip 壓縮針對的 HTTP 協議版本,沒做負載的可以不用
# gzip_http_version 1.0;

# 開啟快取
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
access_log off;
expires 2d;
}

location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {
access_log off;
expires 24h;
}

location ~* ^.+\.(html|htm)$ {
expires 1h;
}

location ~* ^.+\.(eot|ttf|otf|woff|svg)$ {
access_log off;
expires max;
}

# 格式
# expires 30s;
# expires 30m;
# expires 2h;
# expires 30d;

以上單獨引數的說明:

gzip on:

開啟或關閉gzip

Syntax: gzip on | off;

Default: gzip off;

Context: http, server, location, if in location

gzip_buffers:

用於處理請求壓縮的緩衝區數量和大小。如32 4K表示按照記憶體頁為單位,建議使用預設值。

Syntax: gzip_buffers number size;

Default: gzip_buffers 32 4k|16 8k;

Context: http, server, location

gzip_comp_level

設定gzip壓縮級別,級別越低壓縮速度越快,檔案壓縮比越小。反之速度越慢檔案壓縮比越大。

Syntax: gzip_comp_level level;

Default: gzip_comp_level 1;

Context: http, server, location

gzip_disable

通過表示式,表明哪些 UA 頭部使用 gzip 壓縮。

Syntax: gzip_disable regex ...;

Default: —

Context: http, server, location

This directive appeared in version 0.6.23.

gzip_min_length

表示當資源大於該長度時,才進行壓縮,資源大小取響應頭中的Content-Length 進行比較,如果響應頭不存在 Content_length 資訊,該限制引數對於這個響應包是不起作用的;這個值不建議設定太小,如果太小,一些本來很小的檔案,經過壓縮,反而變大,建議1k起,當然也需要根據自己實際的情況來去設計。

Syntax: gzip_min_length length;

Default: gzip_min_length 20;

Context: http, server, location

gzip_http_version

識別 http 協議的版本,早期的瀏覽器不支援 gzip 壓縮,使用者會看到亂碼。預設在http1.0的協議下不開啟gzip壓縮。

Syntax: gzip_http_version 1.0 | 1.1;

Default: gzip_http_version 1.1;

Context: http, server, location

gzip_proxied

Nginx 作為反向代理的時候啟用:

off – 關閉所有的代理結果資料壓縮

expired – 如果 header 中包含 "Expires" 頭資訊,啟用壓縮

no-cache – 如果 header 中包含 "Cache-Control:no-cache" 頭資訊,啟用壓縮

no-store – 如果 header 中包含 "Cache-Control:no-store" 頭資訊,啟用壓縮

private – 如果 header 中包含 "Cache-Control:private" 頭資訊,啟用壓縮

no_last_modified – 啟用壓縮,如果 header 中包含 "Last_Modified" 頭資訊,

啟用壓縮

no_etag – 啟用壓縮,如果 header 中包含 "ETag" 頭資訊,啟用壓縮

auth – 啟用壓縮,如果 header 中包含 "Authorization" 頭資訊,啟用壓縮

any – 無條件壓縮所有結果資料

Syntax: gzip_proxied off | expired | no-cache | no-store | private | no_last_modified

| no_etag | auth | any ...;

Default: gzip_proxied off;

Context: http, server, location

gzip_types

設定需要壓縮的 MIME 型別,如果不在設定類型範圍內的請求不進行壓縮。根據這個值進行匹配。"text/html"型別總是會被壓縮。

Syntax: gzip_types mime-type ...;

Default: gzip_types text/html;

Context: http, server, location

gzip_vary

在響應頭新增

AcceptEncoding:gzip,對於本身不支援agip壓縮的客戶端瀏覽器有用。

Syntax: gzip_vary on | off;

Default: gzip_vary off;

Context: http, server, location

本篇文章就分析到這裡,歡迎點贊,收藏,分享。

轉自https://www.toutiao.com/i6849516963987718663/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1594863398&app=news_article&utm_source=weixin&utm_medium=toutiao_android&use_new_style=1&req_id=202007160936380101941000854F41A7DE&group_id=6849516963987718663