什么是字符編碼

一、前言

一直以來,都對字符編碼有一個較模糊的概念,更談不上懂得其中的原理。本文記錄自己對字符編碼的學習。

二、概念

字符編碼(英語:Character encoding)也稱字集碼,是把字符集中的字符編碼為指定集合中某一對象(例如:比特模式、自然數序列、8位組或者電脈沖),以便文本在計算機中存儲和通過通信網絡的傳遞。
  計算機是不認識字符(用來表明達意文字或者符號)的,也不能直接存儲字符。所以計算機工程師們就用一些規則,按照這個規則,把一個個字符編成計算機能夠處理和存儲的二進制。字符全部使用某一規則編碼,就有了這些字符的集合,即字符集。例如常用的ASCII、GBK、Unicode等字符集。

三、計算機中的二進制

計算機如何將二進制轉換為人可以讀的懂文字呢?二進制又如何存儲在計算機里的呢?
  我們都知道計算機有個CPU,CPU內部是通過大量的邏輯門電路實現計算的。邏輯門是在集成電路上的基本組件。簡單的邏輯門可由晶體管組成。這些晶體管的組合可以使代表兩種信號的高低電平在通過它們之后產生高電平或者低電平的信號。高、低電平可以分別代表邏輯上的“真”與“假”或二進制當中的1和0,從而實現邏輯運算。邏輯門的實現直接應用了二進制,因此現代的計算機和依賴計算機的設備里都用到二進制。每個數字稱為一個比特(二進制位)。

四、字符集歷史

歷史上最先發明的編碼規則是ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼),ASCII第一次以規范標準的類型發表是在1967年,最后一次更新則是在1986年,至今為止共定義了128個字符。他這128個字符主要用于顯示英語。也就是說其它字體用ASCII顯示不了,例如漢字、朝鮮字等等。
  隨著計算機的發展,應用到各國,ASCII字符集明顯是不夠用,我想用計算機顯示漢字怎么辦呢?于是在1981年,中國人自己發布了GB 2312 或 GB 2312–80,后來由于還是不夠用,于是廠商微軟利用GB 2312-80未使用的編碼空間,收錄GB 13000.1-93全部字符制定了GBK編碼。這個···于2000年3月17日推出了GB 18030-2000標準,以取代GBK。GB 18030-2000除保留全部GBK編碼漢字,在第二字節把能使用范圍再度進行擴展,增加了大約一百個漢字及四位元組編碼空間,但是將GBK作為子集全部保留。請參看GB 18030
歷史就不扯了,扯不完。看一幅圖片

字符集歷史

  當計算機傳到世界各個國家時,為了適合當地語言和字符,設計和實現類似GB232/GBK/GB18030/BIG5的編碼方案。這樣各搞一套,在本地使用沒有問題,一旦出現在網絡中,由于不兼容,互相訪問就出現了亂碼現象。為了解決這個問題,一個偉大的創想產生了——Unicode。

五、二進制與字符集

以ASCII字符集為例,探討一下二進制與編碼的關系。

Paste_Image.png

ASCII可顯示字符

  從ASCII可顯示字符圖,我們可以看到二進制與圖形(字符)是一一對應的關系,比如空格"SPACE"是32(二進制00100000),大寫的字母A是65(二進制01000001)。這128個符號(包括32個不能打印出來的控制符號),只占用了一個字節的后面7位,最前面的1位統一規定為0。我們再看看Unicode碼。

六、Unicode碼

Unicode(中文:萬國碼、國際碼、統一碼、單一碼)是計算機科學領域里的一項業界標準。它對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更為簡單的方式來呈現和處理文字。
Unicode伴隨著通用字符集的標準而發展,同時也以書本的形式對外發表。Unicode至今仍在不斷增修,每個新版本都加入更多新的字符。目前最新的版本為2016年6月21日公布的9.0.0,已經收入超過十萬個字符(第十萬個字符在2005年獲采納)。Unicode涵蓋的數據除了視覺上的字形、編碼方法、標準的字符編碼外,還包含了字符特性,如大小寫字母。
Unicode發展由非營利機構統一碼聯盟負責,該機構致力于讓Unicode方案替換既有的字符編碼方案。因為既有的方案往往空間非常有限,亦不適用于多語環境。
  Unicode備受認可,并廣泛地應用于電腦軟件的國際化與本地化過程。有很多新科技,如可擴展置標語言(Extensible Markup Language,簡稱:XML)、Java編程語言以及現代的操作系統,都采用Unicode編碼。
前面說到ASCII碼是用一個字節表示,不夠用,來個Unicode碼用4個字節表示。比如,漢字"超"的unicode是十六進制數8D85,轉換成二進制數足足有15位(1000 1101 1000 0101),也就是說這個符號的表示至少需要2個字節。對于漢字,或許用2個字節就夠了,但是表示其他更大的符號,可能需要3個字節或者4個字節,甚至更多。
  這就出現了問題,想想如果字符都用4個字節表示,例如“超”用4個字節表示就是(0000 0000 0000 0000 1000 1101 1000 0101),前面的十六位都是0,這不就對計算機存儲和運算帶來極大的浪費以及負擔。所以這也出現了Unicode的多種存儲方式,也就是說有許多種不同的二進制格式,例如,2個字節存儲,3個字節存儲,甚至是4個字節存儲,都可以用來表示Unicode。也造成了Unicode在很長一段時間內無法推廣,直到互聯網的出現。

七、UTF-8

互聯網的普及,強烈要求出現一種統一的編碼方式。目前的Unicode字符分為17組編排,0x0000 至 0x1FFFF,每組稱為平面(Plane),而每平面擁有65536個碼位,共1114112個。然而目前只用了少數平面。UTF-8UTF-16UTF-32都是將數字轉換到程序數據的編碼方案。
  UTF-8就是在互聯網上使用最廣的一種Unicode的實現方式。其他實現方式還包括UTF-16(字符用兩個字節或四個字節表示)和UTF-32(字符用四個字節表示),不過在互聯網上基本不用。重復一遍,這里的關系是,UTF-8是Unicode的實現方式之一。
  UTF-8以字節為單位對Unicode進行編碼。從Unicode到UTF-8的編碼方式如下:

Unicode編碼(十六進制) UTF-8 字節流(二進制)
000000-00007F 0xxxxxxx
000080-0007FF 110xxxxx 10xxxxxx
000800-00FFFF 1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF 11110xxx10xxxxxx10xxxxxx10xxxxxx
6字節

UTF-8的特點是對不同字節范圍的字符使用不同長度的編碼。對于0x00-0x7F之間的字符,UTF-8編碼與ASCII編碼完全相同。UTF-8編碼的最大長度是6個字節。從上表可以看出,6字節模板有31個x,即可以容納31位二進制數字。Unicode的最大碼位0x7FFFFFFF也只有31位。滿足了不同長度字符的需要,也不會造成極大的浪費,也能識別編碼處于什么范圍。
  跟據上表,解讀UTF-8編碼非常簡單。如果一個字節的第一位是0,則這個字節單獨就是一個字符;如果第一位是1,則連續有多少個1,就表示當前字符占用多少個字節。

例1:“漢”字的Unicode編碼是0x6C49。0x6C49在0x0800-0xFFFF之間,使用用3字節模板了:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進制是:0110 1100 0100 1001, 用這個比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

例2:Unicode編碼0x20C30在0x010000-0x10FFFF之間,使用用4字節模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。將0x20C30寫成21位二進制數字(不足21位就在前面補0):0 0010 0000 1100 0011 0000,用這個比特流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即F0 A0 B0 B0。

八、總結

通過以上解讀,對字符編碼又有了一個更深的印象。本文只是一個對字符編碼進行一個淺顯的介紹。詳情還需看參考資料。另外與編碼原理相關的很多很有意思地方,例如,亂碼,摩斯密碼,二進制在計算機中的處理思維等等,聽說還有三進制計算機
文章中存在不準確之處,希望大家批評指正。

參考資料:
1、https://zh.wikipedia.org/zh/UTF-8
2、http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
3、https://zh.wikipedia.org/wiki/Unicode
4、https://zh.wikipedia.org/zh/ASCII

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 計算機是如何存儲數據的 在談什么是字符編碼前,我們首先要知道一個概念,計算機是如何存儲數據的:計算機是由邏輯電路組...
    七里之境閱讀 295評論 0 1
  • 基礎知識 計算機中儲存的信息都是用二進制數表示的;而我們在屏幕上看到的英文、漢字等字符是二進制數轉換之后的結果。通...
    海馬啊你沒有腿閱讀 322評論 0 0
  • 在了解什么是字符編碼之前,首先要了解什么是字符集? 我們在計算機屏幕上看到的是實體化的文字,而在計算機存儲介質中存...
    饑人谷_oathy閱讀 499評論 0 1
  • 1 信仰不能狹義的單單的理解成為對神的愚昧的信任,有的人很一針見血的闡明,這種信仰是無知的,我也絕不相信神會以人格...
    李好像條狗閱讀 459評論 0 0
  • 假設時間是一條線 用世界最精細的放大鏡去看 會有許多許多斷點 想盡一切辦法擠進去吧 那是永恒的時間黑洞 . . ....
    水熊貓的小詩畫閱讀 260評論 0 0