日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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)一旦數據通過緩沖區,那么它將移動到滑動窗口中,并變成字典的一部分?;瑒哟翱谛枰A設一個定值。

(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

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

分享到:
標簽:數據壓縮
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定