計算機編碼方式雜談

weixin_33785972發表於2017-08-20

標題有點大!能總結多少我就總結多少吧。如有錯誤的地方,望各位看客指正!

對於從事iOS開發的童鞋們來說,UTF-8這個詞對大家來說並不陌生:UTF-8是一種編碼方式。編碼是什麼?編碼方式又是什麼?UTF-8是怎樣一種編碼方式?與UTF-16和UTF-32編碼方式有什麼區別?由此擴充,還存在哪些編碼方式?不同的編碼方式都有什麼特點?就以這些問題為切入點,我們來依次展開!

編碼是什麼?
編碼,兩個字要分開來理解。編是一個行為,碼是編作用的物件。要想編,肯定得有碼。碼有ASCII碼,GB2312碼,GBK碼,Unicode碼等。上面列舉的這些碼標準其實是一套資訊字元與二進位制字串的對映表。例:在ASCII碼標準中拉丁字母A與二進位制字串01000001是對應的,其它的拉丁字母與符號相應的也有一個唯一的二進位制客串與之對應。計算機不認識字母,也不認識符號,但它能將字母或符號依據碼標準轉化(轉化其實也就是編的過程)成相應的二進位制字串。我們將這個轉化過程稱為編碼。

編碼方式是什麼?
編碼我們知道了,就是將碼轉化的過程。碼以什麼演算法編以及編的結果就是編碼方式。還以拉丁字母A為例:可以將其編成八位的二進位制字串01000001,也可以將其編成十六位的二進位制字串 00000000 01000001。一個是八位的,一個是十六位的,二進位制的字串長度不一樣,儲存到計算機系統中後佔用的記憶體就不一樣了。 這就兩種不同的編碼方式。

理解了上面兩個概念之後,我們就來擴充套件說一下碼和編。先有碼,後有編。沒有碼,你編什麼?這話沒毛病!


上面提了,碼有ASCII碼,GB2312碼,GBK碼,Unicode碼等。碼(其實這裡說成標準碼更合適一點,為了呈上啟下,我這裡依然說成碼,下同)是怎麼來的呢?

在計算機系統中,所有的資訊最終都將以二進位制的形式表示並儲存。一個二進位制位(bit)有0和1兩種狀態,八個二進位制位就能組合出256種狀態(2的8次方),如果每一個狀態對應一個符號,就能表示256個符號。以此類推,十六個二制位就能表示65,536個字元...

一開始,是沒有標準的,處於混戰狀態。一個字元在一個系統裡可能被編成二進位制字串00000001,在另外一個系統裡被編成二進位制字串00000002,在各自的系統裡,大家用起來挺好,完全沒壓力啊!但這個字元要是從一個系統被傳送到另外一個系統裡就讀不出來了,因為編碼的標準不同。這沒法交流嘛!於是,為了避免混亂,更為了交流,有些人就站出來了:大家聽我說,我們們不鬧了,統一一個標準吧。這樣,就有了統一的碼。ASCII碼是最早的一個標準!

1967年,美國國家標準學會(American National Standard Institute , ANSI )制定了一套統一的ASCII標準碼。ASCII碼的出現,很好的解決了以西文字元為基礎進行交流的國家的計算機通訊資訊不相容的問題。它最初是美國國家標準,供不同計算機在相互通訊時用作共同遵守的西文字元編碼標準,它已被國際標準化組織(International Organization for Standardization, ISO)定為國際標準,稱為ISO 646標準。一開始指定為7位,即含128個字元,後來擴充套件至8位,可以表示256個不同的字元。

時代在發展,網際網路快速全球化!世界上有那麼多語言,原有的ASCII碼已經不能滿足需求,於是各個國家開始制定自己的ASCII版本。就拿我們的漢語來說,我們制定了自己的漢語編碼標準GB2312、GBK,這樣,我們就能在電腦上使用統一的漢語編碼標準用漢語進行愉快的溝通交流了。

其他國家當然也沒閒著,都在搞各自的標準碼,這麼多標準碼,也是一團亂麻啊!這時候,又有人站出來喊話了:我來一統江湖吧!Unicode橫空出世了!

Unicode 標準為世界上幾乎所有的書寫系統裡所使用的每一個字元或符號定義了一個唯一的數字。不得不說,世界種地的吃瓜群眾要想愉快的溝通,這個太有必要了!

下面著重介紹一下我們熟悉的各種碼!

ASCII:又稱單位元組碼。因為每個碼最多有8位,也就是一個位元組大小。其包含大寫和小寫字母,數字0 到9、標點符號、在美式英語中使用的特殊控制字元、特殊符號字元、外來語字母和圖形符號。

GB2312:GB2312共收入漢字6763個和非漢字圖形字元682個。GB2312編碼適用於漢字處理、漢字通訊等系統之間的資訊交換,通行於中國大陸;新加坡等地也採用此編碼。中國大陸幾乎所有的中文系統和國際化的軟體都支援GB 2312。GB2312中每個字元佔兩個位元組,也就是16位。

GBK:GBK是在GB2312-80標準基礎上的內碼擴充套件規範,使用了雙位元組編碼方案,其編碼範圍從8140至FEFE(剔除xx7F),共23940個碼位,共收錄了21003個漢字,完全相容GB2312-80標準,支援國際標準ISO/IEC10646-1和國家標準GB13000-1中的全部中日韓漢字,幷包含了BIG5編碼中的所有漢字。GBK編碼方案於1995年10月制定, 1995年12月正式釋出,目前中文版的WIN95、WIN98、WINDOWS NT以及WINDOWS 2000、WINDOWS XP、WIN 7等都支援GBK編碼方案。寫在GBK後面的話:如果說GB2312統一了中國,那麼GBK就統一了漢字!嘿嘿!自己理解吧!GBK中的字元同樣也佔兩個位元組。

Unicode:Unicode(統一碼、萬國碼、單一碼)是電腦科學領域裡的一項業界標準,包括字符集、編碼方案等。Unicode 是為了解決傳統的字元編碼方案的侷限而產生的,它為每種語言中的每個字元設定了統一併且唯一的二進位制編碼,以滿足跨語言、跨平臺進行文字轉換、處理的要求。1990年開始研發,1994年正式公佈。

Unicode 不是 16 位的編碼!它是 21 位的。這 21 位提供了 1,114,112 個碼點,其中,只有大概 10% 正在使用,所以還有相當大的擴充空間。

Unicode編碼空間被分成 17 個平面(plane),每個平面有 65,536 個字元。0 號平面叫做基本多文種平面(Basic Multilingual Plane, BMP),涵蓋了幾乎所有你能遇到的字元,除了 emoji。其它平面叫做補充平面,大多是空的。

以上是計算機中非常常用的一些碼,當然其他的肯定還有很多,知識有限,又出不去。如果你知道,歡迎在評論區列出!

編碼方式
碼有了,接下來就是如何用了。於是,各種編碼方式就登場了!

UTF-8,UTF-16,UTF-32
一看他們就是UTF家族的!但事實如此嗎?
先來看看UTF是個什麼鬼?UTF是UCS Transfer Format的縮寫,翻成漢語就是UCS傳輸格式,UCS又是什麼鬼?UCS是Universal Multiple-Octet Coded Character Set的縮寫,簡稱UCS,俗稱Unicode。所以,UTF-8、UTF-16、UTF-32是編Unicode碼的不同方式。的確是一個家族的!它們是對Unicode編碼的不同方式!

UTF-32:它在每個碼點上使用整 32 位。32 大於 21,因此每一個 UTF-32 值都可以直接表示對應的碼點。儘管簡單,UTF-32卻幾乎從來不在實際中使用,因為每個字元佔用 4 位元組太浪費空間了。(碼點:碼中每個字元對應一個唯一的二進位制字串,這個二進位制字串就叫做碼點)

UTF-16:UTF-16 本身是一種長度可變的編碼。基本多文種平面(BMP)中的每一個碼點都直接與一個碼元相對映。鑑於 BMP 幾乎囊括了所有常見字元,UTF-16 一般只需要 UTF-32 一半的空間。其它平面裡很少使用的碼點都是用兩個 16 位的碼元來編碼的,這兩個合起來表示一個碼點的碼元就叫做代理對(surrogate pair)。

UTF-8:UTF-8也是一種長度可變的編碼方式。它使用一到四個[^5]位元組來編碼一個碼點。從 0 到 127 的這些碼點直接對映成 1 個位元組(對於只包含這個範圍字元的文字來說,這一點使得 UTF-8 和 ASCII 完全相同)。接下來的 1,920 個碼點對映成 2 個位元組,在 BMP 裡所有剩下的碼點需要 3 個位元組。Unicode 的其他平面裡的碼點則需要 4 個位元組。UTF-8 是基於 8 位的碼元的,因此它並不需要關心位元組順序(不過仍有一些程式會在 UTF-8 檔案里加上多餘的 BOM)。有效率的空間使用(僅就西方語言來講),以及不需要操心位元組順序問題使得 UTF-8 成為儲存和交流 Unicode 文字方面的最佳編碼。它也已經是檔案格式、網路協議以及 Web API 領域裡事實上的標準了。

下面介紹一下其他的一些編碼!
Base64
Base64是一種用64個字元來表示任意二進位制資料的方法。Base64碼一共有64個字元,每個字元佔6位(2的6次方),在百度百科中你可以檢視一下所有的Base64碼的字元與二進位制字串的對映關係。
原理就是將原文字編碼後的二進位制串依次以每6位為一個單位,然後在Base64碼錶中找出這個二進位制串對應的字元,這樣以次類推,直到把所有的文字全部轉化為Base64碼為止。Base64編碼是從二進位制到字元的過程,可用於在HTTP環境下傳遞較長的標識資訊。

BIG5
Big5是雙位元組編碼。Big5收錄的漢字只包括繁體漢字,不包括簡體漢字,一些生僻的漢字也沒有收錄。大陸是簡體字的天下,因此這個碼標準我們瞭解一下就好。

下面附上常用的一些字元的Unicode編碼範圍
26個大寫字母編碼範圍:01000001~ 01011010(65~90)
26個小寫字母編碼範圍:01100001~ 01111010(97~122)
阿拉伯數字編碼範圍:00110000~ 00111001(48~57)
基本漢字編碼範圍:0x4E00~ 0x9FA5(19968~ 40869)

由於知識有限,就整理這麼多吧!
如果有錯誤的地方,歡迎指正交流!不喜勿噴!

引用資料:
1 .百度百科
2 .https://www.objccn.io/issue-9-1/

相關文章