引言
無損壓縮算法可行的基本原理是,任意一個非隨機文件都含有重復數據,這些重復數據可以通過用來確定字符或短語出現概率的統計建模技術來壓縮。統計模型可以用來為特定的字符或者短語生成代碼,基於它們出現的頻率,配置最短的代碼給最常用的數據。這些技術包括熵編碼(entropy encoding),游程編碼(run-length encoding),以及字典壓縮。運用這些技術以及其它技術,一個8-bit長度的字符或者字符串可以用很少的bit來表示,從而大量的重復數據被移除。
歷史
直到20世紀70年代,數據壓縮才在計算機領域開始扮演重要角色,那時互聯網變得更加流行,Lempel-Ziv算法被發明出來,但壓縮算法在計算機領域之外有着更悠久的歷史。發明於1838年的Morse code,是最早的數據壓縮實例,為英語中最常用的字母比如"e"和"t"分配更短的Morse code。之后,隨着大型機的興起,Claude Shannon和Robert Fano發明了Shannon-Fano編碼算法。他們的算法基於符號(symbol)出現的概率來給符號分配編碼(code)。一個符號出現的概率大小與對應的編碼成反比,從而用更短的方式來表示符號。
兩年后,David Huffman在MIT學習信息理論並上了一門Robert Fano老師的課,Fano給班級的同學兩個選項,寫一篇學期論文或者參加期末考試。Huffman選擇的是寫學期論文,題目是尋找二叉編碼的最優算法。經過幾個月的努力后依然沒有任何成果,Huffman決定放棄所有論文相關的工作,開始學習為參加期末考試做准備。正在那時,靈感爆發,Huffman找到一個與Shannon-Fano編碼相類似但是更有效的編碼算法。Shannon-Fano編碼和Huffman編碼的主要區別是構建概率樹的過程不同,前者是自下而上,得到一個次優結果,而后者是自上而下。
早期的Shannon-Fano編碼和Huffman編碼算法實現是使用硬件和硬編碼完成的。直到20世紀70年代互聯網以及在線存儲的出現,軟件壓縮才被實現為Huffman編碼依據輸入數據動態產生。隨后,1977年Abraham Lempel 和 Jacob Ziv發表了他們獨創性的LZ77算法,第一個使用字典來壓縮數據的算法。特別的,LZ77使用了一個叫做slidingwindow的動態字典。1778年,這對搭檔發表了同樣使用字典的LZ78算法。與LZ77不同,LZ78解析輸入數據,生成一個靜態字典,不像LZ77動態產生。
法律問題
Deflate的崛起
當前的一些歸檔軟件
壓縮技術
有許多不同的技術被用來壓縮數據。大多數技術都不能單獨使用,需要結合起來形成一套算法。那些能夠單獨使用的技術比需要結合的技術通常更加有效。其中的絕大部分都歸於entropy編碼類別下面,但其它的一些技術也挺常用,如Run-Length Encoding和Burrows-Wheeler Transform。
Run-Length Encoding
Run-Length Encoding是一個非常簡單的壓縮技術,把重復出現的多個字符替換為重復次數外加字符。單個字符次數為1。RLE非常適合數據重復度比較高的數據,同一行有很多像素顏色相同的漸進圖片,也可以結合Burrows-Wheeler Transform等其它技術一起使用。
下面是RLE的一個簡單例子:
輸入: AAABBCCCCDEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA輸出: 3A2B4C1D6E38A
Burrows-Wheeler Transform
Burrows-Wheeler Transform是1994年發明的技術,目的是可逆的處理一段輸入數據,使得相同字符連續出現的次數最大化。BWT自身並不做任何的壓縮操作,僅簡單地轉化數據,讓Run-Length Encoder等壓縮算法可以更有效的編碼。
Entropy Encoding
數據壓縮中,平均來說為了表示一個字符或短語,Entropy意味着所需要的最少bit數。一個基本的entropy編碼器包括一個分析模型以及一套編碼。輸入文件被解析,並產生一個由字符出現概率組成的統計模型。然后,編碼器可以利用該統計模型去決定該給每一個字符多少個bit,從而使得最常用的字符用最短的編碼,反之最不常用的字符用最長的編碼。
Shannon-Fano Coding
這是最早的壓縮技術,於1949年由Claude Shannon和Robert Fano發明。這個技術的其中一個步驟是產生一個代表字符出現概率的二叉樹。字符以這樣一種方式排序,出現得越頻繁的字符越靠近樹的頂端,越不常見的越靠近樹的底部。
一個字符對應的編碼通過搜索Shannon-Fano來獲得,此外,左分支后面加0,右分支加1。例如,"A"是兩個左節點后接一個右節點,那么對於的編碼為"0012"。Shannon-Fano coding不總是能夠產生最優的編碼,主要是由於二叉樹是自下而上構建的。由於這個原因,使用的較多的還是對於任意輸入都能夠得到最優編碼的Huffman coding。
Huffman Coding
Huffman Coding是另外一個entropy coding的例子,與Shannon-Fano Coding非常的相似,只是為了產生最優編碼二叉樹是自上而下構建的。