壓縮文件為什麼不能一層層壓縮自身?

這是我很多年前的一個想法。
假設壓縮比是50%,例如:把abc.rmvb(1G)壓縮成1.rar(512M)。然後再把1.rar壓縮成2.rar(256MB),如此類推。。


因為從理論上來講,所有的信息如果想要表達一個特定地,不會有歧義的含義,在數學上都會有一個最小的「信息熵」(信息量)才可以。

如果僅僅就理論來舉個簡單的例子的話,經典的連續數學理論會認為,如果用135膠捲相機拍出來的膠捲能沖洗出一張5寸的照片,而裡面的所有細節都可以得到保留,那麼我們在太空上對著地球用相機拍下一張膠片,然後想辦法盡量將這張膠片放大,就可以看到天安門廣場上的行人。

你會認為這是玩笑是嗎?事實上,用谷歌地球上的資料庫,不就拼成了一張這樣的照片么?但是其代價,絕不是一張膠片能包含的信息量,而是上百個TB的數據。

這意味著什麼?意味著信息的本質是離散而不是連續的,如果要想看出「地球是個圓的」,也許巴掌大的照片就夠了,但是想要看到地球上更清晰的細節,則沒有捷徑可走,只有增加照片的信息量——換言之,信息量和能量一樣,是守恆的。

那麼壓縮文件的原理是什麼?

就是利用「一個文件的體積與它的信息量並不相等,而且它的體積肯定要大於它的信息量」的特點,使用演算法「將一個文件所包含的同樣的信息量用更少的容量來描述」。

舉個簡單的例子,一張大小為 3x3 的圖片是純黑色的,那麼我們用兩種方法來描述這張圖片:

  1. 這張圖片是3x3的,且他們的顏色分布為:{純黑色,純黑色,純黑色, 純黑色, 純黑色, 純黑色, 純黑色, 純黑色, 純黑色}
  2. 這張照片是3x3的,且它們的顏色全部是{純黑色}

可以明顯看出,第二種描述的方法比第一種描述的方法佔用的空間(容量)要小得多。無損圖像壓縮演算法中的「行程演算法」就部分借鑒了這樣的思想。

再舉一個例子,讓我們來看看,在英語中為何會出現一種這樣情況——使用頻率越高的單詞,其包含的字母越少,而使用頻率越低的單詞,其包含字母越多?

比如說在 Elvis Costello 的一首歌《she》中(感謝 @姚沛然 指出錯誤),我們把英語中的「she)」統一換成一個長一些的單詞,比如說「輕浮的女人flibbertigibbet,僅僅是隨意找一個比較長的單詞,並非故意「政治不正確」XD)」那麼起後果就是這樣的:
修改前:

she may be the face I can"t forget , a trace of pleasure I regret, may be my treasure or the price I have to pay she may be the song that Summer sings, may be the chill that autumn brings, may be a hundred different things, within the measure of the day. she may be the beauty or the beast, may be the famine or the feast, may turn each day into heaven or a hell, she may be the mirror of my dream a smile reflected in a stream, she may not be what she may seem, inside her shell, she who always seems so happy"n proud, who"s eyes can be so private and so proud, no one"s allowed to see them when they cry, she may be the love that can and hope to last, may come to me from shadows of the past, that I remember till the day I die, she may be the reason I survive, the why and wherefor I"m alive the one I"ll care for through the rough and rainy years, me I"ll take her laughter and her tears, and make them all my souvenirs, for where she goes I got to be the meaning of my life is she she she

修改後:

flibbertigibbet may be the face I can"t forget , a trace of pleasure I regret, may be my treasure or the price I have to pay flibbertigibbet may be the song that Summer sings, may be the chill that autumn brings, may be a hundred different things, within the measure of the day. flibbertigibbet may be the beauty or the beast, may be the famine or the feast, may turn each day into heaven or a hell, flibbertigibbet may be the mirror of my dream a smile reflected in a stream, flibbertigibbet may not be what flibbertigibbet may seem, inside her flibbertigibbetll, flibbertigibbet who always seems so happy"n proud, who"s eyes can be so private and so proud, no one"s allowed to see them when they cry, flibbertigibbet may be the love that can and hope to last, may come to me from shadows of the past, that I remember till the day I die, flibbertigibbet may be the reason I survive, the why and wherefor I"m alive the one I"ll care for through the rough and rainy years, me I"ll take her laughter and her tears, and make them all my souvenirs, for where flibbertigibbet goes I got to be the meaning of my life is flibbertigibbet flibbertigibbet flibbertigibbet

修改後與修改前的歌詞相比,整整長了一行半。可是這兩首歌詞要表達的意思是一模一樣的啊!那麼用更短的字母來描述使用更頻繁的含義是不是就意味著,這本書的厚度可以減少?你猜對了,這就是著名的無損壓縮演算法「霍夫曼編碼」的基本原理。

說了這麼多,就是想解釋一下,壓縮演算法只不過是想將「文件容量大於其所含信息量的那一部分」當成海綿中的水擠出來。但是總不能擠到連海綿都被擠消失的地步。你要問怎樣判斷一個文件的信息量有多少?一個粗略的解釋就是,將所有計算機上的文件都看作是數學上0和1的排序的話,通過數學方法就可以計算出這個數列的有序度。這個有序度就是指不管採用什麼辦法,能夠翻譯出這組序列最少最少,需要一個多長的序列,才有實力做到這一點。具體如何計算嘛...略微複雜,有興趣的同學還是去看看相關的資料叭 XD

P.S. @曹夢迪 的答案解釋地非常形象到位,強烈推薦。


首先科普一下壓縮分為兩種:無損壓縮和有損壓縮。
無損壓縮的一個類比是侯寶林的相聲:
「這是誰啊?」「是我您哪。」「你幹嗎去?」「我撒泡尿。」 -(壓縮)-&>「誰?」「我!」「抓?」「尿!」
把複雜的話用簡單的話說出來,但保持原有的意思,這就是無損壓縮的基本原理。
關於什麼是「保持原有的意思」,對這個問題,資訊理論中有個嚴格的概念叫做「信息量保持不變」,嚴格的定義在此就不展開討論了,大概類比一下就是「能夠毫無困難地恢復成原有信息」,再舉個例子
「我家的門是紅色的」-&>「我家門紅色」,你只看後一句就知道前一句所要說的全部內容,這個就是毫無困難地、唯一地恢復成原有信息,但是
「我家的門是紅色的」-&>「我家門色」,這時候你只看到後一句就永遠沒有辦法知道門到底是什麼顏色的,這個就不屬於「保持原有意思」。
那麼「保持原有意思」的壓縮能不能無限壓縮呢?顯然不能,比如上面的例子,你還有更簡單的辦法說出「誰?」「我。」「抓?」「尿!」么?漢字的範疇估計是沒有了,在計算機中你可以用更高效的編碼(比如霍夫曼編碼)的辦法來壓縮到更少的位元組,但是,這個也是有極限的,就好像漢字里的「誰?」「我。」「抓?」「尿!」一樣。為什麼呢?我們來用反證法證明之:假定壓縮不存在極限,任意大小的文件都可以壓縮到n個比特,那麼我們知道,n個比特的二進位數最多表示2^n個不同的數字,而「任意大小的文件」有多少種選擇呢?顯然是無窮種。將無窮種的「任意大小的文件」,壓縮為2^n個不同的數字,那麼必然存在多個文件被壓縮成一個數字的情況。也就是說,對於壓縮後的一個數字,可以恢復成的原有信息是很多個的,而這和「毫無困難地、唯一地恢復成原有信息」是矛盾的。所以假設是錯誤的,無損壓縮必然是存在一個極限的,而不能無限縮小下去。

那麼壓縮是不是一定要保持原有的意思呢?顯然不是,再舉個例子,我們知道名著有「縮寫本」,一部百萬字的名著可以縮寫成幾十萬字,但是能讓你看了之後仍知道大概的故事梗概,這就是有損壓縮。其原理和上面的「重寫」不同,是「刪去」,比如一首歌曲,錄製的時候除了有伴奏和演唱的聲音之外,還有歌手的呼吸聲、錄音設備的摩擦聲、空氣流動的聲音等等,有損壓縮的原理就是在錄音之中把這些「無關緊要」的信息去掉。目前常用的音頻、圖像和視頻編碼方法絕大部分有損壓縮的。顯然,這個壓縮的程度取決於你怎樣定義「無關緊要的信息」:如果你在看一場電影的時候,覺得整個電影都極度無聊,只有某一個三秒鐘的場景中閃過的一個美女是你覺得值得看的,那麼整個電影基本上就都是「無關緊要的信息了」,用這個標準,一場電影可以被壓縮為幾百K(那個美女的圖片的大小)。但是這在大多數人看來,已經不是原來意義上的電影了。

所以,從理論上說的確可以一次又一次,越壓縮越小的可能,但是只有一種情況,就是不斷地提高壓縮時的損失率,最終,當你捨棄所有的信息的時候,你可以把文件壓縮到0位元組。但是這種「為了壓縮而壓縮」的做法,是沒有任何實際意義的。


你的想法很好,軟體業就缺你這樣有創造性思維的人才

按照你的想法壓縮下去之後,最終成為1 byte也就是8 bit,然後成為1 bit也就是1位。1位有兩個狀態,進一步壓縮成一個狀態,一個狀態毋需表示,所以也就不用存儲了。
看到沒有,這就是逆向的道德經,萬物成8卦,8成2,2成1,1從有到無。

可惜,世人都不理解大道。

因為他們還沒找到解壓的辦法。


這個問題最簡單的解釋是,單位數據量能攜帶的信息的最大熵是固定的。

無損壓縮的原理就是對於熵小的文件進行處理,將其熵提高到最大程度,然後文件體積就小了。

由於壓縮文件的熵通常已經達到或者接近最大值,因而使用無損壓縮演算法無法對其進一步壓縮。

因為在物質守恆的前提下,熵只能增加不能減少。因而要想進一步壓縮,只能削減信息,成為有損壓縮。


我打個比方,一個麵包和餅乾,現在給你壓縮。你想,如果麵包能達到壓縮至50%的話,同等條件下,餅乾能被壓縮那麼多麼?不行吧。
那麼現在想想,如果壓好的麵包團,你用同樣的力氣,再去壓他,他還會變小么?也不會吧。
======
打比方結束,下面說學術點兒的:
信息是有測量尺度的,叫做信息熵,他是衡量信息量的大小的。我們之所以說一段信息能夠被壓縮,那是用於表示該信息的數據過多了,實際上對於一定信息熵的信息,我們可以計算出用以表示他的數據量下限的,所以如果實際數據量遠大於理論下線的話,理論上來說我們是可以用更少的數據來表示同樣的信息量的。
當原始數據被壓縮之後,他的數據量基本上更加接近表示該信息量數據的下限了,想要進一步壓縮也只能無限逼近這個下限而不能更小了。所以,壓縮過後的數據,是很難再壓縮得更小了。這就和之前,壓縮過的麵包難以再壓縮小一樣的道理。


因為數學意義上的"壓縮"演算法並不存在,更不要說具有50%壓縮比的了。

我們所謂的壓縮演算法其實應該叫轉編碼演算法。這類轉編碼演算法叫壓縮演算法只是因為它能壓縮很多人類感興趣的文件。同時,任何一個壓縮演算法都會膨脹那些人類不感興趣的文件。

數學一點說,如果定義文件為一段有限長度的位元組串。那麼把所有可能的文件放在一起可以得到一個文件空間。轉編碼演算法就是一個文件空間到自身的一一對應。由於文件長度是離散的,很容易得到對於任意一個轉編碼演算法,如果它能壓縮某個文件,那麼必然存在一個長度小於原文件的新文件,使得轉編碼演算法讓這個新文件變大。

如果不存在數學意義上的「壓縮」演算法,那麼人類所說的壓縮演算法為什麼還會有用呢?因為實際上人類感興趣的文件在所有數學上可能的文件中所佔的比例實在是太小太小太小了。所以即使那些最高級的"壓縮"演算法仍然會讓很多很多文件變大,這也並沒有什麼關係,因為那些文件很少被人類用到。或者至少人們會為那些特定類型的文件換一個更適合的「壓縮」演算法。

你可以很容易的找到與「人類感興趣的文件在所有數學上可能的文件所佔的比例」相關的東西來感受下這個比例有多麼的小。這包括
無限猴子定理:讓一個猴子在打字機上亂打字,那麼只有給定足夠長時間,它幾乎必然能夠打出莎士比亞的全部著作。即使這個足夠長時間是非常非常的長。
通用唯一識別碼(UUID):要把所有數學上可能的16個位元組文件全部羅列起來,每秒羅列100萬個文件,需要100億年。


這個問題涉及到資訊理論的概念。
在資訊理論中,數據有一個固有的特性叫做熵,或可以稱為數據混亂的程度。舉例來說,如果一枚硬幣,落地時隨機一面朝上,其正反面各佔50%,那麼每一次投擲硬幣的結果的信息量為 -lb0.5=1bit(lb 表示取以2為底的對數);但如果這枚硬幣其正面佔75%反面佔25%,顯然投出反面的機會更小,因此一旦出現了反面,能提供的信息的信息量也要大於正常情況,這時投出反面的信息量為 -lb0.25=2bit,而正面只有 -lb0.75=0.415bit;這時如果我們以原來的比例記錄每一次投擲的結果,同樣1bit的數據,其中75%的可能性信息量只有0.415bit,而25%的可能性信息有2bit,於是平均起來1bit的數據只存儲了 0.75*0.415+0.25*2=0.811bit,數據攜帶的信息量小於數據的大小。這時我們便可以選擇用更多的數據來記錄信息量大的信息,而更少的數據來記錄信息量小的信息。這正是壓縮的本質。
從上面可以看出,實際上壓縮的理論極限即是數據固有的熵,亦即數據所攜帶的信息本身的信息量,任何壓縮演算法都不可能突破這一極限,使壓縮得到的數據大小小於數據的熵。換言之,如果經過一個壓縮演算法得到的數據其大小小於原數據的熵,那麼這個演算法一定丟失了一部分信息減小了熵,這就不是一個無損的壓縮演算法。


中國最早的壓縮格式應該是成語


假設壓縮比是50%

不存在這種東西。


所有無損壓縮技術都會越壓越像沒規律的亂碼,越像沒規律的亂碼就越無法壓縮,到最後你無論怎麼壓縮都是101%的壓縮率。

比如我現在要記住18988888888這串電話號碼,總共11個音節。現在我不想記那麼多數字,可以記作「189跟八個八」,這樣就只剩下7個音節。但我還是覺得太長,於是我就記作「ct5八個八」,表示中國電信五個號碼段中最高位的189然後後面跟八個八,壓縮到了6個音節。再繼續壓縮就是「15八」,只有3個音節,意思是中國第一大運營商的第五個號碼段後面余位用8補全。到最後壓到極限就只能是記作「5八」兩個音節,即「各號碼段按中國運營商排名的順序合併中的第五個號碼段後面余位用8補全」,無論如何也無法壓縮到只有1個音節了。

也就是說,使用不同的壓縮演算法「一層層」壓縮可能可以繼續縮小佔用空間,但並不可能無限壓縮。


實際上並不存在所謂的「壓縮」演算法,只有「編碼」演算法而已。壓縮是無法100%保證的(有時會膨脹)

有些演算法有好的「壓縮比」是因為輸入數據有特徵,被編碼演算法利用了而已


醜小鴨!?你可千萬別小看了它!這可是史上最強之圖片!
請大家滑鼠指著圖片的時候,用 滑鼠另存為保存,然後將保存的圖片擴展名改為rar(網站圖片可能會處理,大家可以到此處下載:http://pan.baidu.com/netdisk/singlepublic?fid=559977_2803047645)。解壓之後你會得到3個可執行動畫文件。每個動畫都有15~30分鐘的時間,但是大小卻只有64K!
其中《彗星撞地球》是最為經典之作,其64K的大小竟然演示了近30分鐘的不重複3D影片,還包括震撼的音效。Warez組織把將1.9G的數據量壓縮為64K,相當於壓縮了25萬倍。
64K能夠幹什麼?VisualStudio生成一個空的exe需要40k,一首音樂需要4000k,一張圖片也需要30K,而這64K卻給我們帶來了震撼!實在是一個技術的奇蹟!
技術的力量實在令人感到畏懼!
PS:系統必須安裝有Directx8.0才能播放。請使用高版本Winrar解壓。
因為解壓後是一些可執行文件,一些安全軟體可能會提示,請放心打開。
PPS:經過求證,這個圖片的原理應該是利用GPU進行實時渲染的程序庫,對系統API調用,通過GPU渲染表現出3D動畫效果.答案可以算是有點跑題。。。所以還是摺疊了吧。


能把海綿里的水擠出來,不能把海綿擠沒了


如果壓完還能再壓。。那為什麼不一開始就多壓幾遍鬧。。(≧?≦)


如果是有損壓縮的話,你壓縮什麼最後都會得到兩個位元組:


假設壓縮比是50%……
這個假設是不成立的,沒有壓縮軟體能把不同的文件壓縮成固定的壓縮比,壓縮比要看文件代碼自身的特點。所以這個類推也是不可能成立的。


這其實是涉及一個本質的問題, 即:

  信息與物質一樣, 也是實在的, 它也有度量, 如同質量的是物質密度的度量. 信息也存在一種度量,叫信息熵

任何一條信息, 可以用任何你想得到的方式, 工具來表示, 但它有一個臨界的度量值, 這是它本質固有的, 不跟你選擇的工具或方法而異. 

比如, 你要表示一個二元的信號量, 即只有兩個狀態, 可以用下面的任一方式來表示:

  1. 一盞燈來表示: 暗表示關, 亮表示開.
  2.  也可以用兩盞燈來表示, 紅的表示關, 綠的表示開. 
  3.  甚至你可以用三盞燈來表示, 比如紅紅紅表示關, 綠綠綠表示開.
  4. . ...
  5. . ...

可以想見, 你可以用任何你能想像的數量的燈來表示這個信息. 但是, 無論多少, 都只表示了兩種狀態. 這本質地暗含: 這個信息最少需要用1盞燈來表示, 或者說1個單位的信息熵.


那如果信息是個三元量, 有開, 關, 半開半關,
則顯然, 1盞燈(假定這燈非亮即滅)是無論如何也表示不了的. 容易證明, 至少需要2盞燈.


由此, 可以發現, 任何一條信息, 都存在一個臨界的度量, 用少於這個度量的方式, 你勢必無法完全地表示這個信息, 換句話說, 你會丟失信息.


所以, 你可以壓縮信息, 就如同開始用10盞燈來表示開和關兩個狀態, 壓縮後變成只用1盞燈來表示, 但無法再繼續減少燈的數量了. 對於壓縮, 同理.


當然可行,我一直都是這樣壓縮文件的,唯一的問題是最後無論如何都會壓縮成一個位元組:42


剛剛看了點資訊理論,可以來回答下這個問題。
(本回答只談論無失真編碼)
根據香農第一定理

如果信源編碼碼率(編碼後傳送信源符號所需的比特數)不小於信源的熵,就存在無失真編碼;反之,不存在無失真編碼。即:
Rgeq H Leftrightarrow 存在無失真信源編碼
R為信源編碼碼率,H為信源的熵。

也就是說呢,無論何種壓縮方法,要保證編碼後的無失真,即壓縮文件解碼後可以恢復其自身,那麼壓縮的極限是該信源的熵。
舉例而言,如果有A,B,C,D四個字母,用

00來編碼A,01來編碼B,10來編碼C,11來編碼D

在一個文檔裡面,有200個A字母,200個B字母,400個C字母,800個D字母。則用上述編碼方法,文檔所佔比特數是:

200	imes 2+200	imes 2+400	imes 2+800	imes 2=3200 bit(公式1)

如果對該文檔進行霍夫曼編碼(如果不懂,請自行百度霍夫曼編碼),則變為

111來編碼A,110來編碼B,10來編碼C,0來編碼D

總的比特數為:

200	imes 3+200	imes3 +400	imes 2 +800	imes 1=2800(公式2)
R=2800div (200+200+400+800)=1.75(公式3)

而根據香農的信息熵定義,得到H為:

H=-sum_{i=1}^{4}{p(x_i)cdot log_{2}(p(x_i)) } =1.75(公式4)
R=H,即改種霍夫曼編碼是該信源的無失真編碼極限。

所以,一個文件被壓縮之後仍然可以壓縮,是因為前一次的壓縮方法沒有實現完全壓縮。而對於已經完全壓縮的文件,本身是無法再壓縮的了。


因為信息本身無法壓縮,壓縮掉的只是冗餘的信息


推薦閱讀:

如何通俗的解釋交叉熵與相對熵?
香農的資訊理論究竟牛在哪裡?

TAG:壓縮軟體 | 資訊理論 |