1. 程式人生 > >字符集與字元編碼

字符集與字元編碼

首先,我們要明確最基本的一點就是計算機的最小儲存單位是位元組(1byte=8bit)

字符集

1.什麼是字元
字元是各種文字和符號的總稱,包括各個國家文字標點符號,圖形符號,數字等。
2.字符集

首先,我們可以說一句廢話,字符集是字元的集合。
將一些特定的漢字,符號,字母收入到一個標準中,這些遵循同個標準的字元集合就稱為字符集。
常見字符集有Unicode字符集,ASCII字符集,ISO 8859字符集、GB2312字符集。

編碼

規定每個“字元”分別用一個位元組還是多個位元組儲存,用哪些位元組來儲存,這個規定就叫做“編碼”

ASCII編碼

ASCII字符集只有128個字元,ASCII字符集第一次以規範標準的型態發表是在1967年,最後一次更新則是在1986年,至今為止共定義了128個字元

;其中33個字元無法顯示(這是以現今作業系統為依歸,但在DOS模式下可顯示出一些諸如笑臉、撲克牌花式等8-bit符號),且這33個字元多數都已是陳廢的控制字元。控制字元的用途主要是用來操控已經處理過的文字。在33個字元之外的是95個可顯示的字元,包含用鍵盤敲下空白鍵所產生的空白字元也算1個可顯示字元(顯示為空白)。

在ASCII編碼中,單位元組字串使用一個位元組存放一個字元(SBCS,Single Byte Character System)。如:”Bob123”佔6個位元組。

注意:ASCII編碼是單位元組編碼,只能表示128個字元,也就是說有一位是沒有用到的。沒有用到的那一位是最高位。

ANSI編碼

因為最開始的ASCII編碼只支援英語,所以為了支援更多的語言,出現了ANSI編碼,通常用兩個位元組來表示一個字元。 關於ANSI編碼,不同的地區制定了不同的標準。為了讓計算機能夠表示中文字符集,出現了GB2312編碼。

對於臺灣繁體中文字符集,對應的編碼是BIG5

注意:不同 ANSI 編碼之間互不相容,當資訊在國際間交流時,無法將屬於兩種語言的文字,儲存在同一段 ANSI 編碼的文字中。

GB2312

ANSI編碼是相容ASCII編碼的,以表示中文字符集的GB2312編碼為例。GB2312編碼規定,一個小於127的位元組的意義與原來相同(與ASCII碼),但兩個大於127的位元組連在一起時,就表示一個漢字

,也就是說當一個位元組的最高位為0的時候,就代表這單個位元組代表一個ASCII字符集中的字元。而想要表示一個漢字,必須要兩個位元組,且這兩個位元組的最高位都必須為1,只要位元組的最高位為0,那麼這個單位元組就表示一個ASCII字符集中的字元。這樣的設計相容了ASCII編碼,但是也導致了兩個位元組能表示的字元少了很多。

GBK

但是中國的漢字太多了,我們很快就就發現有許多人的人名沒有辦法在這裡打出來,不得不繼續把 GB2312 沒有用到的碼位找出來用上。後來還是不夠用,於是乾脆不再要求低位元組一定是127號之後的內碼,只要第一個位元組是大於127就固定表示這是一個漢字的開始,不管後面跟的是不是擴充套件字符集裡的內容。結果擴充套件之後的編碼方案被稱為 “GBK” 標準,GBK 包括了 GB2312 的所有內容,同時又增加了近20000個新的漢字(包括繁體字)和符號。

GB18030

後來少數民族也要用電腦了,於是我們再擴充套件,又加了幾千個新的少數民族的字,GBK 擴成了 GB18030。從此之後,中華民族的文化就可以在計算機時代中傳承了。

GB 18030,全稱:國家標準 GB 18030-2005《資訊科技中文編碼字符集》,是中華人民共和國現時最新的內碼字集,是 GB 18030-2000《資訊科技資訊交換用漢字編碼字符集基本集的擴充》的修訂版。

GB 18030相容GBK。

GB 18030 編碼是一二四位元組變長編碼。

  • 單位元組,其值從 0 到 0x7F,與 ASCII 編碼相容。
  • 雙位元組,第一個位元組的值從 0x81 到 0xFE,第二個位元組的值從 0x40 到 0xFE(不包括0x7F),與 GBK 標準相容。
  • 四位元組,第一個位元組的值從 0x81 到 0xFE,第二個位元組的值從 0x30 到 0x39,第三個位元組從0x81 到 0xFE,第四個位元組從 0x30 到 0x39。

UNICODE字符集

廣義而言的UNICODE是一種標準,定義了一個字符集以及一系列的編碼規則,即UNICODE字符集以及UTF-8、UTF-16、UTF-32等編碼。

UNicode字符集為每一個字元分配一個碼位,它為每種語言中的每個字元設定了統一併且唯一的二進位制編碼,以滿足跨語言、跨平臺進行文字轉換、處理的要求。

之前已經說過:不同 ANSI 編碼之間互不相容,當資訊在國際間交流時,無法將屬於兩種語言的文字,儲存在同一段 ANSI 編碼的文字中。UNICODE的出現就是為了解決這個問題。

關於UNICODE字符集的說法,個人還是有點疑問的。我感覺嚴格來說是這樣的:

首先,UNICODE給每一個字元都指定了一個唯一的二進位制編碼,也就是每一個字元都有他對應的碼位。

而UTF-8等編碼,指定了位元組與碼位的對應關係,而並非直接指定了位元組與字符集中的字元的對應的關係。

所以我對到底有沒有UNICODE字符集是有疑問的,UNICODE標準中,字符集就是包含全部語言的字元,不過這一點並不影響我們對字元編碼的理解。

UTF-8

一個字元的Unicode編碼是確定的,但是在實際傳輸過程中,由於不同系統平臺的設計不一定一致,以及出於節省空間的目的,對Unicode編碼的實現方式有所不同。Unicode的實現方式稱為Unicode轉換格式(Unicode Transformation Format,簡稱為UTF)[1]。Unicode是字符集,它主要有UTF-8、UTF-16、UTF-32三種實現方式。UTF-8是目前主流的UNICODE字符集編碼方式。

UTF-8是一種針對Unicode的可變長度字元編碼,可以使用1~4個位元組表示一個符號,根據不同的符號而變化位元組長度。它可以用來表示Unicode標準中的任何字元。

UTF-8的編碼規則很簡單,只有二條

  1. 對於單位元組的符號,位元組的第一位設為0,後面7位為這個符號的Unicode碼。因此對於英語字母,UTF-8編碼和ASCII碼是相同的。
  2. 對於n位元組的符號(n>1),第一個位元組的前n位都設為1,第n+1位設為0,後面位元組的前兩位一律設為10。剩下的沒有提及的二進位制位,全部為這個符號的Unicode碼。

下表總結了編碼規則,字母x表示可用編碼的位。

Unicode符號範圍 UTF-8編碼方式
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

說明:解讀UTF-8編碼非常簡單。如果一個位元組的第一位是0,則這個位元組單獨就是一個字元;如果第一位是1,則連續有多少個1,就表示當前字元佔用多少個位元組。