編碼:二進位的世界

我們要聊的編碼並不是「寫代碼(Coding)」,而是信息從一種形式被轉換為另外一種形式的這個過程,即 Encoding.

感謝 @lotuspaste 為最後一個段落提供內容,感謝 @parthas@李開元@趙瑞鵬 為草稿提供參考意見。

二進位的世界

n就像大家知道的那樣,在計算機的世界中,信息必須被轉換為二進位(Binary)才能被 CPU 計算、被內存或硬碟存儲、在網路上傳輸。

n相比於我們從小使用的十進位,二進位既不直觀,又顯得冗長,那麼為什麼計算機選擇二進位作為內部的信息表現形式呢?

n十進位意味著每個數位上有從 0 到 9 十種可能的狀態,也就是十進位中的一位可以表示 10 種事物中的一種,兩位則可以表示 100 種事物的一種。要不是人有十個手指,其實我們也可以使用八進位(偶爾會在計算機領域使用)或十二進位(時間和角度通常基於十二進位)。

n那麼我們可以考慮一下極端情況,最少可以用幾進位來表示信息呢?很好猜到答案 —— 二進位,要表達一個有意義的信息,至少要能區分兩種的情況中的一種吧。科學家喜歡追求一種「簡潔之美」,既然我們找到了表示信息的最簡形式,為什麼不以它為基礎來構築計算機世界呢。

n這種「信息的最小單位」被稱為比特 (Bit),正因為它是信息的最小單位,比特位之間的運算規則也遠比十進位簡單得多(例如兩個比特位相加只有 4 種情況);在工程上也得到了很多便利,例如比特的兩種狀態剛好被映射到信號的有無、低電壓或高電壓、連通或斷開等等。

數字的編碼

n因為計算機選擇了用比特作為信息的表現形式,所以各種其他的形式的信息必須被以某種方式被轉換為若干個比特才能被計算機處理,這種過程就叫「編碼」。

n我們先從數字說起,數字是最容易被編碼的信息了,因為比特可以被簡單地看作二進位的數字,只需將我們平常的十進位數字換算到二進位即可。

n在這種編碼方式下,一個數字所需要的比特數正比於它的大小,比如用二進位表示 123 需要 7 個比特,而表示一億則需要 27 個比特。使用這種方式編碼數字存在一些局限性,例如需要大量的比特去表示一個較大的數、無法去表示小數點等。

n所以還存在另一種被普遍使用的方法來編碼數字,被稱為「浮點數(Floating Point Number)表示法」。這種表示方法非常類似於「科學計數法」,它將一個數字拆分為三個部分來保存:正/負、指數、係數。這樣的話,浮點數表示法可以在一個非常大的範圍(受限於指數部分的位數)內表示包括小數在內的,具有一定精度(受限於係數部分的位數)數字。

字元串的編碼

n計算機中的「字元串(String)」就是人們通常所說的文字,一個字元串是由若干的「字元(Character)」構成的。而字元則取決於具體的語言,例如英語中的字元包括 26 個英文字母,而漢字則有兩萬餘個字元。

n計算機如何編碼字元呢?儲存它的圖形顯然會令問題複雜化,所以最簡單的辦法就是給每個字元一個編號,在計算機中儲存和計算編號,直到需要展示的時候才繪製為人們所見到的圖形。

n最簡單的一種字元編碼方案就是 ASCII 了,它支持 128 個字元,包括大寫和小寫的 26 個英文字母、數字、英文標點和一些特殊字元。ASCII 將一個字元編碼為 8 個比特,但實際只用到了 7 個比特而已(128 剛好是 2 的 7 次方)。

字符集和字元編碼

n為了對各種語言的字元提供支持,後來又出現了很多種將字元編號的規則,這種規則被稱為「字符集(Character Set)」,例如中國官方最新的字符集標準被稱為 GB18030, 包括了七萬多個漢字和一些少數民族的字元。

n字符集之間可能互不兼容,例如同樣的一個二進位序列,在一個中文字符集中可能是一個漢字,而在其他的字符集中就可能是另外的字元,甚至是無法顯示的字元。所以計算機在顯示一段字元串的時候需要知道它的字符集,否則就會出現我們稱之為「亂碼」的情況,即字元串被以一種錯誤的字符集被顯示,以至於無法閱讀。

通常一段字元串只能使用一種字符集,一旦你選擇了一種字符集,你就沒有辦法表示不在這個字符集中的字元。例如如果你選擇了一個中文字符集,那麼可能就沒辦法去表示韓文中的字元。為了解決這種不便,出現了一種叫「Unicode(暫譯作通用字符集)」的字符集,它覆蓋了世界上絕大部分語言的字元,甚至包括了經常被使用的表情符號(Emoji)。目前大部分的網頁、編程語言、操作系統都使用 Unicode 來表示字元串。

n和其他一些直接規定了編碼方式的字符集不同,Unicode 本身只是對字元的編號,它定義了幾種具體的編碼方式。例如 UTF-8 最少使用 8 個比特,最多使用 48 個比特來表示一個字元,適合英文居多的場景(因為 ASCII 中的字元只需要 8 比特);UTF-32 則總是用 32 個比特表示一個字元,這樣固定長度的編碼方式會擁有更好的性能。

來自自然界的信息

n計算機經常還被用來處理圖片、音頻、視頻這類來自自然界的信息。我們所生活在的物理世界可以被認為是「連續」的。例如自然界中的聲音,在任意一個時間點都可能會有頻率和響度的變化,但在目前的計算機體系來看,這樣的數據擁有無限大的信息量,沒辦法被編碼。

n於是我們使用「採樣」的方式將這些信息轉化為有限的「離散」的信息。例如我們每一毫秒去測量聲音的頻率,這樣計算機就可以去編碼每次測量到的頻率的數字,將這段聲音數字化了。

n這種採樣的過程是會丟失信息的,比如在兩次測量之間的某一時間點的情況我們是不得而知的,只能推測它大概介於這兩次結果之間。所以很好想像,丟失的信息取決於採樣的頻率,以越短的間隔採樣,就會得到越多的信息,越接近原始的信息。

未完待續,下一篇將會介紹更多有關「編碼」的內容。


推薦閱讀:

TAG:计算机科学 | 编程 | 字符编码 |