-
字符編碼
鎖定
字符編碼ASCII
美國(國家)信息交換標準(代)碼,一種使用7個或8個二進制位進行編碼的方案,最多可以給256個字符(包括字母、數字、標點符號、控制字符及其他符號)分配(或指定)數值。
ASCII碼於1961年提出,用於在不同計算機硬件和軟件系統中實現數據傳輸標準化,在大多數的小型機和全部的個人計算機都使用此碼。ASCII碼劃分為兩個集合:128個字符的標準ASCII碼和附加的128個字符的擴充和ASCII碼。比較EBCDIC。其中95個字符可以顯示。另外33個不可以顯示。 標準ASCII碼為7位,擴充為8位。
目前使用最廣泛的西文字符集及其編碼是 ASCII 字符集和 ASCII 碼( ASCII 是 American Standard Code for Information Interchange 的縮寫),它同時也被國際標準化組織( International Organization for Standardization, ISO )批准為國際標準。
基本的 ASCII 字符集共有 128 個字符,其中有 96 個可打印字符,包括常用的字母、數字、標點符號等,另外還有 32 個控制字符。標準 ASCII 碼使用 7 個二進位對字符進行編碼,對應的 ISO 標準為 ISO646 標準。下表展示了基本 ASCII 字符集及其編碼:
字母和數字的 ASCII 碼的記憶是非常簡單的。我們只要記住了一個字母或數字的 ASCII 碼(例如記住 A 為 65 , 0 的 ASCII 碼為 48 ),知道相應的大小寫字母之間差 32 ,就可以推算出其餘字母、數字的 ASCII 碼。
雖然標準 ASCII 碼是 7 位編碼,但由於計算機基本處理單位為字節( 1byte = 8bit ),所以一般仍以一個字節來存放一個 ASCII 字符。每一個字節中多餘出來的一位(最高位)在計算機內部通常保持為 0 (在數據傳輸時可用作奇偶校驗位)。
由於標準 ASCII 字符集字符數目有限,在實際應用中往往無法滿足要求。為此,國際標準化組織又制定了 ISO2022 標準,它規定了在保持與 ISO646 兼容的前提下將 ASCII 字符集擴充為 8 位代碼的統一方法。 ISO 陸續制定了一批適用於不同地區的擴充 ASCII 字符集,每種擴充 ASCII 字符集分別可以擴充 128 個字符,這些擴充字符的編碼均為高位為 1 的 8 位代碼(即十進制數 128~255 ),稱為擴展 ASCII 碼。
字符編碼編碼
在顯示器上看見的文字、圖片等信息在電腦裏面其實並不是我們看見的樣子,即使你知道所有信息都存儲在硬盤裏,把它拆開也看不見裏面有任何東西,只有些盤片。假設,你用顯微鏡把盤片放大,會看見盤片表面凹凸不平,凸起的地方被磁化,凹的地方是沒有被磁化;凸起的地方代表數字1,凹的地方代表數字0。硬盤只能用0和1來表示所有文字、圖片等信息。那麼字母”A”在硬盤上是如何存儲的呢?可能小張計算機存儲字母”A”是1100001,而小王存儲字母”A”是11000010,這樣雙方交換信息時就會誤解。比如小張把1100001發送給小王,小王並不認為1100001是字母”A”,可能認為這是字母”X”,於是小王在用記事本訪問存儲在硬盤上的1100001時,在屏幕上顯示的就是字母”X”。也就是説,小張和小王使用了不同的編碼表。小張用的編碼表是ASCII,ASCII編碼表把26個字母都一一的對應到2進制1和0上;小王用的編碼表可能是EBCDIC,只不過EBCDIC編碼與ASCII編碼中的字母和01的對應關係不同。一般地説,開放的操作系統(LINUX 、WINDOWS等)採用ASCII 編碼,而大型主機系統(MVS 、OS/390等)採用EBCDIC 編碼。在發送數據給對方前,需要事先告知對方自己所使用的編碼,或者通過轉碼,使不同編碼方案的兩個系統可溝通自如。
ASCII碼使用7位2進制數表示一個字符,7位2進制數可以表示出2的7次方個字符,共128個字符。EBCDIC碼使用8位,可以表示出2的8次方個字符,256個字符。
無論是ASCII碼還是EBCDIC碼,都無法對擁有幾萬個的漢字進行編碼。因為上面已經提過,7位2進制數最多對應上128個字符,8位最多對應上256個字符。
0~31及127(共33個)是控制字符或通信專用字符(其餘為可顯示字符),如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BS(退格)、BEL(振鈴)等;通信專用字符:SOH(文頭)、EOT(文尾)、ACK(確認)等;ASCII值為8、9、10和13分別轉換為退格、製表、換行和回車字符。它們並沒有特定的圖形顯示,但會依不同的應用程序而對文本顯示有不同的影響。
字符編碼MBCS
為了擴充ASCII編碼,以用於顯示本國的語言,不同的國家和地區制定了不同的標準,由此產生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼,又稱為"MBCS(Muilti-Bytes Character Set,多字節字符集)"。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文操作系統下,ANSI 編碼代表 JIS 編碼,所以在中文 windows下要轉碼成gb2312,gbk只需要把文本保存為ANSI 編碼即可。 不同 ANSI 編碼之間互不兼容,當信息在國際間交流時,無法將屬於兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。一個很大的缺點是,同一個編碼值,在不同的編碼體系裏代表着不同的字。這樣就容易造成混亂。導致了unicode碼的誕生。
其中每個語言下的ANSI編碼,都有一套一對一的編碼轉換器,Unicode變成所有編碼轉換的中間介質。所有的編碼都有一個轉換器可以轉換到Unicode,而Unicode也可以轉換到其他所有的編碼。
字符編碼GB2312
GB2312 也是ANSI編碼裏的一種,對ANSI編碼最初始的ASCII編碼進行擴充,為了滿足國內在計算機中使用漢字的需要,中國國家標準總局發佈了一系列的漢字字符集國家標準編碼,統稱為GB碼,或國標碼。其中最有影響的是於1980年發佈的《信息交換用漢字編碼字符集 基本集》,標準號為GB 2312-1980,因其使用非常普遍,也常被通稱為國標碼。GB2312編碼通行於我國內地;新加坡等地也採用此編碼。幾乎所有的中文系統和國際化的軟件都支持GB 2312。
GB 2312是一個簡體中文字符集,由6763個常用漢字和682個全角的非漢字字符組成。其中漢字根據使用的頻率分為兩級。一級漢字3755個,二級漢字3008個。由於字符數量比較大,GB2312採用了二維矩陣編碼法對所有字符進行編碼。首先構造一個94行94列的方陣,對每一行稱為一個“區”,每一列稱為一個“位”,然後將所有字符依照下表的規律填寫到方陣中。這樣所有的字符在方陣中都有一個唯一的位置,這個位置可以用區號、位號合成表示,稱為字符的區位碼。如第一個漢字“啊”出現在第16區的第1位上,其區位碼為1601。因為區位碼同字符的位置是完全對應的,因此區位碼同字符之間也是一一對應的。這樣所有的字符都可通過其區位碼轉換為數字編碼信息。GB2312字符的排列分佈情況見表1-4。
表1-4 GB2312 字符編碼分佈表
分區範圍 | 符號類型 |
第01區 | 中文標點、數學符號以及一些特殊字符 |
第02區 | 各種各樣的數學序號 |
第03區 | 全角西文字符 |
第04區 | 日文平假名 |
第05區 | 日文片假名 |
第06區 | 希臘字母表 |
第07區 | 俄文字母表 |
第08區 | 中文拼音字母表 |
第09區 | 製表符號 |
第10-15區 | 無字符 |
第16-55區 | 一級漢字(以拼音字母排序) |
第56-87區 | 二級漢字(以部首筆畫排序) |
第88-94區 | 無字符 |
GB2312字符在計算機中存儲是以其區位碼為基礎的,其中漢字的區碼和位碼分別佔一個存儲單元,每個漢字佔兩個存儲單元。由於區碼和位碼的取值範圍都是在1-94之間,這樣的範圍同西文的存儲表示衝突。例如漢字‘珀’在GB2312中的區位碼為7174,其兩字節表示形式為71,74;而兩個西文字符‘GJ’的存儲碼也是71,74。這種衝突將導致在解釋編碼時到底表示的是一個漢字還是兩個西文字符將無法判斷。
為避免同西文的存儲發生衝突,GB2312字符在進行存儲時,通過將原來的每個字節第8bit設置為1同西文加以區別,如果第8bit為0,則表示西文字符,否則表示GB2312中的字符。實際存儲時,採用了將區位碼的每個字節分別加上A0H(160)的方法轉換為存儲碼,計算機存儲規則是此編碼的補碼,而且是位碼在前,區碼在後。例如漢字‘啊’的區位碼為1601,其存儲碼為B0A1H,其轉換過程為:
區位碼 | 區碼轉換 | 位碼轉換 | 存儲碼 |
1001H | 10H+A0H=B0H | 01H+A0H=A1H | B0A1H |
GB2312編碼用兩個字節(8位2進制)表示一個漢字,所以理論上最多可以表示256×256=65536個漢字。但這種編碼方式也僅僅在中國行得通,如果您的網頁使用的GB2312編碼,那麼很多外國人在瀏覽你的網頁時就可能無法正常顯示,因為其瀏覽器不支持GB2312編碼。當然,中國人在瀏覽外國網頁(比如日文)時,也會出現亂碼或無法打開的情況,因為我們的瀏覽器沒有安裝日文的編碼表。
字符編碼GBK
GBK即漢字內碼擴展規範,K為擴展的漢語拼音中“擴”字的聲母。英文全稱Chinese Internal Code Specification。GBK編碼標準兼容GB2312,共收錄漢字21003個、符號883個,並提供1894個造字碼位,簡、繁體字融於一庫。GB2312碼是中華人民共和國國家漢字信息交換用編碼,全稱《信息交換用漢字編碼字符集——基本集》,1980年由國家標準總局發佈。基本集共收入漢字6763個和非漢字圖形字符682個,通行於中國大陸。新加坡等地也使用此編碼。GBK是對GB2312-80的擴展,也就是CP936字碼表 (Code Page 936)的擴展(之前CP936和GB 2312-80一模一樣)。
字符編碼基本簡介
GB 2312的出現,基本滿足了漢字的計算機處理需要,但對於人名、古漢語等方面出現的罕用字,GB 2312不能處理,這導致了後來GBK及GB 18030漢字字符集的出現。
GBK採用雙字節表示,總體編碼範圍為8140-FEFE,首字節在81-FE 之間,尾字節在40-FE 之間,剔除 xx7F一條線。總計23940 個碼位,共收入21886個漢字和圖形符號,其中漢字(包括部首和構件)21003 個,圖形符號883 個。P-Windows3.2和蘋果OS以GB2312為基本漢字編碼, Windows 95/98則以GBK為基本漢字編碼。
字符編碼計算公式
字符編碼編碼方式
字符編碼Big5
在台灣、香港與澳門地區,使用的是繁體中文字符集。而1980年發佈的GB2312面向簡體中文字符集,並不支持繁體漢字。在這些使用繁體中文字符集的地區,一度出現過很多不同廠商提出的字符集編碼,這些編碼彼此互不兼容,造成了信息交流的困難。為統一繁體字符集編碼,1984年,台灣五大廠商宏碁、神通、佳佳、零壹以及大眾一同制定了一種繁體中文編碼方案,因其來源被稱為五大碼,英文寫作Big5,後來按英文翻譯回漢字後,普遍被稱為大五碼。
大五碼是一種繁體中文漢字字符集,其中繁體漢字13053個,808個標點符號、希臘字母及特殊符號。大五碼的編碼碼錶直接針對存儲而設計,每個字符統一使用兩個字節存儲表示。第1字節範圍81H-FEH,避開了同ASCII碼的衝突,第2字節範圍是40H-7EH和A1H-FEH。因為Big5的字符編碼範圍同GB2312字符的存儲碼範圍存在衝突,所以在同一正文不能對兩種字符集的字符同時支持。
Big5編碼的分佈如表1-5所示,Big5字符主要部分集中在三個段內:標點符號、希臘字母及特殊符號;常用漢字;非常用漢字。其餘部分保留給其他廠商支持。
表1-5 Big5字符編碼分佈表
編碼範圍 | 符號類別 |
8140H-A0FEH | 保留(用作造字區) |
A140H-A3BFH | 標點符號、希臘字母及特殊符號 |
A3C0H-A3FEH | 保留(未開放用於造字區) |
A440H-C67EH | 常用漢字(先按筆劃,再按部首排序) |
C6A1H-C8FEH | 保留(用作造字區) |
C940H-F9D5H | 非常用漢字(先按筆劃,再按部首排序) |
F9D6H-FEFEH | 保留(用作造字區) |
Big5編碼推出後,得到了繁體中文軟件廠商的廣泛支持,在使用繁體漢字的地區迅速普及使用。目前,Big5編碼在台灣、香港、澳門及其他海外華人中普遍使用,成為了繁體中文編碼的事實標準。在互聯網中檢索繁體中文網站,所打開的網頁中,大多都是通過Big5編碼產生的文檔。
字符編碼Unicode
如上ANSI編碼條例中所述,世界上存在着多種編碼方式,在ANSi編碼下,同一個編碼值,在不同的編碼體系裏代表着不同的字。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文操作系統下,ANSI 編碼代表 JIS 編碼,可能最終顯示的是中文,也可能顯示的是日文。在ANSI編碼體系下,要想打開一個文本文件,不但要知道它的編碼方式,還要安裝有對應編碼表,否則就可能無法讀取或出現亂碼。為什麼電子郵件和網頁都經常會出現亂碼,就是因為信息的提供者可能是日文的ANSI編碼體系和信息的讀取者可能是中文的編碼體系,他們對同一個二進制編碼值進行顯示,採用了不同的編碼,導致亂碼。這個問題促使了unicode碼的誕生。
Unicode當然是一個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,“漢”這個字的Unicode編碼是U+6C49。
字符編碼UTF-8
為了提高Unicode的編碼效率,於是就出現了UTF-8編碼。UTF-8可以根據不同的符號自動選擇編碼的長短。比如英文字母可以只用1個字節就夠了。
UTF-8的編碼是這樣得出來的,以”漢”這個字為例:
“漢”字的Unicode編碼是U+00006C49,然後把U+00006C49通過UTF-8編碼器進行編碼,最後輸出的UTF-8編碼是E6B189。
字符編碼Base64
有的電子郵件系統(比如國外信箱)不支持非英文字母(比如漢字)傳輸,這是歷史原因造成的(認為只有美國會使用電子郵件?)。因為一個英文字母使用ASCII編碼來存儲,佔存儲器的1個字節(8位),實際上只用了7位2進制來存儲,第一位並沒有使用,設置為0,所以,這樣的系統認為凡是第一位是1的字節都是錯誤的。而有的編碼方案(比如GB2312)不但使用多個字節編碼一個字符,並且第一位經常是1,於是郵件系統就把1換成0,這樣收到郵件的人就會發現郵件亂碼。
為了能讓郵件系統正常的收發信件,就需要把由其他編碼存儲的符號轉換成ASCII碼來傳輸。比如,在一端發送GB2312編碼->根據Base64規則->轉換成ASCII碼,接收端收到ASCII碼->根據Base64規則->還原到GB2312編碼。。