1. 河豚號 > 生活百科 >

unicode碼表轉換(數(shù)字的unicode編碼對比)

計算機運算和存儲使用的是二進制數(shù),也就是0和1。這樣就需要一套標準,把英文字符對應成二進制數(shù)輸入到計算機,這樣才能被計算機識別。

于是,ASCII碼誕生了。

ASCII碼

英文名稱:(American Standard Code for Information Interchange,美國信息互換標準代碼)

起源:ASCII碼是鼻祖,在1967年由美國發(fā)表規(guī)范標準。

前 128位:

一個ASCII字符占用1個字節(jié)(8bit)。因此,ASCII編碼能夠表示的最大字符數(shù)是256。事實上美國使用的英文字符就那么幾個,所以前128個已足夠。這當中包含了控制字符、數(shù)字、大寫和小寫字母和其它一些標點符號。前128個屬于強制標準,各國必須遵循,一直沿用至今。

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

后 128位:

而最高位為1的后128個字符被稱為“擴展ASCII碼”,屬于非強制標準。當時,美國用它來存放英文的制表符、部分音標字符等等的一些其它符號。但是,美國萬萬沒想到是,這后128個“擴展ASCII碼”盡成為了其他國家的五花八門之地。

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

擴展ASCII碼:

既然后128字符并不是強制標準,于是,各個國家紛紛制定了屬于自己的文字編碼規(guī)范,中國也制定了自己的編碼規(guī)范GB2132,它是和ASCII碼兼容的一種編碼規(guī)范,事實上就是利用“擴展ASCII碼”沒有真正標準化這一點,把一個中文字符用兩個擴展ASCII字符來表示,也就是一個中文字符占用2個字節(jié)。

局限問題:

在英語中,用前128個符號編碼便可以表示所有字母,但是用來表示其他語言,這128個符號是遠遠不夠的。比如,在法語中,字母上方有注音符號,這咋辦呢?于是,一些歐洲國家就自行決定,利用后128位編入新的符號。比如,法語中的é的編碼為130(二進制10000010)。這樣一來,一些歐洲國家也開始使用這種編碼方式,但最多也只有256個符號。

但是,這里又出現(xiàn)了新的問題。不同的國家有不同的字母。因此,哪怕它們都使用256個符號的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (?),在俄語編碼中又會代表另一個符號。但是不管怎樣,所有各國編碼方式中,0–127表示的符號都是一樣的,不同的是128–255的這一段 。

關于亞洲國家的文字種類繁多,使用的符號就更多了,光漢字就多達10萬種左右。一個字節(jié)僅僅只能表示256種符號,肯定是不夠用的,那就必須使用多個字節(jié)表達一個符號。比如,簡體中文常見的編碼方式是 GB2312,規(guī)定使用兩個字節(jié)表示一個漢字,所以理論上最多可以表示 256 x 256 = 65536 個漢字 。

可以看出,如果讓全世界都使用“ASCII碼”或是“擴展ASCII碼”,顯然存在著諸多局限性問題。

ANSI標準

英文名稱:(AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI 美國國家標準學會)

起源:從1918年成立,到1969年正式命名為美國國家標準學會(ANSI)

ANSI定義:

ANSI是一種字符代碼,為使計算機支持更多語言,通常使用 0x00~0x7f 范圍的1 個字節(jié)來表示 1 個英文字符。超出此范圍的使用0x80~0xFFFF來編碼,比如:漢字 ‘中’ 在中文操作系統(tǒng)中,使用 2個字節(jié)來表示1個字符。

ANSI編碼:

不同的國家和地區(qū)制定了不同的標準,由此產(chǎn)生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的編碼標準。這些使用多個字節(jié)來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文Windows操作系統(tǒng)中,ANSI 編碼代表 GB2312編碼;在繁體中文Windows操作系統(tǒng)中,ANSI編碼代表Big5;在日文Windows操作系統(tǒng)中,ANSI 編碼代表 JIS 編碼。

“ANSI編碼”和“ASCII編碼“有何關聯(lián):

看到這里你是否感覺“ANSI編碼”和“ASCII編碼”的概念有相似之處?!其實,ANSI編碼所定義的0x00~0x7f 范圍(0–127)的1 個字節(jié)來表示 1 個英文字符,即ASCII碼。而定義中使用0x80~0xFFFF范圍(128–35535)來編碼使用2個字節(jié)表示1個字符,即擴展ASCII碼。而且,不同 ANSI 編碼(即不同國家的擴展ASCII碼)之間互不兼容。當信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。ANSI編碼表示英文字符時用一個字節(jié),表示中文字符用兩個字節(jié)。

舉一個例子:

Windows記事本默認保存編碼是ANSI,這個大家可以在另存為窗口中看到可選擇的編碼方式。而這個ANSI編碼,它在英文操作系統(tǒng)下用的是ASCII碼,它在簡體中文操作系統(tǒng)下用的是GB2312,它在繁體中文操作系統(tǒng)下用的是Big5,等等諸如此類。

適用對象:

ANSI編碼作為中國以及部分亞太地區(qū)的多字符編碼格式,其Windows系統(tǒng)和macOS都是提供原生支持的。但在Linux下卻是UTF-8編碼大行其道,特別是開發(fā)者清一色都使用UTF-8編碼格式。這樣看來,普通用戶用ANSI編碼,因為他們無需理解什么是ANSI編碼,而專業(yè)的開發(fā)者都以UTF-8編碼為主,開發(fā)者需要知道編碼的含義及應用場景,關于UTF-8具體后面會講到。

附圖

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

Unicode(統(tǒng)一碼)

非標準編碼產(chǎn)生的問題:

中國自己制定的GB2312只是國家標準,而非國際標準,像臺灣也自己制定一個Big5編碼,其他如韓國、日本等都有自己的編碼,這些通通不是國際標準。這種方法最大的問題就是,各國文字只適用于自己國家的編碼,不能通用在其他國家。

我們再來看看這個“擴展ASCII碼“,盡管沒有真正的標準化,可是PC里的ASCII碼還是有一個事實標準的(存放著英文制表符),所以早期非常多的軟件利用這些符號來畫表格。這樣的軟件用到中文系統(tǒng)中,這些表格符就會被誤認作中文字,破壞版面。并且,統(tǒng)計中英文混合字符串中的字數(shù),也是頭疼的一件事,我們必須判斷這個字符是否是“擴展ASCII碼”,在邏輯上處理起來顯得比較復雜。

這時候,我們就知道,要真正解決中文問題,不能從“擴展ASCII”的角度入手,也不能僅靠中國一家來解決。而必須有一個全新的編碼系統(tǒng),這個系統(tǒng)要能夠將中文、英文、法文、德文……等等全部的文字統(tǒng)一起來考慮,為每一個文字都分配一個單獨的編碼,這樣才不會有上面那種現(xiàn)象出現(xiàn)。

于是,Unicode誕生了:1990年研發(fā),到1994年正式發(fā)布1.0版本,到2020年發(fā)布13.0版本。

兩套標準:

Unicode有兩套標準,一套叫UCS-2(Unicode-16),用2個字節(jié)為字符編碼,還有一套叫UCS-4(Unicode-32),用4個字節(jié)為字符編碼。

目前使用的是UCS-2,它能夠表示的字符數(shù)為2^16=65535,基本上能夠容納全部的歐美字符和絕大部分的亞洲字符。而UCS-4是為了防止將來2個字節(jié)不夠用才開發(fā)的。在Unicode里,全部的字符被一視同仁。漢字不再使用“兩個擴展ASCII”,而是使用“1個Unicode”。注意,如今的漢字是“一個字符”了,于是,拆字、統(tǒng)計字數(shù)這些問題也就自然而然地攻克了。

可是,這個世界不是理想的,不可能在一夜之間全部的系統(tǒng)都使用Unicode來處理字符,所以Unicode在誕生之日,就必須考慮一個嚴峻的問題,和ASCII字符集之間的不兼容問題。我們知道,ASCII字符是單個字節(jié)的,比方“A”的ASCII是65。而Unicode是雙字節(jié)的,比方“A”的Unicode是0065,這就造成了一個非常大的問題:以前處理ASCII的那套機制不能被用來處理Unicode了。

unicode定義和編碼規(guī)則:

廣義的 Unicode 是一個標準,定義了一個字符集以及一系列的編碼規(guī)則,即 Unicode 字符集和 UTF-8、UTF-16、UTF-32 等等編碼。所以,簡單來講,Unicode可以看作一種標準,它包含了世界上所有的字符,什么語言、文字、符號統(tǒng)統(tǒng)包含在里面。如果可以,你甚至可以理解為unicode全球統(tǒng)一字符集。但這個unicode全球統(tǒng)一字符集不能直接輸入到計算機中,所以需要一套編碼方式才能讓計算機認識,于是UTF-8、UTF-16、UTF-32 等等編碼產(chǎn)生了,使用這些編碼就可以在計算機中進行存儲了。

UTF-8,當今的王者:

UTF-8屬于Unicode的一種可變長度字符編碼,用1到4個字節(jié)表示,它可以表示Unicode全球統(tǒng)一字符集中的任何字符,且其編碼中的第一個字節(jié)仍與ASCII相容,在UTF-8編碼中一個英文占1個字節(jié),一個中文漢字占3個字節(jié)。

舉一個例子:

既然Unicode 全球統(tǒng)一字符集為每一個字符分配一個碼位。就拿我們應用最廣泛的UTF-8來說(UTF-8 顧名思義,是一套以 8 位為一個編碼單位的可變長編碼),它將一個碼位編碼為 1 到 4 個字節(jié)。

如下表,編碼對應二進制:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

例如「知」的碼位是 30693,記作 U+77E5(30693 的十六進制為 0x77E5)

根據(jù)上表中的編碼規(guī)則,「知」字的碼位 U+77E5 屬于第三行的范圍,中文漢字使用了3個字。

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

我們再來看一個具體一點的例子(來自互聯(lián)網(wǎng)):

windows操作系統(tǒng)記事本另存為時,有四種編碼:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

我們把四種編碼分別存為4個文件:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

我們用VC++6.0或Visual Studio以二進制方式打開這4個文件,如下圖所示:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

1)ANSI編碼

A.txt有四個字節(jié):B1 E0 C2 EB。使用了GBK編碼,其中B1 E0是指”編”,C2 EB指是”碼”。

所以,記事本里的ANSI編碼,在簡體中文操作系統(tǒng)中,用的就是GBK編碼。在繁體中文操作系統(tǒng)中,用的就是Big5編碼……

2)UTF16BE編碼

UB.txt有六個字節(jié):FE FF 7F 16 78 01。其中FE FF是BOM(Byte Order Mark)。使用了Unicode字符集的UTF-16編碼,0x7F16是指”編”,0x7801是指”碼”。

UTF16BE編碼是16位(2字節(jié))的Unicode字符集編碼,BE表示big endian,即高位字節(jié)在前,低位字節(jié)在后。0x7F16的高位字節(jié)是7F,低位字節(jié)是16,UTF16BE編碼就是7F 16。

3)UTF16LE編碼

U.txt有六個字節(jié):FF FE 16 7F 01 78。其中FF FE是BOM。使用了Unicode字符集的UTF-16編碼,0x7F16是指”編”,0x7801是指”碼”。

UTF16LE編碼是16位(2字節(jié))的Unicode編碼,LE表示little endian,即低位字節(jié)在前,高位字節(jié)在后。0x7F16的高位字節(jié)是7F,低位字節(jié)是16,UTF16LE編碼就是16 7F。

由此可見:UTF16LE與UTF16BE只是高低位字節(jié)交換了一下而已。

4)UTF-8編碼

U8.txt有九個字節(jié):EF BB BF E7 BC 96 E7 A0 81。其中EF BB BF是BOM。使用了Unicode字符集的UTF-8編碼,E7 BC 96是指”編”,E7 A0 81是指”碼”。

5) BOM

BOM是Byte Order Mark的縮寫,它用來指明編碼,如下所示:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

上面的FE FF和FF FE正好逆序,這也就是Byte Order Mark(字節(jié)順序標記)的來由吧。

6) 亂碼

windows記事本是通過BOM來區(qū)分不同編碼,為什么ANSI不用BOM?原因在于——向下兼容。從DOS到Win98再到如今的Win10,記事本默認都是ANSI編碼,從沒考慮過加BOM。所以BOM對于windows記事本來說是沒必要的,也是無關緊要的。

通過BOM來區(qū)分各種編碼,是一個非常好的方法。不過,沒有歷史包袱的Linux不買賬——Linux默認使用UTF-8編碼,而且是沒有BOM的UTF-8編碼。

為了能夠打開Linux生成的沒有BOM的UTF-8編碼文件,記事本在打開沒有BOM的文本文件時,會對其進行檢查。如果所有編碼符合UTF-8,就以UTF-8編碼打開。

我們把Linux下生成的UTF-8編碼的txt拿到windows下,可以正常打開和顯示,并在windows下把內(nèi)容”編碼”替換為”聯(lián)通”,另存為選ANSI編碼。再次打開,顯示如下圖所示:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

使用VC++6.0打開這個文件,一切正常,如下圖所示:

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

windows下記事本顯示亂碼,是因為它會把”聯(lián)通”的GBK編碼C1 AA CD A8當做UTF-8編碼進行顯示。而VC++6.0沒有顯示亂碼,是因為它不支持UTF-8編碼,只支持ANSI編碼。

附上一個編碼字節(jié)數(shù)表

 

「原」unicode和utf-8有何區(qū)別?ANSI和ASCII有何關聯(lián)?

 

本文由網(wǎng)上采集發(fā)布,不代表我們立場,轉載聯(lián)系作者并注明出處:http://m.zltfw.cn/shbk/37519.html

聯(lián)系我們

在線咨詢:點擊這里給我發(fā)消息

微信號:15705946153

工作日:9:30-18:30,節(jié)假日休息