女人夜夜春高潮爽A∨片传媒_国产精品VIDEOS麻豆_在线精品亚洲一区二区三区_亚洲熟妇无码av

編程代碼
新聞詳情

萬字長文講解編碼知識,看這文就夠了!(二)

發布時間:2020-05-31 10:18:41 最后更新:2020-11-23 14:36:58 瀏覽次數:3726

(4)UTF-8

從前述內容可以看出(chu):無論是UCS-2/4還是UTF-16/32,一個(ge)字(zi)符都(dou)需要多(duo)個(ge)字(zi)節(jie)(jie)來編碼,這(zhe)對(dui)那些英語國家來說(shuo)多(duo)浪費帶(dai)寬啊!(尤其(qi)在網速本來就不(bu)快的(de)那個(ge)年(nian)代......),而且(qie)我(wo)們注意到UTF-16最少2字(zi)節(jie)(jie)和UTF-32不(bu)變4字(zi)節(jie)(jie),這(zhe)肯定是不(bu)兼容ASCII碼的(de),由(you)此,UTF-8產生(sheng)了。

在UTF-8編碼(ma)(ma)中,ASCII碼(ma)(ma)中的字符(fu)還是ASCII碼(ma)(ma)的值,只需要一個字節表示(shi),其(qi)余的字符(fu)需要2字節、3字節或4字節來(lai)表示(shi)。

UTF-8的編碼(ma)規則:

  • 對于ASCII碼中(zhong)(zhong)的符號(hao),使用(yong)單(dan)字節編碼,其編碼值(zhi)與(yu)ASCII值(zhi)相同。其中(zhong)(zhong)ASCII值(zhi)的范圍為0~0x7F,所有(you)編碼的二進制值(zhi)中(zhong)(zhong)第一(yi)位為0(這個正好(hao)可以用(yong)來(lai)區(qu)分(fen)單(dan)字節編碼和多字節編碼)。

  • 其它字(zi)符(fu)用多個(ge)(ge)字(zi)節(jie)來編(bian)碼(假設用N個(ge)(ge)字(zi)節(jie)),多字(zi)節(jie)編(bian)碼需(xu)滿(man)足(zu):第(di)一個(ge)(ge)字(zi)節(jie)的前N位都(dou)(dou)為(wei)(wei)1,第(di)N+1位為(wei)(wei)0,后(hou)面N-1 個(ge)(ge)字(zi)節(jie)的前兩位都(dou)(dou)為(wei)(wei)10,這N個(ge)(ge)字(zi)節(jie)中其余(yu)位全(quan)部用來存儲Unicode中的碼位值(zhi)。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

現如今UTF-8 是互(hu)聯網上(shang)使用最(zui)廣(guang)的(de)一種 Unicode 的(de)實(shi)現(xian)方式(shi),是其他兩(liang)種無可比擬的。

(5)UTF的字節序和BOM

字節序就要(yao)先(xian)補充一點知識:

碼(ma)元(code unit):是能(neng)用于處理或交換編(bian)碼(ma)文(wen)本的最(zui)(zui)小(xiao)比特組合。它代(dai)表(biao)某種編(bian)碼(ma)中最(zui)(zui)小(xiao)的可用來識別一個合法(fa)字(zi)符(fu)的最(zui)(zui)小(xiao)字(zi)節數(shu)序列。

  • UTF-8使(shi)用(yong)變長的字(zi)(zi)節序(xu)列來表示字(zi)(zi)符(fu);某個(ge)(ge)字(zi)(zi)符(fu)(對(dui)應一(yi)個(ge)(ge)碼點)可能使(shi)用(yong)1-4個(ge)(ge)字(zi)(zi)節才(cai)能表示;在UTF-8中一(yi)個(ge)(ge)字(zi)(zi)符(fu)最小可能一(yi)個(ge)(ge)字(zi)(zi)節,所以我(wo)們規定(ding)1個(ge)(ge)字(zi)(zi)節就是一(yi)個(ge)(ge)碼元;

  • UTF-16使用也變長(chang)字節序(xu)列來表示字符;某個(ge)字符(對應一(yi)個(ge)碼點(dian))可能使用2個(ge)或者4個(ge)字符來表示;因(yin)為2個(ge)字節序(xu)列是最小(xiao)的(de)能夠識別一(yi)個(ge)碼點(dian)的(de)單位(wei),同理(li)我們規定2個(ge)字節就是一(yi)個(ge)碼元(yuan);

  • UTF-32使(shi)用定長(chang)的4個(ge)(ge)字(zi)節表示(shi)一個(ge)(ge)字(zi)符;一個(ge)(ge)字(zi)符(對應一個(ge)(ge)碼(ma)點)使(shi)用4個(ge)(ge)字(zi)符來(lai)表示(shi),這(zhe)樣4個(ge)(ge)字(zi)節就是一個(ge)(ge)碼(ma)元。

簡單(dan)來說,就是(shi)(shi)“碼(ma)點(dian)”經過映(ying)射后得到的二進制(zhi)串(chuan)的轉(zhuan)(zhuan)換(huan)格式單(dan)位(wei)稱之為“碼(ma)元”。“碼(ma)點(dian)”就是(shi)(shi)一串(chuan)二進制(zhi)數,“碼(ma)元”就是(shi)(shi)切分這(zhe)(zhe)個(ge)二進制(zhi)數的方法。這(zhe)(zhe)些編碼(ma)每次(ci)處(chu)理(li)(li)一個(ge)碼(ma)元,你可以把(ba)它理(li)(li)解為UTF-8每次(ci)讀碼(ma)點(dian)的8位(wei),UTF-16每次(ci)讀碼(ma)點(dian)的16位(wei),UTF-32每次(ci)讀碼(ma)點(dian)的32位(wei),。當然這(zhe)(zhe)也是(shi)(shi)為什么叫這(zhe)(zhe)些叫Unicode轉(zhuan)(zhuan)換(huan)格式的原因。處(chu)理(li)(li)的是(shi)(shi)同(tong)一個(ge)字符集,但是(shi)(shi)處(chu)理(li)(li)方式不同(tong)。

字節序

UTF-8一次一個(ge)UTF-8碼元,即處(chu)理一個(ge)字(zi)節(jie)(jie)(jie),沒有字(zi)節(jie)(jie)(jie)序的問題(ti)。UTF-16一次處(chu)理一個(ge)UTF-16碼元,對應兩個(ge)字(zi)節(jie)(jie)(jie),UTF-32一次一個(ge)UTF-32碼元,對應處(chu)理四個(ge)字(zi)節(jie)(jie)(jie),所以這就(jiu)要考慮到一個(ge)字(zi)節(jie)(jie)(jie)序問題(ti)。

以UTF-16w為例(li)(li),在解釋一個UTF-16編碼(ma)文(wen)本前(qian),首先要弄清楚每(mei)個編碼(ma)單元的(de)字節序(xu)。例(li)(li)如收到一個“奎”的(de)Unicode編碼(ma)是594E,“乙”的(de)Unicode編碼(ma)是4E59。

如果我們收到UTF-16字節流“594E”,那么(me)這(zhe)是“奎”還是“乙”?這(zhe)就考慮大(da)小端問題,所以UTF-16編碼包括三種:UTF-16BE(Big Endian),UTF-16LE(Little Endian)、UTF-16(類似的(de)名稱UCS-2BE和(he)UCS-2LE用于顯示UCS-2的(de)版本。)

UTF-16BE和(he)UTF-16LE好(hao)理解,直接指定了字節序(大小端),但(dan)是UTF-16怎么處理呢?

Unicode規范中推(tui)薦的標記字節順序的方法是BOM。BOM不(bu)是“Bill Of Material”的BOM表(biao),而是Byte Order Mark。BOM是一個(ge)有點小聰明的想法:

在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAKSPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸字節流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。這(zhe)樣(yang)如果(guo)接收者收到(dao)FEFF,就表明這(zhe)個(ge)字節流(liu)是Big-Endian的(de);如果(guo)收到(dao)FFFE,就表明這(zhe)個(ge)字節流(liu)是Little-Endian的(de)

同樣(yang)的(de)類比,UTF-32也(ye)是(shi)這樣(yang)的(de)。有UTF-32BE、UTF-32LE、UTF-32。前面(mian)UTF-32BE和UTF-32LE直接指定了字節(jie)序(xu)(大小(xiao)端),后(hou)面(mian)的(de)UTF-32也(ye)是(shi)靠(kao)BOM。

UTF-8不需(xu)要(yao)BOM來表明字(zi)節順序,但可以(yi)(yi)(yi)用BOM來表明編碼(ma)方式。字(zi)符"ZERO WIDTH NO-BREAKSPACE"的UTF-8編碼(ma)是EF BB BF(讀(du)者可以(yi)(yi)(yi)用我們(men)前面介(jie)紹的編碼(ma)方法驗證一下)。所以(yi)(yi)(yi)如果接收者收到以(yi)(yi)(yi)EF BB BF開頭的字(zi)節流,就知道(dao)這是UTF-8編碼(ma)了。

Windows就是使用(yong)BOM來標記(ji)文(wen)(wen)本文(wen)(wen)件(jian)的(de)(de)(de)編碼(ma)(ma)方式(shi)的(de)(de)(de)。它(ta)就建議所有的(de)(de)(de) Unicode 文(wen)(wen)件(jian)應該以(yi) ZERO WIDTH NOBREAK SPACE(U+FEFF)字符開頭(tou)(tou)。這作為(wei)一(yi)個“特征符”或“字節(jie)順序標記(ji)(byte-ordermark,BOM)”來識別文(wen)(wen)件(jian)中使用(yong)的(de)(de)(de)編碼(ma)(ma)和字節(jie)順序。所以(yi)用(yong)Windows自帶的(de)(de)(de)記(ji)事本將文(wen)(wen)件(jian)保存為(wei)UTF-8編碼(ma)(ma)的(de)(de)(de)時候,記(ji)事本會自動在文(wen)(wen)件(jian)開頭(tou)(tou)插(cha)入BOM(雖(sui)然BOM對UTF-8來說并不(bu)是必須的(de)(de)(de))。

但(dan)也有(you)(you)一些系統(tong)或程序不支持BOM,因(yin)此帶(dai)有(you)(you)BOM的(de)(de)Unicode文件(jian)有(you)(you)時會帶(dai)來一些問(wen)題。比如JDK1.5以及(ji)之前(qian)的(de)(de)Reader都不能(neng)處理帶(dai)有(you)(you)BOM的(de)(de)UTF-8編(bian)碼(ma)的(de)(de)文件(jian),解析這種格(ge)式(shi)的(de)(de)xml文件(jian)時,會拋出異(yi)常:Content is not allowed inprolog。

Linux/UNIX 并沒有使用 BOM,因為它會(hui)破壞現有的(de) ASCII 文(wen)件的(de)語法約定(ding)。所以一般我(wo)們(men)不建議用Windows自帶(dai)的(de)記事本(ben)編輯UTF-8文(wen)件就是這(zhe)樣。

總結

1、簡單地說(shuo):Unicode和UCS是字符集,不(bu)屬(shu)于編(bian)碼(ma)(ma)UTF-8、UTF-16、UTF-32等是針(zhen)對Unicode字符集的編(bian)碼(ma)(ma),UCS-2和UCS-4是針(zhen)對UCS字符集的編(bian)碼(ma)(ma)(只是我(wo)們習(xi)慣把Unicode字符集編(bian)碼(ma)(ma)簡稱(cheng)為Unicode編(bian)碼(ma)(ma),把UCS字符集編(bian)碼(ma)(ma)稱(cheng)為UCS編(bian)碼(ma)(ma))。

Unicode沿用UCS字(zi)符集(ji),在UCS-2和UCS-4基(ji)礎上提出的(de)(de)UTF-16、UTF-32。并發(fa)展了(le)(le)UTF-8,發(fa)展到現在,就密不可分了(le)(le),大家基(ji)于UCS就把Uniocde維護好就行(xing),發(fa)布(bu)標準(zhun)大家統一(yi)(yi)。以往的(de)(de)UCS-2和UCS-4概念就默認作廢了(le)(le)這樣(yang)(yang)一(yi)(yi)個關系,整個他們的(de)(de)發(fa)展長話短說就是這樣(yang)(yang),懂(dong)了(le)(le)嗎。

2、UTF-8、UTF-16、UTF-32、UCS-2、UCS-4對比:

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

由于歷史方面的原因,你還會在不少地方看到把Unicode稱為一種編碼的情況,那是因為早期的2字節編碼最初(chu)稱為“ Unicode”但現(xian)在(zai)稱(cheng)為“ UCS-2”,這種情況下的 Unicode 通常就是 UTF-16 或者是更早的 UCS-2 編碼(ma)(ma),只是被一直(zhi)搞(gao)混了,在某些(xie)老軟件上尤為常見(jian)。比如下面editplus里面文件編碼(ma)(ma)設置。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

以前的(de)Windows電腦上的(de)記事本(左邊)顯示(shi)的(de)是Unicode,不過現在好像改了變成(cheng)了UTF-16。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

不過(guo)由于各種(zhong)原因,必須承認,在不同(tong)的(de)語境下,“Unicode”這個詞有著不同(tong)的(de)含(han)義。

它可能指:

(1)Unicode 標準

(2)Unicode 字符集

(3)Unicode 的抽(chou)象編碼(ma)(編號(hao)),也即碼(ma)點、碼(ma)位(code point)

(4)Unicode 的(de)一個(ge)具體(ti)編(bian)碼實(shi)現,通常(chang)即為變長(chang)的(de) UTF-16(16 或 32 位),又或者是更早期的(de)定長(chang) 16 位的(de) UCS-2

所以像我一(yi)般有時(shi)候非(fei)要區分的話都(dou)是直接說全(quan),Unicode 標準,Unicode 字(zi)符集(ji),Unicode編(bian)碼等等。

ANSI編碼

為使(shi)計算機(ji)支(zhi)持更多語言,通常使(shi)用0x800~xFF范(fan)圍的2個字(zi)節(jie)來(lai)表示1個字(zi)符(fu)。比如:漢字(zi)‘中’ 在中文操作系統中,使(shi)用 [0xD6,0xD0]這兩(liang)個字(zi)節(jie)存儲。

不同的國(guo)家和(he)地區(qu)制定了(le)不同的標(biao)準(zhun),由此產生了(le) GB2312、GBK、GB18030、Big5、Shift_JIS 等各自(zi)的編碼(ma)標(biao)準(zhun)。這些使用多個(ge)字(zi)節來(lai)代表一個(ge)字(zi)符的各種(zhong)語言(yan)延(yan)伸編碼(ma)方式,稱為 ANSI 編碼(ma)。

在簡體(ti)中(zhong)(zhong)(zhong)文(wen)Windows操作系統(tong)中(zhong)(zhong)(zhong),ANSI 編碼代(dai)表(biao) GBK 編碼;在繁體(ti)中(zhong)(zhong)(zhong)文(wen)Windows操作系統(tong)中(zhong)(zhong)(zhong),ANSI編碼代(dai)表(biao)Big5;在日文(wen)Windows操作系統(tong)中(zhong)(zhong)(zhong),ANSI 編碼代(dai)表(biao) Shift_JIS 編碼。

不同 ANSI 編碼之間互不兼(jian)容,當(dang)信息在國際間交流時,無法(fa)將屬于兩種語言的(de)文字,存儲在同一(yi)段 ANSI 編碼的(de)文本(ben)中。

在(zai)使用(yong)ANSI編碼(ma)支持多語言階段(duan),每個(ge)字(zi)(zi)(zi)符使用(yong)一個(ge)字(zi)(zi)(zi)節(jie)或多個(ge)字(zi)(zi)(zi)節(jie)來表示(MBCS,Multi-Byte Character System),因此,這種(zhong)方(fang)式存放(fang)的字(zi)(zi)(zi)符也被稱作多字(zi)(zi)(zi)節(jie)字(zi)(zi)(zi)符。比如,“中文123” 在(zai)中文 Windows 95 內存中為7個(ge)字(zi)(zi)(zi)節(jie),每個(ge)漢字(zi)(zi)(zi)占(zhan)(zhan)2個(ge)字(zi)(zi)(zi)節(jie),每個(ge)英文和數字(zi)(zi)(zi)字(zi)(zi)(zi)符占(zhan)(zhan)1個(ge)字(zi)(zi)(zi)節(jie)。

在非(fei)(fei) Unicode 環境下,由于(yu)不同國家和地區采用(yong)的(de)(de)字符集不一致,很(hen)可能出(chu)現無(wu)法(fa)正常顯示所有字符的(de)(de)情(qing)況。微軟公(gong)司使用(yong)了代碼(ma)頁(ye)(Codepage)轉換(huan)表(biao)的(de)(de)技術(shu)來過渡性的(de)(de)部分解決這一問(wen)題,即通過指定(ding)的(de)(de)轉換(huan)表(biao)將(jiang)非(fei)(fei)Unicode 的(de)(de)字符編碼(ma)轉換(huan)為同一字符對應(ying)的(de)(de)系統內部使用(yong)的(de)(de)Unicode 編碼(ma)。

可以在(zai)“語言(yan)與區域(yu)設置”中選擇一(yi)個代(dai)(dai)碼頁作為非 Unicode 編(bian)(bian)碼所(suo)采用(yong)的(de)默認編(bian)(bian)碼方式,如936為簡體(ti)中文(wen)GBK,950為正(zheng)體(ti)中文(wen)Big5(皆指PC上使用(yong)的(de))。在(zai)這(zhe)種(zhong)情況(kuang)下,一(yi)些非英(ying)語的(de)歐洲語言(yan)編(bian)(bian)寫的(de)軟件和文(wen)檔很可能出現亂(luan)碼。而(er)將代(dai)(dai)碼頁設置為相(xiang)應語言(yan)中文(wen)處理又會出現問題,這(zhe)一(yi)情況(kuang)無法(fa)避免。

從根本上(shang)說,完(wan)全采用統(tong)(tong)一編(bian)碼(ma)才是解決(jue)之道,雖然(ran)現(xian)在(zai)Unicode有了,但由于歷史遺留,老(lao)軟件(jian)等等原因,所以(yi)系統(tong)(tong)統(tong)(tong)一用某種編(bian)碼(ma)格式的Unicode目前尚無法做到這一點。

代(dai)(dai)碼(ma)頁(ye)技術現在廣泛為各種平臺(tai)所采用(yong)。UTF-7 的(de)代(dai)(dai)碼(ma)頁(ye)是(shi)65000,UTF-8的(de)代(dai)(dai)碼(ma)頁(ye)是(shi)65001。簡體中文(wen)上使(shi)用(yong)的(de)代(dai)(dai)碼(ma)頁(ye)為936,GBK編碼(ma)。

以前中文(wen)DOS、中文(wen)/日文(wen)Windows95/98時代系統內碼(ma)(ma)使用的(de)是ANSI編碼(ma)(ma)(本地化(hua),根(gen)據不同(tong)(tong)地區設置不同(tong)(tong)的(de)系統內碼(ma)(ma)Windows版(ban)本),現在win7,win10等等系統的(de)內碼(ma)(ma)都是用的(de)Unicode。

不(bu)過微軟(ruan)為了(le)以(yi)前的(de)程(cheng)(cheng)序(xu)兼容性,比(bi)如(ru)在某些情況下(xia),比(bi)如(ru)你的(de)程(cheng)(cheng)序(xu)需要(yao)和不(bu)支(zhi)持Unicode的(de)程(cheng)(cheng)序(xu)交(jiao)互(hu)時,可能(neng)(neng)還(huan)是會需要(yao)用到(dao)code page,提供代碼頁服(fu)務(就好(hao)比(bi)微軟(ruan)不(bu)能(neng)(neng)說:“老子(zi)支(zhi)持unicode了(le),以(yi)后不(bu)支(zhi)持Unicode的(de)程(cheng)(cheng)序(xu)都給我(wo)滾粗(cu)。”只(zhi)能(neng)(neng)撅著屁股讓這些老掉(diao)牙的(de)程(cheng)(cheng)序(xu)仍然(ran)可以(yi)運行,于是只(zhi)好(hao)給他(ta)們提供一個(ge)“非Unicode默認字符集”) 。可以(yi)在cmd下(xia)輸入chcp查看(kan)code page。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃
  • WindowsAPI 的(de)Wide Char 表達是 UTF-16: Unicode (Windows), L"" 表示是轉換為(wei) wide char。

  • Cocoa的(de)NSString 和 Core Foundation 的(de)CFString 內(nei)部表達都(dou)是 UTF-16,所以其(qi)實 OSX 和 iOS 內(nei)部處理都(dou)用的(de)是 UTF-16。

  • JavaString 的內(nei)部表達是(shi) UTF-16,所(suo)以大量跨平(ping)臺程(cheng)序(xu)和 Android 程(cheng)序(xu)其實(shi)內(nei)部也在用(yong) UTF-16。

  • 大部分的(de)操(cao)作系統和 UI framework 的(de)內部字符串表達(內碼)都是UTF-16,不過Linux系統內使(shi)用的(de)內碼是UTF-8。

Tip:內碼(ma)和外碼(ma)

在計算機(ji)科學及相關領域(yu)當中(zhong)(zhong),內(nei)碼(ma)指的是“將(jiang)信息編(bian)碼(ma)后,透過某種方(fang)式(shi)(shi)存儲在特定(ding)記憶設(she)備時,設(she)備內(nei)部(bu)的編(bian)碼(ma)形式(shi)(shi)”。在不同(tong)的系統中(zhong)(zhong),會有不同(tong)的內(nei)碼(ma)。

在(zai)以往的(de)英文系統中(zhong),內碼(ma)為(wei)ASCII。在(zai)繁(fan)體中(zhong)文系統中(zhong),當前(qian)常用的(de)內碼(ma)為(wei)大五碼(ma)。在(zai)簡體中(zhong)文系統中(zhong),內碼(ma)則為(wei)國標碼(ma)。

為(wei)了軟件(jian)開發方(fang)便,如(ru)(ru)國際化與本地化,現在(zai)許(xu)多系(xi)統會使(shi)用Unicode做為(wei)內碼(ma),常見的操作(zuo)系(xi)統Windows、Mac OS X、Linux皆如(ru)(ru)此(ci)。許(xu)多編程語言也(ye)采(cai)用Unicode為(wei)內碼(ma),如(ru)(ru)Java、Python3。

外(wai)碼(ma)(ma)(ma)(ma):除了(le)內碼(ma)(ma)(ma)(ma),皆是外(wai)碼(ma)(ma)(ma)(ma)。要注意的是,源代碼(ma)(ma)(ma)(ma)編譯產生的目標代碼(ma)(ma)(ma)(ma)文(wen)件(jian)(如果Java可(ke)執行文(wen)件(jian)或class文(wen)件(jian))中的編碼(ma)(ma)(ma)(ma)方式(shi)屬于外(wai)碼(ma)(ma)(ma)(ma)。

在線(xian)客服(fu)
客服電話
  • 0755-23712116
  • 13310869691