字符編碼集(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個代碼點作為專用區域,這些代碼點沒有標準化的含義,可供各個應用程序自行定義。
處理器體系結構的不同之處在於多字節機器整數映射到存儲位置的方式。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塊中,但那些非字符不是“阿拉伯語非字符”或“從右到左的非字符”,並且不在任何區別與其他非字符的其他方式,除瞭代碼點值。
單字節字符集(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)。不要太在意多字節字符集的定義,似乎有點岐義,是歷史遺留的產物。
早期字符集編碼標準有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編碼(American Standard Code for Information Interchange,美國標準信息交換碼)是目前計算機中用得最廣泛的字符集及其編碼,於1968年提出,由美國國傢標準局ANSI(American National Standards Institute)制定且已被國際標準化組織(ISO)定為國際標準,稱為ISO 646標準。適用於所有拉丁文字字母,ASCII碼有7位代碼點(code point)和8位代碼點(也稱擴展ASCII碼)兩種形式。
標準的ASCII碼用一個字節存儲,可以表示128個字符,其中最高位用作校驗碼,用於代碼傳送過程中用來檢驗是否出現錯誤的,一般分為奇校驗(正確的代碼一個字節中1的個數必須是奇數,若非奇數,則在最高位b7添1)和偶校驗(正確的代碼一個字節中1的個數必須是偶數,若非偶數,則在最高位b7添1)兩種。擴展ASCII 碼允許將每個字符的第8 位用於確定附加的128 個特殊符號字符、外來語字母和圖形符號。
擴展ASCII編碼(extended the ASCII)
由於ASCII是針對英語設計的,當處理帶有音調標號(形如漢語的拼音)的歐洲文字時就會出現問題。為瞭表示更多字符,人們打起瞭校驗碼的註意,讓最高位也用作字符表示,這就是ASCII碼擴字符集。ASCII擴展的字符集包括255個字符。
ISO8859 是一個系列的標準,主要是以同樣的碼位對應不同字符集。
MS-Windows character sets主要有以下幾種:
漢字編碼根據應用目的的不同,大致可分為如下編碼:
常見國標碼有以下幾種:
漢字在程序中是以機內碼進行表示,國標碼是一個四位十六進制數,區位碼是一個四位的十進制數。國標碼不是從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