1,編碼只是表示字符一種方式,字符還是那個字符,只不過其數值表示的不一樣而已。字體、樣式和用什么編碼表示字符沒有任何關系。不可能存在UTF-8達不到的效果。除非你處理字符串的方式有問題,例如后臺程序寫死了一個中文等于兩個字節。或者你的css文件編碼有問題。例如html用了UTF-8編碼,而css文件用了GB編碼,又沒有用charset指定css的編碼等等。而對于前臺HTML來說,無論頁面什么編碼,JavaScript內建的字符串類型是UTF-16編碼的,不存在任何問題。 UTF-8的編碼是變長的,從1字節(兼容ASCII)到4字節不等。用UTF-8的好處是它能表示任意Unicode字符,而GBK/GB2312做不到,除了不能表示一些外國文字外,一些古老的中文(如康熙字典里的一些字)也不能表示,但在Unicode里就有。后來發展出的GB18030可以表示任意Unicode字符,也是變長編碼,兼容GBK,最長4個字節。編碼問題是很麻煩的事情,尤其是同一個系統中存在多種編碼的情況。由于每種編碼表示的字符范圍有限,所以轉碼過程中有可能丟失字符信息。因此,如果你的程序著眼于全球市場,而不僅僅局限于中文用戶,或者未來發展有這方面的需求,那么就應該堅持程序內部都使用同一種Unicode編碼,如UTF-8,這樣以后程序在國際化時就不會存在什么編碼問題。
來源:?http://news.csdn.net/n/20080509/115815.html
2,
ISO-8859-1. 這套標準完全和ASCII兼容,它使用8位二進制表示一個字符 —---
剛好一個字節,其中最高位是0時的解釋和ASCII一樣,但最高位是1時則用于定義其它字符,這樣就在保證和
ASCII兼容的同時又擴展了ASCII,可以多表示字符啦
對java中的編碼,類加載,類路徑查找,集合等機制的理解
3,
(轉)談談我對Java中Unicode、編碼的理解
此篇文章寫得很清楚。
在Java 中,String的getBytes()方法就是對特定的字符串(unicode)按照給定的字符集進行編碼(encode),new String()則可以按照某個字符集將字節流轉換回unicode(decode)
之所以你會經常看到new String(text.getBytes("ISO-8859-1"),"GBK")這句代碼,是因為一個GBK的字節流被錯誤地以ISO-8859- 1的方式轉換為String(unicode)了!
如果系統誤以為是其它編碼格式,就有可能再也轉換不回來了,因為編碼轉換并不是負負得正那么簡單的
4,
ANSI和Unicode big endia:
我們在Windows系統中保存文本文件時通常可以選擇編碼為ANSI、Unicode、Unicode big endian
和UTF-8,這里的ANSI和Unicode big endia是什么編碼呢?
Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會多出幾個字節,分別是FF、FE(Unicode),FE、FF(Unicode
big endian),EF、BB、BF(UTF-8)
例如"聯通",如果保存為Unicode,則hex為ff fe 54 80 la 90
如果保存為Unicode big endian,則hex為fe ff 80 54 90 la
也就是說,在windows里,所謂的Unicode其實是Unicode little endian
ANSI:
對于簡體中文windows操作系統,ANSI就是GBK
UCS有兩種格式:UCS-2和UCS-4。顧名思義,UCS-2就是用兩個字節編碼,UCS-4就是用4個字節(實際上只用了31位,最高位必須為0)編碼
說UCS-4中,高兩個字節為0的碼位被稱作BMP
將UCS-4的BMP去掉前面的兩個零字節就得到了UCS-2。在UCS-2的兩個字節前加上兩個零字節,就得到了UCS-4的BMP。而目前的UCS-4規范中還沒有任何字符被分配在BMP之外。
所以目前
UNICODE=UCS-2big endian和little endian
big endian和little endian是CPU處理多字節數的不同方式。例如“漢”字的Unicode編碼是6C49。那么寫到文件里時,究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big
endian。如果將49寫在前面,就是little endian。
“endian”這個詞出自《格列佛游記》。小人國的內戰就源于吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,一個皇帝送了命,另一個丟了王位。
我們一般將endian翻譯成“字節序”,將big endian和little endian稱作“大尾”和“小尾”。
UTF編碼
UTF-8就是以8位為單元對UCS進行編碼。從UCS-2到UTF-8的編碼方式如下:
UCS-2編碼(16進制) | UTF-8 字節流(二進制) |
0000 - 007F | 0xxxxxxx |
0080 - 07FF | 110xxxxx 10xxxxxx |
0800 - FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
例如“漢”字的Unicode編碼是6C49。6C49在0800-FFFF之間,所以肯定要用3字節模板了:1110xxxx
10xxxxxx 10xxxxxx。將6C49寫成二進制是:0110
110001 001001, 用這個比特流依次代替模板中的x,得到:11100110 10110001
10001001,即E6 B1 89。
讀者可以用記事本測試一下我們的編碼是否正確。需要注意,UltraEdit在打開utf-8編碼的文本文件時會自動轉換為UTF-16,可能產生混淆。你可以在設置中關掉這個選項。更好的工具是Hex
Workshop。
UTF-16以16位為單元對UCS進行編碼。對于小于0x10000的UCS碼,UTF-16編碼就等于UCS碼對應的16位無符號整數。對于不
小于0x10000的UCS碼,定義了一個算法。不過由于實際使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以認為
UTF-16(確切的說,是utf16-BE)和UCS-2(也就是我們通常所說的UNICODE)基本相同。但UCS-2只是一個編碼方案,UTF-16卻要用于實際的傳輸,所以就不得不考慮字節序的問題。
UTF的字節序和BOM
UTF-8以字節為編碼單元,沒有字節序的問題。UTF-16以兩個字節為編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的字
節序。例如“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節流“594E”,那么這是“奎”
還是“乙”?
Unicode規范中推薦的標記字節順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:
在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸字節流前,先傳輸字符"ZERO
WIDTH NO-BREAK SPACE"。
這樣如果接收者收到FEFF,就表明這個字節流是Big-Endian的;如果收到FFFE,就表明這個字節流是Little-Endian的。因此字符"ZERO
WIDTH NO-BREAK SPACE"又被稱作BOM。
UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF
BB BF(讀者可以用我們前面介紹的編碼方法驗證一下)。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。
Windows就是使用BOM來標記文本文件的編碼方式的。
UTF-8 是 1-4 字節變長編碼方案;
JVM用的是UCS-2
String其實是由char拼起來的,對char進行int后得到的數字就是unicode碼16進制換算后的值
例如
char?? int??? Unicode
1????? 49???? 0031
中??? 20013?? 4e2d
國??? 22269?? 56fd
Integer.toHexString((int)str.charAt(i))
Windows的內碼也是Unicode
從http://www.fmddlmyy.cn/text6.html受益良多。
6,http://www.javaeye.com/topic/398782比較形象,
提到一個很著名的奇怪現象:當你在 windows 的記事本里新建一個文件,輸入"聯通"兩個字之后,保存,關閉,然后再次打開,你會發現這兩個字已經消失了,代之的是幾個亂碼!
但有錯誤
UTF應該是UCS Transformation Format,其中的T不是Transfer
7,
ASCII碼表

ISO-8859-1收錄的字符除ASCII收錄的字符外,還包括一些其他語言的文字符號和一些控制字符。歐元符號出現的比較晚,沒有被收錄在ISO-8859-1當中。



因為ISO-8859-1編碼范圍使用了單字節內的所有空間,在支持ISO-8859-1的系統中傳輸和存儲其他任何編碼的字節流都不會被拋棄。換言之,把其他任何編碼的字節流當作ISO-8859-1編碼看待都沒有問題。這是個很重要的特性,MySQL數據庫默認編碼是Latin1就是利用了這個特性。Latin1是ISO-8859-1的別名
法語及芬蘭語本來也使用ISO/IEC?8859-1來表示。但因它沒有法語使用的 ?、?、 ? 三個字母及芬蘭語使用的 ?、?、?、? ,故于1998年被
ISO/IEC?8859-15所取代。(ISO?8859-15同時加入了歐元符號)


http://blog.cathayan.org/item/1765
http://hedong.3322.org/archives/000355.html