亂碼或者轉碼,是開發中經常碰到的問題. 理解了編碼到底是怎麼回事,解決起來就會輕鬆很多.
繼續提出問題並解決;
1. 位,字節,字符,編碼,字符集的概念
2.java中的轉碼方式
3.常見亂碼問題
1. 位,字節,字符,編碼,字符集的概念
位(bit): 我們都知道計算機只認識01, 一bit就是這裏的一個0或者1.(二進制的01)
字節(byte): 8個bit構成一個byte,可以表示英語字母,數字(這裏01是十進制的),還可以表示一些符號.是一個很具體的存儲空間.(例如 0x01, 0x45)
字符: 一個或多個字節組合起來代表一個字符.
編碼: 字節組合成字符時,需要一定的規則,這個規則就是編碼方式.(經常看到說1個漢字=2個字節,其實是錯誤的,根據編碼不同,所需字節也不同)
字符集: 字符按編碼規則,能表示出來的字符集合,就是字符集.
各個國家和地區在制定編碼標準的時候,“字符的集合”和“編碼”一般都是同時制定的。因此,平常我們所說的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”這層含義外,同時也包含了“編碼”的含義。
|
系統內碼 | 說明 | 系統 |
階段一 | ASCII | 計算機剛開始只支持英語,其它語言不能夠在計算機上存儲和顯示。 | 英文 DOS |
階段二 |
ANSI編碼 (本地化) |
爲使計算機支持更多語言,通常使用 0x80~0xFF 範圍的 2 個字節來表示 1 個字符。比如:漢字 '中' 在中文操作系統中,使用 [0xD6,0xD0] 這兩個字節存儲。 不同的國家和地區制定了不同的標準,由此產生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節來代表一個字符的各種漢字延伸編碼方式,稱爲 ANSI 編碼。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文操作系統下,ANSI 編碼代表 JIS 編碼。 不同 ANSI 編碼之間互不兼容,當信息在國際間交流時,無法將屬於兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。 |
中文 DOS,中文 Windows 95/98,日文 Windows 95/98 |
階段三 |
UNICODE (國際化) |
爲了使國際間信息交流更加方便,國際組織制定了 UNICODE 字符集,爲各種語言中的每一個字符設定了統一併且唯一的數字編號,以滿足跨語言、跨平臺進行文本轉換、處理的要求。 | Windows NT/2000/XP,Linux,Java |
然後再用表格來區分下字符,字節的概念:
|
概念描述 | 舉例 |
字符 | 人們使用的記號,抽象意義上的一個符號。 | '1', '中', 'a', '$', '¥', …… |
字節 | 計算機中存儲數據的單元,一個8位的二進制數,是一個很具體的存儲空間。 | 0x01, 0x45, 0xFA, …… |
ANSI 字符串 |
在內存中,如果“字符”是以 ANSI 編碼形式存在的,一個字符可能使用一個字節或多個字節來表示,那麼我們稱這種字符串爲 ANSI 字符串或者多字節字符串。 |
"中文123" (佔7字節) |
UNICODE 字符串 |
在內存中,如果“字符”是以在 UNICODE 中的序號存在的,那麼我們稱這種字符串爲UNICODE 字符串或者寬字節字符串。 |
L"中文123" (佔10字節) |
由於不同 ANSI 編碼所規定的標準是不相同的,因此,對於一個給定的多字節字符串,我們必須知道它採用的是哪一種編碼規則,才能夠知道它包含了哪些“字符”。而對於 UNICODE 字符串來說,不管在什麼環境下,它所代表的“字符”內容總是不變的。
2.java中的轉碼方式
在 C++ 和 Java 中,用來代表“字符”和“字節”的數據類型,以及進行編碼的方法:
類型或操作 | C++ | Java |
字符 | wchar_t | char |
字節 | char | byte |
ANSI 字符串 | char[] | byte[] |
UNICODE 字符串 | wchar_t[] | String |
字節串→字符串 | mbstowcs(), MultiByteToWideChar() | string = new String(bytes, "encoding") |
字符串→字節串 | wcstombs(), WideCharToMultiByte() | bytes = string.getBytes("encoding") |
以上需要注意幾點:
1)Java 中的 char 代表一個“UNICODE 字符(寬字節字符)”,而 C++ 中的 char 代表一個字節。
2)MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函數。
參考文章:
http://www.regexlab.com/zh/encoding.htm
http://blog.csdn.net/ygj281583295/article/details/4035386