关于编码ansi、GB2312、unicode与utf-8的区别
先做一個小小的試驗:
在一個文件夾里,把一個txt文本(文本里包含“今天的天氣非常好”這句話)分別另存為ansi、unicode、utf-8這三種編碼的txt文件。然后,在該文件夾上點擊右鍵,選擇“搜索(E)…”。
搜索“天氣”二字,可以搜索出ansi和unicode這兩種編碼的txt文件,搜索不出utf-8編碼的文件。
原因:
1.中文操作系統(tǒng)默認ansi編碼,生成的txt文件默認為ansi編碼,所以,可以搜索出來。
2.unicode是國際通用編碼,所以,可以搜索出來。
3.utf-8編碼是unicode編碼在網(wǎng)絡(luò)之間(主要是網(wǎng)頁)傳輸時的一種“變通”和“橋梁”編碼。utf-8在網(wǎng)絡(luò)之間傳輸時可以節(jié)約數(shù)據(jù)量。所以,使用操作系統(tǒng)無法搜索出txt文本。
?
按照utf-8創(chuàng)始人的愿望:
端(unicode)——傳輸(utf-8)——端(unicode)
?
但是,后來,許多網(wǎng)站開發(fā)者在開發(fā)網(wǎng)頁時直接使用utf-8編碼。
端(utf-8)——傳輸(utf-8)——端(utf-8)
?
所以,在瀏覽器上看到的編碼是:unicode(utf-8)。正因為在瀏覽器上這么并列地列出unicode(utf-8),造成許多網(wǎng)友(甚至不少程序員)誤認為unicode=utf-8。其實,按照utf-8創(chuàng)始人的原意,在開發(fā)網(wǎng)頁時使用utf-8編碼是錯誤的做法,并且,早期的瀏覽器也不支持解析utf-8編碼。但是,眾人的力量是巨大的,微軟不得不“趨炎附勢”,在瀏覽器上支持解析utf-8編碼。
?
問題是:utf-8編碼影響了網(wǎng)站開發(fā)者,或者說,網(wǎng)站開發(fā)者“擴展”了utf-8編碼的使用范圍。但是,網(wǎng)站開發(fā)者仍然無法影響各類文檔的開發(fā)者,所以,word文檔和一些國際通用的文檔仍然使用unicode編碼而不使用utf-8編碼。
?
比如:“嚴”的Unicode碼是4E25,UTF-8編碼是E4B8A5,兩者是不一樣的。
?
在中文和日文操作系統(tǒng)里生成的(txt和xml)文件的編碼雖然都是ansi,但是,在簡體中文系統(tǒng)下,ansi 編碼代表 GB2312 編碼,在日文操作系統(tǒng)下,ansi 編碼代表 JIS 編碼。不同 ansi 編碼之間互不兼容,當信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段 ansi 編碼的文本中。
?
結(jié)論:國際文檔(txt和xml)使用unicode編碼是正宗做法;操作系統(tǒng)和瀏覽器都能夠“理解”unicode編碼。瀏覽器“迫于壓力”才“理解”utf-8編碼。但是,操作系統(tǒng)有時只認unicode編碼。
Unicode與Unicode big endian的區(qū)別:你吃雞蛋時先吃小頭還是先吃大頭?Unicode與Unicode big endian的區(qū)別就是在編碼時小頭優(yōu)先與大頭優(yōu)先的區(qū)別?!半S波逐流”使用Unicode就OK了。
我(不是程序員)這幾年一直因為編碼問題,感到非常困惑,查了許多資料,在國際文檔的實際應用中也遇到過許多問題,所以,“感性”地總結(jié)了上述觀點,不一定準確(或者說,不一定正確)。
?
企業(yè)級項目實戰(zhàn)(帶源碼)地址:http://zz563143188.iteye.com/blog/1825168
收集五年的開發(fā)資料下載地址: ?http://pan.baidu.com/share/link?shareid=3739316113&uk=4076915866#dir/path=%2Fstudy
?
http://wenku.baidu.com/view/a651b849f7ec4afe04a1df9f.html
?
?
Unicode、UTF-8 和 ISO8859-1到底有什么區(qū)別
1.本文主要包括以下幾個方面:編碼基本知識,java,系統(tǒng)軟件,url,工具軟件等。?
在下面的描述中,將以"中文"兩個字為例,經(jīng)查表可以知道其GB2312編碼是"d6d0 cec4",Unicode編碼為"4e2d 6587",UTF編碼就是"e4b8ad e69687"。注意,這兩個字沒有iso8859-1編碼,但可以用iso8859-1編碼來"表示"。
在下面的描述中,將以"中文"兩個字為例,經(jīng)查表可以知道其GB2312編碼是"d6d0 cec4",Unicode編碼為"4e2d 6587",UTF編碼就是"e4b8ad e69687"。注意,這兩個字沒有iso8859-1編碼,但可以用iso8859-1編碼來"表示"。
2. 編碼基本知識?
最早的編碼是iso8859-1,和ascii編碼相似。但為了方便表示各種各樣的語言,逐漸出現(xiàn)了很多標準編碼,重要的有如下幾個。?
2.1. iso8859-1 通常叫做Latin-1
屬于單字節(jié)編碼,最多能表示的字符范圍是0-255,應用于英文系列。比如,字母a的編碼為0x61=97。?
很明顯,iso8859-1編碼表示的字符范圍很窄,無法表示中文字符。但是,由于是單字節(jié)編碼,和計算機最基礎(chǔ)的表示單位一致,所以很多時候,仍舊使用iso8859-1編碼來表示。而且在很多協(xié)議上,默認使用該編碼。比如,雖然"中文"兩個字不存在iso8859-1編碼,以gb2312編碼為例,應該是"d6d0 cec4"兩個字符,使用iso8859-1編碼的時候則將它拆開為4個字節(jié)來表示:"d6 d0 ce c4"(事實上,在進行存儲的時候,也是以字節(jié)為單位處理的)。而如果是UTF編碼,則是6個字節(jié)"e4 b8 ad e6 96 87"。很明顯,這種表示方法還需要以另一種編碼為基礎(chǔ)。
2.2. GB2312/GBK?
這就是漢子的國標碼,專門用來表示漢字,是雙字節(jié)編碼,而英文字母和iso8859-1一致(兼容iso8859-1編碼)。其中g(shù)bk編碼能夠用來同時表示繁體字和簡體字,而gb2312只能表示簡體字,gbk是兼容gb2312編碼的。
2.3. unicode?
這是最統(tǒng)一的編碼,可以用來表示所有語言的字符,而且是定長雙字節(jié)(也有四字節(jié)的)編碼,包括英文字母在內(nèi)。所以可以說它是不兼容iso8859-1編碼的,也不兼容任何編碼。不過,相對于iso8859-1編碼來說,uniocode編碼只是在前面增加了一個0字節(jié),比如字母a為"00 61"。?
需要說明的是,定長編碼便于計算機處理(注意GB2312/GBK不是定長編碼),而unicode又可以用來表示所有字符,所以在很多軟件內(nèi)部是使用unicode編碼來處理的,比如java。
2.4. UTF?
考慮到unicode編碼不兼容iso8859-1編碼,而且容易占用更多的空間:因為對于英文字母,unicode也需要兩個字節(jié)來表示。所以unicode不便于傳輸和存儲。因此而產(chǎn)生了utf編碼,utf編碼兼容iso8859-1編碼,同時也可以用來表示所有語言的字符,不過,utf編碼是不定長編碼,每一個字符的長度從1-6個字節(jié)不等。另外,utf編碼自帶簡單的校驗功能。一般來講,英文字母都是用一個字節(jié)表示,而漢字使用三個字節(jié)。?
注意,雖然說utf是為了使用更少的空間而使用的,但那只是相對于unicode編碼來說,如果已經(jīng)知道是漢字,則使用GB2312/GBK無疑是最節(jié)省的。不過另一方面,值得說明的是,雖然utf編碼對漢字使用3個字節(jié),但即使對于漢字網(wǎng)頁,utf編碼也會比unicode編碼節(jié)省,因為網(wǎng)頁中包含了很多的英文字符。
3. java對字符的處理?
在java應用軟件中,會有多處涉及到字符集編碼,有些地方需要進行正確的設(shè)置,有些地方需要進行一定程度的處理。?
3.1. getBytes(charset)?
這是java字符串處理的一個標準函數(shù),其作用是將字符串所表示的字符按照charset編碼,并以字節(jié)方式表示。注意字符串在java內(nèi)存中總是按unicode編碼存儲的。比如"中文",正常情況下(即沒有錯誤的時候)存儲為"4e2d 6587",如果charset為"gbk",則被編碼為"d6d0 cec4",然后返回字節(jié)"d6 d0 ce c4"。如果charset為"utf8"則最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1",則由于無法編碼,最后返回 "3f 3f"(兩個問號)。
3.2. new String(charset)?
這是java字符串處理的另一個標準函數(shù),和上一個函數(shù)的作用相反,將字節(jié)數(shù)組按照charset編碼進行組合識別,最后轉(zhuǎn)換為unicode存儲。參考上述getBytes的例子,"gbk" 和"utf8"都可以得出正確的結(jié)果"4e2d 6587",但iso8859-1最后變成了"003f 003f"(兩個問號)。?
因為utf8可以用來表示/編碼所有字符,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。
3.3. setCharacterEncoding()?
該函數(shù)用來設(shè)置http請求或者相應的編碼。?
對于request,是指提交內(nèi)容的編碼,指定后可以通過getParameter()則直接獲得正確的字符串,如果不指定,則默認使用iso8859-1編碼,需要進一步處理。參見下述"表單輸入"。值得注意的是在執(zhí)行setCharacterEncoding()之前,不能執(zhí)行任何getParameter()。java doc上說明:This method must be called prior to reading request parameters or reading input using getReader()。而且,該指定只對POST方法有效,對GET方法無效。分析原因,應該是在執(zhí)行第一個getParameter()的時候,java將會按照編碼分析所有的提交內(nèi)容,而后續(xù)的getParameter()不再進行分析,所以setCharacterEncoding()無效。而對于GET方法提交表單是,提交的內(nèi)容在URL中,一開始就已經(jīng)按照編碼分析所有的提交內(nèi)容,setCharacterEncoding()自然就無效。
4.iso-8859-1是JAVA網(wǎng)絡(luò)傳輸使用的標準 字符集,而gb2312是標準中文字符集,當你作出提交表單等需要網(wǎng)絡(luò)傳輸?shù)牟僮鞯臅r候,就需要把 iso-8859-1轉(zhuǎn)換為gb2312字符集顯示,否則如果按瀏覽器的gb2312格式來解釋iso-8859-1字符集的話,由于2者不兼容,所以會 是亂碼.
?
轉(zhuǎn)自http://hi.baidu.com/libo20475/blog/item/2761afdea8d3105d94ee37f2.html
?
unicode和utf-8是什么關(guān)系
?
?
Unicode的最初目標,是用1個16位的編碼來為超過65000個字符提供映射。但這還不夠,它不能覆蓋全部歷史上的文字,也不能解決傳輸?shù)膯栴}(implantation head-ache's),尤其在那些基于網(wǎng)絡(luò)的應用中。已有的軟件必須做大量的工作來實現(xiàn)16位的數(shù)據(jù)。
因此,Unicode用一些基本的保留字符制定了三套編碼方式。它們分別是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列來編碼的,用一個或幾個字節(jié)來表示一個字符。這種方式的最大好處,是UTF-8保留了ASCII字符的編碼做為它的一部分,例如,在UTF-8和ASCII中,“A”的編碼都是0x41. UTF-16和UTF-32分別是Unicode的16位和32位編碼方式??紤]到最初的目的,通常說的Unicode就是指UTF-16。在討論Unicode時,搞清楚哪種編碼方式非常重要。Unicode:
unicode.org制定的編碼機制, 要將全世界常用文字都函括進去.
在1.0中是16位編碼, 由U+0000到U+FFFF. 每個2byte碼對應一個字符; 在2.0開始拋棄了16位限制, 原來的16位作為基本位平面, 另外增加了16個位平面, 相當于20位編碼, 編碼范圍0到0x10FFFF.
UTF: Unicode/UCS Transformation Format
UTF-8, 8bit編碼, ASCII不作變換, 其他字符做變長編碼, 每個字符1-3 byte. 通常作為外碼. 有以下優(yōu)點:
* 與CPU字節(jié)順序無關(guān), 可以在不同平臺之間交流
* 容錯能力高, 任何一個字節(jié)損壞后, 最多只會導致一個編碼碼位損失, 不會鏈鎖錯誤(如GB碼錯一個字節(jié)就會整行亂碼)
UTF-16, 16bit編碼, 是變長碼, 大致相當于20位編碼, 值在0到0x10FFFF之間, 基本上就是unicode編碼的實現(xiàn). 它是變長碼, 與CPU字序有關(guān), 但因為最省空間, 常作為網(wǎng)絡(luò)傳輸?shù)耐獯a.
UTF-16是unicode的preferred encoding.
UTF-32, 僅使用了unicode范圍(0到0x10FFFF)的32位編碼, 相當于UCS-4的子集.
UTF與unicode的關(guān)系:
Unicode是一個字符集, 可以看作為內(nèi)碼.
而UTF是一種編碼方式, 它的出現(xiàn)是因為unicode不適宜在某些場合直接傳輸和處理. UTF-16直接就是unicode編碼, 沒有變換, 但它包含了0x00在編碼內(nèi), 頭256字節(jié)碼的第一個byte都是0x00, 在操作系統(tǒng)(C語言)中有特殊意義, 會引起問題. 采用UTF-8編碼對unicode的直接編碼作些變換可以避免這問題, 并帶來一些優(yōu)點
?
utf-8與utf-16的區(qū)別
UTF8 和 UTF16 都是變長表示的,為啥歐美技術(shù)宅會覺得太浪費了咧?因為歐美字符 0x0000 - 0x00FF 就搞定了,UTF8 最小變長是 1 個字節(jié),而 UTF16 變長是 2 個字節(jié),
.utf-8 與 uft-16 表示 'a' a的ascii是0X61?
? utf-8為[0X61] ?
? uft-16 [0x00,0X61]
UTF-8:Unicode Transformation Format-8bit,允許含BOM,但通常不含BOM。是用以解決國際上字符的一種多字節(jié)編碼,它對英文使用8位(即一個字節(jié)),中文使用24為(三 個字節(jié))來編碼。UTF-8包含全世界所有國家需要用到的字符,是國際編碼,通用性強。UTF-8編碼的文字可以在各國支持UTF8字符集的瀏覽器上顯 示。如,如果是UTF8編碼,則在外國人的英文IE上也能顯示中文,他們無需下載IE的中文語言支持包。
GBK是國家標準GB2312基礎(chǔ)上擴容后兼容GB2312的標準。GBK的文字編碼是用雙字節(jié)來表示的,即不論中、英文字符均使用雙字節(jié)來表示, 為了區(qū)分中文,將其最高位都設(shè)定成1。GBK包含全部中文字符,是國家編碼,通用性比UTF8差,不過UTF8占用的數(shù)據(jù)庫比GBK大。
GBK、GB2312等與UTF8之間都必須通過Unicode編碼才能相互轉(zhuǎn)換:
GBK、GB2312--Unicode--UTF8
UTF8--Unicode--GBK、GB2312
對于一個網(wǎng)站、論壇來說,如果英文字符較多,則建議使用UTF-8節(jié)省空間。不過現(xiàn)在很多論壇的插件一般只支持GBK。
GB2312是GBK的子集,GBK是GB18030的子集?
GBK是包括中日韓字符的大字符集合?
如果是中文的網(wǎng)站 推薦GB2312 GBK有時還是有點問題?
為了避免所有亂碼問題,應該采用UTF-8,將來要支持國際化也非常方便?
UTF-8可以看作是大字符集,它包含了大部分文字的編碼。?
使用UTF-8的一個好處是其他地區(qū)的用戶(如香港臺灣)無需安裝簡體中文支持就能正常觀看你的文字而不會出現(xiàn)亂碼。
gb2312是簡體中文的碼
gbk支持簡體中文及繁體中文
big5支持繁體中文
utf-8支持幾乎所有字符
ANSI 編碼
為使計算機支持更多語言,通常使用 0x80~0xFF 范圍的 2 個字節(jié)來表示 1 個字符。比如:漢字 '中' 在中文操作系統(tǒng)中,使用 [0xD6,0xD0] 這兩個字節(jié)存儲。
不同的國家和地區(qū)制定了不同的標準,由此產(chǎn)生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節(jié)來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文系統(tǒng)下,ANSI 編碼代表 GB2312 編碼,在日文操作系統(tǒng)下,ANSI 編碼代表 JIS 編碼。
不同 ANSI 編碼之間互不兼容,當信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。
總結(jié)
以上是生活随笔為你收集整理的关于编码ansi、GB2312、unicode与utf-8的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习中的训练集,验证集及测试集的关系
- 下一篇: 徐博 From RankNet to L