字符的編碼與Unicode

一、概述

字符編碼集(Character encoding set)也稱字符集(character set)或代碼頁(code page),字符編碼是將一組字符分配或映射給稱為代碼點(code point)的數字序號(或無符號整數)的一種方式,通俗地講就是用數值集合來表示的無序字符集合。以便於數據傳輸。最小代碼點為零,代碼點通常寫成十六進制,例如“0x20AC”(十進制為8364),映射具有固定大小。例如,大多數7位編碼具有128個代碼點,大多數8位編碼具有256個代碼點。最大的字符集是Unicode字符集6.0,包含1114112個代碼點。代碼點其中大多數代表可見的符號,但也可以有其他含義,例如指定符號的一個方面(字母的重音、表情符號的膚色等)。

代碼單元(code unit)是編碼代碼點最小單位,需要一個或多個代碼單元對單個代碼點進行編碼。每個代碼單元具有相同的大小(可能是1字節、2字節和4字節等),其大小這取決於所使用的編碼格式(或者說是字符編碼方案)(如ASCII、UCS-2、UCS-2、utf-8、utf-16、utf-32等)。最流行的格式UTF-8有8-bit(字節)大小的代碼單位。

與字符編碼集不同,字符編碼方案或格式(character encoding scheme)是如何利用位(bit)與字節(byte)來形成字符代碼點的數字值(也就是說編碼值不一定就是代碼點的值)。對於ASCII等簡單的字符編碼,ASCII將128個字符和控制代碼分配給0到127的連續數字。這些字符和控制代碼被編碼為簡單的、無符號的二進制整數。因此,ASCII既是一種編碼字符集,也是一種字符編碼方案,但對於UNICODE編碼方案就不一定是這種簡單情況瞭,它則要復雜得多。

用於映射抽象字符的非負整數集合的代碼點大小范圍組成瞭代碼空間(code space)。傳統上,代碼空間的范圍與編碼形式密切相關,因為抽象字符到非負整數的映射是在考慮特定編碼形式的情況下完成的。代碼空間的常見范圍有0..7F、0..FF、0..7FFFF、0..7FFFFFFF和0..FFFFFF。Unicode標準的代碼空間范圍由0..10FFFF界定,另外還保留瞭另外137468個代碼點作為專用區域,這些代碼點沒有標準化的含義,可供各個應用程序自行定義。

1)字節順序(byte order)

處理器體系結構的不同之處在於多字節機器整數映射到存儲位置的方式。Little Endian架構將最低有效字節放在較低的地址,而Big Endian架構從最高有效字節開始。這種差異對內存中的代碼單元的操作並不重要,但當使用特定CES(Character Encoding Scheme)將代碼單元序列化為字節序列時,字節順序變得重要。就讀取數據流而言,有兩種類型的字節順序:與讀取數據的處理器的字節順序相同或相反。在前一種情況下,無需采取特殊操作;在後一種情況下,數據需要在處理之前進行字節反轉(byte-reversed)。就數據流的外部指定而言,可以區分三種類型的字節順序:Big Endian(BE)、Little Endian(LE)和默認或內部標記。

在Unicode中,代碼點U+FEFF處的字符被定義為字節順序標記(byte order mark),而其字節反轉的對應字符U+FFFE在UTF-16中是非字符(U+FFFE)或者在UTF-32的代碼空間(0xFFFE0000)之外。因此,在數據流的開頭,字節順序標記的存在可以用於明確地表示代碼單元的字節順序。

Unicode標準預留瞭66個非字符代碼點。每個平面的最後兩個代碼點是非字符的:BMP上的U + FFFE和U + FFFF,平面1上的U + 1FFFE和U + 1FFFF,依此類推,直到U + 10FFFE和平面16上的U + 10FFFF,總共34個代碼點。此外,BMP中還有另外32個非字符代碼點的連續范圍:U + FDD0..U + FDEF。由於歷史原因,范圍U + FDD0..U + FDEF包含在阿拉伯語Presentation Forms-A塊中,但那些非字符不是“阿拉伯語非字符”或“從右到左的非字符”,並且不在任何區別與其他非字符的其他方式,除瞭代碼點值。

2)SBCS(單字節字符集)與DBCS(雙字節字符集)

單字節字符集(Single-byte character sets )

大多數字符集使用一個字節來表示每個字符,因此稱為SBCS(Single-byte character sets )。這些字符集相對簡單,最多可以表示255個唯一字符。如ASII、ISO 8859-1(Latin1)、ISO 8859-2(Latin2)、Microsoft CP1252(類似於Latin1,但特定於供應商)和IBM CCSID 37。

雙字節字符集(Double-byte character sets )

DBCS(Double-byte character sets )使用一個或兩個字節來表示每個字符,通常用於書寫表意文字,如日語、漢語和韓語。大多數DBCS允許混合使用一個字節和兩個字節的字符,因此不能假定字符串字節長度為偶數。混合使用單字節和雙字節字符的編碼也稱為可變寬度編碼,這種字符集有時被稱為多字節字符集(MBCS)。不要太在意多字節字符集的定義,似乎有點岐義,是歷史遺留的產物。

3)字符集編碼的簡史

早期字符集編碼標準有1963年的ASCII和1964年的EBCDIC(Extended Binary Coded Decimal Interchange Code,IBM的字符編碼)。隨著計算機的廣泛使用,ASCII成為第一個廣泛使用的編碼方案。然而,它僅限於128個字符的定義。這對於最常見的英語字符、數字和標點符號來說是很好的,但對於世界其他國傢和地區的語言來說並不能滿足它們的需要,於是出現瞭像ISO-8859-1(Latin-1)、Windows-1252和ISO/IEC 8859這樣的編碼將ASCII編碼的容量擴展到8位(256個代碼點),並能夠支持歐洲重音字符。所有這些編碼為前128個代碼點分配相同的字符,與ASCII完全相同。它們在為其餘128個代碼點分配新字符方面略有不同。

除瞭歐洲,其它國傢和地區也為擴充ASCII編碼制定瞭不同的標準,由此產生瞭 GB2312、BIG5、JIS 等各自的編碼標準,這些使用2個字節來代表一個字符的各種表意文字(漢語、韓語、日語和越南語)延伸編碼方式,稱為 ANSI (American National Standards Institute)編碼,又稱為MBCS(Muilti-Bytes Character Set,多字節字符集)。在簡體中文中ANSI 編碼為GB2312 編碼,在日文中ANSI 編碼代表 JIS 編碼,所以在中文 windows下要轉碼成gb2312,gbk隻需要把文本保存為ANSI 編碼即可,GBK和GB2312都是針對簡體字的編碼,隻是GB2312隻支持六千多個漢字的編碼,而GBK支持1萬多個漢字編碼,而GB18030是我們的國傢標準。漢字存儲時都使用兩個字節來儲存。 不同 ANSI 編碼間互不兼容,當信息在國際間交流時,無法將屬於兩種語言的文字,存儲在同一段ANSI 編碼的文本中。一個很大的缺點是,同一個編碼值,在不同的編碼體系裡代表著不同的字。這樣就容易造成混亂。這種混亂的狀況導致瞭unicode編碼的誕生,試圖將世界上所有的語言符號都納入其中統一所有不同的編碼方案,以便盡可能減少計算機之間的混淆。

最初創建的UNICODE編碼是2個字節的編碼方案UCS-2,目標是包括世界上大多數語言的所有必需字符,以及科學、數學和音樂等技術領域的符號。它通過增加一個高字節對ISO Latin-1字符集進行擴展,當這些高字節位為0時,低字節就是ISO Latin-1字符。UNICODE支持歐洲、非洲、中東、亞洲(包括統一標準的東亞象形漢字和韓國象形文字)。但是,UNICODE並沒有提供對諸如Braille、Cherokee、Ethiopic、Khmer、Mongolian、Hmong、Tai Lu、Tai Mau文字的支持。同時它也不支持如Ahom、Akkadian、Aramaic、Babylonian Cuneiform、Balti、Brahmi、Etruscan、Hittite、Javanese、Numidian、Old Persian Cuneiform、Syrian之類的古老的文字。

當越來越清楚意識到UCS-2的65536個(2^16 ) 字符不夠時,IEEE引入瞭更大的31-bit空間和編碼方案UCS-4(與之相同的是utf-32),每個字符需要4個字節。這遭到瞭Unicode聯盟的抵制,既因為每個字符4字節浪費瞭大量內存和磁盤空間,也因為一些制造商已經對每個字符2字節的技術進行瞭大量投資。UTF-16編碼方案是作為一種折衷方案開發的,並於1996年7月隨Unicode標準2.0版引入。IETF於2000年發佈的RFC 2781中對其進行瞭全面規定。後來為瞭進一步提高Unicode的編碼效率,於是就出現瞭UTF-8編碼。

二、ASCII編碼

ASCII編碼(American Standard Code for Information Interchange,美國標準信息交換碼)是目前計算機中用得最廣泛的字符集及其編碼,於1968年提出,由美國國傢標準局ANSI(American National Standards Institute)制定且已被國際標準化組織(ISO)定為國際標準,稱為ISO 646標準。適用於所有拉丁文字字母,ASCII碼有7位代碼點(code point)和8位代碼點(也稱擴展ASCII碼)兩種形式。

  • 0~32號、127號(共34個):控制字符或通訊專用字符,如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BEL(振鈴)等;通訊專用字符:SOH(文頭)、EOT(文尾)、ACK(確認)等;
  • 33~126號(共94個):字符,其中第48~57號為0~9十個阿拉伯數字;65~90號為26個大寫英文字母,97~122號為26個小寫英文字母,其餘為一些標點符號、運算符號等。

標準的ASCII碼用一個字節存儲,可以表示128個字符,其中最高位用作校驗碼,用於代碼傳送過程中用來檢驗是否出現錯誤的,一般分為奇校驗(正確的代碼一個字節中1的個數必須是奇數,若非奇數,則在最高位b7添1)和偶校驗(正確的代碼一個字節中1的個數必須是偶數,若非偶數,則在最高位b7添1)兩種。擴展ASCII 碼允許將每個字符的第8 位用於確定附加的128 個特殊符號字符、外來語字母和圖形符號。

擴展ASCII編碼(extended the ASCII)

由於ASCII是針對英語設計的,當處理帶有音調標號(形如漢語的拼音)的歐洲文字時就會出現問題。為瞭表示更多字符,人們打起瞭校驗碼的註意,讓最高位也用作字符表示,這就是ASCII碼擴字符集。ASCII擴展的字符集包括255個字符。

1)ISO/IEC 8859-1(15)

ISO8859 是一個系列的標準,主要是以同樣的碼位對應不同字符集。

  1. ISO8859-1(Latin-1):西歐常用字符,包括德法兩國的字母。
  2. ISO8859-2 (Latin-2):收集瞭東歐字符。
  3. ISO8859-3(Latin-3):收集瞭南歐字符。
  4. ISO8859-4(Latin-4):收集瞭北歐字符。
  5. ISO8859-5(Cyrillic):收集瞭斯拉夫語系字符。
  6. ISO8859-6(Arabic):收集瞭阿拉伯語系字符。
  7. ISO8859-7 (Greek):收集瞭希臘字符。
  8. ISO8859-8 ( Hebrew):收集瞭西伯萊 (猶太人) 字符。
  9. ISO8859-9 (Latin-5 或 Turkish):收集瞭土耳其字符。
  10. ISO8859-10(Latin-6 或 Nordic):收集瞭北歐 (主要指斯堪地那維亞半島) 的字符。
  11. ISO8859-11(Thai):它是從泰國的 TIS620 標準字符集演化而來。
  12. ISO8859-12 :目前尚未定義。
  13. ISO8859-13 (Latin-7):主要函蓋波羅的海(Baltic) 諸國的文字符號,也補充一些在 Latin-6 中遺漏的拉脫維亞 (Latvian) 字符。
  14. ISO8859-14 (Latin-8):它將 Latin-1 中的某些符號換成塞爾特語 (Celtic) 的字符。塞爾特族是指英倫外圍的威爾斯人 (Welsh) 和蓋爾人 (Gaelic)。
  15. ISO8859-15 Latin-9或 Latin-0,):它將 Latin-1 中較少用到的符號刪除,換成當初遺漏的法文和芬蘭字母;還有,把英鎊和日元之間的金錢符號,換成瞭歐盟貨幣符號。
  16. ISO 8859-16(Latin-10):正式編號為ISO/IEC 8859-16:2001,這個字符集設計來涵蓋阿爾巴尼亞語、克羅地亞語、匈牙利語、意大利語、波蘭語、羅馬尼亞語及斯洛文尼亞語等東南歐國傢語言。

2)MS-Windows character sets

MS-Windows character sets主要有以下幾種:

  1. Windows-1250 (legacy, Central Europe)
  2. Windows-1251 (legacy, Cyrillic)
  3. Windows-1252 (legacy, Western Europe)
  4. Windows-1253 (legacy, Greek)
  5. Windows-1254 (legacy, Turkish)
  6. Windows-1255 (legacy, Hebrew)
  7. Windows-1256 (legacy, Arabic)
  8. Windows-1257 (legacy, Baltic Rim)
  9. Windows-1258 (legacy, Vietnam)

三、漢字的編碼(Chinese character encoding)

漢字編碼根據應用目的的不同,大致可分為如下編碼:

  1. 外碼:也稱輸入碼,是用來將漢字輸入到計算機中的一組鍵盤符號,如拼音碼、五筆字型碼等。
  2. 交換碼(國標碼):中國標準總局1981年制定瞭中華人民共和國國傢標準GB2312--80《信息交換用漢字編碼字符集--基本集》,即國標碼,除瞭GB2312編碼還有GBK編碼和GB18030編碼,是一個四位十六進制數,不是從0x0000開始的,而是從0x2020開始的。區位碼則是國標碼另一種表現形式,是一個四位的十進制數,把國標GB2312--80中的漢字、圖形符號組成一個94×94的方陣,分為94個區(01-94),每區包含94個位(01-94),類似數組的數組,全部元素或位置=94×94=8836個,其中7445個位置分配給漢字和圖形字符,其餘的1391個位置保留備用。
  3. 機內碼:是區位碼(國標碼、交換碼)在計算機內部的二進制具體表示、GB內碼的存儲格式始終是big endian,即高位在前。
  4. 字形碼:談不上說是什麼具體的碼值,隻不過是個約定成俗的叫法而已,其實是一個圖形點陣結構(常用是16×16點陣)。
  5. 地址碼:漢字地址碼是指字庫中邏輯地址碼,與漢字內碼有著簡單的對應關系易於相互轉換。

常見國標碼有以下幾種:

  1. GB 2312-1980:信息交換用漢字編碼字符集、國標碼的基本集、7445個字符、CP936
  2. GBK-1995:漢字內碼擴展規范、21886個字符、CP936
  3. GB13000.1-1993:通用多八位編碼字符集用於信息技術
  4. GB18030-2000:信息交換用漢字編碼字符集、基本集的擴充、27484字符、CP54936、不支持手機與MP3

3.1)國標碼、區位碼與機內碼

漢字在程序中是以機內碼進行表示,國標碼是一個四位十六進制數,區位碼是一個四位的十進制數。國標碼不是從0x0000開始的,而是從0x2020開始的,而區號和位號,是從0開始的,因此( 區號+0x20 ) << 8 + (位號 + 0x20) = 國標碼。

在區位碼中,01-09區為682個特殊字符,16~87區為漢字區,包含6763個漢字。其中16-55區為一級漢字(3755個最常用的漢字,按拼音字母的次序排列),56-87區為二級漢字(3008個漢字,按部首次序排列),88-94區為用戶自定義漢字區(未編碼)。區位碼通常都是用十進制表示的,例如“誠”字的區位碼為1947,也就說它位於19區第47個字符。

國標碼、區位碼與機內碼相互轉換的公式與樣例如下:

國標碼 = 區位碼(區碼和位碼各自16進制化)+2020H
機內碼 = 國標碼 + 8080H
機內碼 = 區位碼(區碼和位碼各自16進制化) + a0a0H

漢字“大”的區內碼為20和83
1、區號為20,位號為83
2、將區位號轉換為十六進制表示為1453H
3、1453H+2020H=3473H,得到國標碼3473H
4、3473H+8080H=B4F3H,得到機內碼為B4F3H

发表回复

相关推荐

第1章 什麼是數據化管理

1.1 數據化管理的概念數據化管理是指運用分析工具對客觀、真實的數據進行科學分析,並將分析結果運用到生產、運營、銷售等各...

· 32秒前

拼多多補單技巧,拼多多首頁資源位操作方案。新店運營方案。

第一、一但有瞭真實的客戶開始拼團,想要買你們傢的東西,但是湊不齊人拼單,然後開團之後又覺得沒人拼時間會過去。於是主動...

· 1分钟前

到底如何應對通貨膨脹?

經常有一些朋友或客戶與我討論“怎樣才能跑贏通脹”這個話題。我的建議一般是:你隻需要比走路的人跑得快,或者比大多數人快一...

· 3分钟前

钟表馆事件——新本格的华丽诡计,来自异界的杀人魔法

钟表馆事件——新本格的华丽诡计,来自异界的杀人魔法

· 13分钟前

季末抄底怎么买才更便宜?唯品会上有哪些百搭单品值得推荐?

打入唯品会两年多的内部员工告诉你: 7、8月份很多衣服都会清仓处理,那价格简直就是打骨折了,尤其是8月,实体服装店进入换 ...

· 13分钟前