java Java與編碼

Coding-lover發表於2015-11-21

ASCII編碼

上個世紀60年代,美國製定了一套字元編碼,對英語字元與二進位制位之間的關係,做了統一規定。這被稱為ASCII碼,一直沿用至今。ASCII碼一共規定了128個字元的編碼,比如空格”SPACE”是32(二進位制00100000),大寫的字母A是65(二進位制01000001)。這128個符號(包括32個不能列印出來的控制符號),只佔用了一個位元組的後面7位,最前面的1位統一規定為0。

ISO-8859-1編碼

ASCII碼主要是為了表示英文字元而設計的,英語用128個符號編碼就夠了,但是用來表示其他語言,128個符號是不夠的。比如,在法語中,字母上方有注音符號,它就無法用ASCII碼錶示。於是ISO組織在ASCII碼基礎上又制定了一系列標準用來擴充套件ASCII編碼,它們是ISO-8859-1~ ISO-8859-15,其中ISO-8859-1覆蓋了大多數西歐語言字元,所以應用得最廣泛。
ISO-8859-1仍然是單位元組編碼,它總共能表示256個字元。ISO-8859-1向下相容ASCII,其編碼範圍是0x00-0xFF,0x00-0x7F之間完全和ASCII一致,0x80-0x9F之間是控制字元,0xA0-0xFF之間是文字元號。
ISO-8859-1收錄的字元除ASCII收錄的字元外,還包括西歐語言、希臘語、泰語、阿拉伯語、希伯來語對應的文字元號。所以,Latin1是ISO-8859-1的別名,有些環境下寫作Latin-1。歐元符號出現的比較晚,沒有被收錄在ISO-8859-1當中。
因為ISO-8859-1編碼範圍使用了單位元組內的所有空間,在支援ISO-8859-1的系統中傳輸和儲存其他任何編碼的位元組流都不會被拋棄。換言之,把其他任何編碼的位元組流當作ISO-8859-1編碼看待都沒有問題。這是個很重要的特性,MySQL資料庫預設編碼是Latin1就是利用了這個特性。

GB2312編碼

GB2312編碼是第一個漢字編碼國家標準,由中國國家標準總局1980年釋出,1981年5月1日開始使用。GB2312編碼共收錄漢字6763個,其中一級漢字3755個,二級漢字3008個。同時,GB2312編碼收錄了包括拉丁字母、希臘字母、日文平假名及片假名字母、俄語西裡爾字母在內的682個全形字元。

分割槽表示:
GB2312編碼對所收錄字元進行了“分割槽”處理,共94個區,每區含有94個位,共8836個碼位。這種表示方式也稱為區位碼。
01-09區收錄除漢字外的682個字元。
10-15區為空白區,沒有使用。
16-55區收錄3755個一級漢字,按拼音排序。
56-87區收錄3008個二級漢字,按部首/筆畫排序。
88-94區為空白區,沒有使用。
舉例來說,“啊”字是GB2312編碼中的第一個漢字,它位於16區的01位,所以它的區位碼就是1601。

雙位元組編碼:
GB2312規定對收錄的每個字元采用兩個位元組表示,第一個位元組為“高位元組”,對應94個區;第二個位元組為“低位元組”,對應94個位。所以它的區位碼範圍是:0101-9494。區號和位號分別加上0xA0就是GB2312編碼。例如最後一個碼位是9494,區號和位號分別轉換成十六進位制是5E5E,0x5E+0xA0=0xFE,所以該碼位的GB2312編碼是FEFE。

GB2312編碼範圍:
GB2312編碼範圍是A1A1-FEFE,其中漢字的編碼範圍為B0A1-F7FE,第一位元組0xB0-0xF7(對應區號:16-87),第二個位元組0xA1-0xFE(對應位號:01-94)。

BIG5編碼

BIG5編碼是臺灣地區繁體中文標準字符集,採用雙位元組編碼,共收錄13053箇中文字,1984年實施。BIG5編碼又稱大五碼,是繁體中文字符集編碼標準,共收錄13060箇中文字,其中有二字為重複編碼。
BIG5採用雙位元組編碼,使用兩個位元組來表示一個字元。高位位元組使用了0x81-0xFE,低位位元組使用了0x40-0x7E,及0xA1-0xFE。在BIG5的分割槽中:
8140-A0FE 保留給使用者自定義字元(造字區)
A140-A3BF 標點符號、希臘字母及特殊符號。其中在A259-A261,收錄了度量衡單位用字:兙兛兞兝兡兣嗧瓩糎。
A3C0-A3FE 保留。此區沒有開放作造字區用。
A440-C67E 常用漢字,先按筆劃再按部首排序。
C6A1-F9DC 其它漢字。
F9DD-F9FE 製表符。
值得留意的是,BIG5重複地收錄了兩個相同的字:“兀、兀”(A461及C94A)、“嗀、嗀”(DCD1及DDFC)。

ANSI編碼

針對漢字的編碼,不同的國家和地區制定了不同的標準,由此產生了 GB2312、GBK、Big5、Shift_JIS 等各自的編碼標準。這些使用 1 至 4 個位元組來代表一個字元的各種漢字延伸編碼方式,稱為ANSI 編碼。
ANSI全稱是AMERICAN NATIONAL STANDARDS INSTITUTE,美國國家標準學會。在簡體中文Windows作業系統中,ANSI 編碼代表 GBK 編碼;在日文Windows作業系統中,ANSI 編碼代表 Shift_JIS 編碼。

Unicode簡介

Unicode是為整合全世界的所有語言文字而誕生的。任何字元在Unicode中都對應一個值。這個值就可以稱為這個字元的Unicode值。Unicode的值通常寫成 U+ABCD 的格式。
為什麼採用這種方式表示呢?這其中還有個過程。為了統一全世界的字元編碼,最初有兩個組織各自獨立指定標準:
(1)ISO制定了通用字符集(Universal Character Set,UCS)。UCS包括UCS-2和UCS-4。UCS-2用兩個位元組編碼,UCS-4用4個位元組編碼。
(2)多語言軟體製造商組成的統一碼聯盟,它開發的統一碼專案,制定了Unicode專案。
後來,兩個專案的參與者都認識到,世界不需要兩個不相容的字符集。於是,它們開始合併雙方的工作成果,併為創立一個單一編碼表而協同工作。從Unicode 2.0開始,Unicode採用了與ISO的UCS編碼;ISO也承諾,UCS編碼將不會替超出U+10FFFF的UCS-4編碼賦值,以使得兩者保持一致。所以,現在Unicode都是使用U+ABCD 的格式。

UCS2和UCS4編碼

Unicode是為整合全世界的所有語言文字而誕生的。任何文字在Unicode中都對應一個值,這個值稱為程式碼點(Code Point)。程式碼點的值通常寫成 U+ABCD 的格式。而文字和程式碼點之間的對應關係就是UCS-2(Universal Character Set coded in 2 octets)。顧名思義,UCS-2是用兩個位元組來表示程式碼點,其取值範圍為 U+0000~U+FFFF。
為了能表示更多的文字,人們又提出了UCS-4,即用四個位元組表示程式碼點。它的範圍為 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一樣的。要注意,UCS-2和UCS-4只規定了程式碼點和文字之間的對應關係,並沒有規定程式碼點在計算機中如何儲存。規定儲存方式的稱為UTF(Unicode Transformation Format),其中應用較多的就是UTF-16和UTF-8了。

UTF-16編碼

UTF是Unicode Transformation Format的縮寫,表示了Unicode的儲存轉換形式。Unicode只表示了字元的程式碼點。如何儲存則是通過UTF規定來實現的。最常見的就是UTF-16和UTF-8。
UTF-16是完全對應於UCS-2的,即把UCS-2規定的程式碼點通過Big Endian或Little Endian方式直接儲存下來。所以UTF-16採用2個位元組來儲存Unicode。UTF-16也可以表示UCS-4的部分字元,所以UTF-16也採用4個位元組來儲存Unicode。

Big Endian和Little Endian

一個字元可能佔用多個位元組,那麼這多個位元組在計算機中如何儲存呢?比如字元0xABCD,它的儲存格式到底是AB CD,還是CD AB 呢?實際上兩者都有可能,並分別有不同的名字。如果儲存為AB CD,則稱為Big Endian;如果儲存為 CD AB,則稱為Little Endian。
具體來說,以下這種儲存格式為Big Endian,因為值(0xABCD)的高位(0xAB)儲存在前面:
地址 值
0x00000000 AB
0x00000001 CD
相反,以下這種儲存格式為Little Endian:
地址 值
0x00000000 CD
0x00000001 AB

UTF-8編碼

通常情況下,UTF-16統一採用兩個位元組表示一個字元,雖然在表示上非常簡單方便,但是也有其缺點,有很大一部分字元用一個位元組就可以表示的現在要用兩個位元組表示,儲存空間放大了一倍,而在網路頻寬還非常有限的情況下,這樣會增大網路傳輸的流量,而且也沒有必要。而UTF-8採用了一種變長技術,每個編碼區域有不同的字碼長度。不同型別的字元可以由1-6個位元組組成。UTF-8的編碼規則是:
(1)如果一個位元組,最高位(第8位)為0,表示這是一個ASCII字元(00-7F)。可見,所有的ASCII編碼已經是UTF-8了。
(2)如果一個位元組,以11開頭,連續的1的個數暗示這個字元的位元組數,例如:110xxxxx代表它是雙位元組UTF-8字元的首位元組。
(3)如果一個位元組,以10開始,表示它不是首位元組,需要向前查詢才能得到當前字元的首位元組。

UTF-16編碼和Java,UTF-8編碼和網際網路

Java採用UTF-16編碼。在Java誕生的時候,UTF-16編碼使用的更廣泛,而且定長編碼的形式也方便計算器處理。後來,隨著網際網路的流行和壯大,UTF-8編碼才得以出現。UTF-8採用變長位元組的方式編碼,這樣在傳輸過程節省了頻寬。

轉載自:金絲燕網/字元和編碼

相關文章