使用新安裝的 myeclipse 打開了曾經的項目,發現原來的中文註釋,所有變成亂碼了。因而頭皮一陣發麻,對於喜歡透明的程序員來講,看不懂又想要弄明白的亂碼十分揪心。html
網上搜索了一陣,發現緣由是新安裝的 myeclipse 默認使用 cp1252 編碼,只要將其改爲支持中文字符的 UTF-8 便可解決中文亂碼問題。linux
爲了完全弄明白字符亂碼的緣由,下功夫學習了一番,將學習和思考的內容寫在這篇博客中。nginx
咱們在計算機屏幕上看到的是實體化的文字和符號,而在計算機存儲介質中存放的實際是二進制的比特流。把實體化的文字轉換成二進制比特流的過程,就是「編碼」,將比特流轉化成文字的過程,就是「解碼」。git
好比,「永」字在不一樣字符編碼表的十六進制和二進制編碼結果以下:程序員
字符編碼表 | 十六進制編碼 | 二進制編碼 |
UTF-8 | E6B0B8C281 | 1110 0110 1011 0000 1011 1000 1100 0010 1000 0001 |
UTF-16 | 6C380081 | 0110 1100 0011 1000 0000 0000 1000 0001 |
GBK | D3C03F | 1101 0011 1100 0000 0011 1111 |
因而可知,若是在編碼和解碼是採用了不一樣的字符編碼表,那麼就會產生錯誤的解碼結果,有時甚至沒法看到結果。github
在文章開頭的例子中,就是使用了 UTF-8 的編碼方式,又採用 Cp1252 來解碼,致使了亂碼的結果。sql
首先明確一些字符編碼的術語:編程
Unicode 對世界上大部分的文字系統進行了整理和編碼,使得電腦能夠用更爲簡單的方式來呈現和處理文字。Unicode 使用使用16位的編碼空間,也就是每一個字符佔用2個字節。這樣理論上一共最多能夠表示2^16(即65536)個字符。eclipse
Unicode 的實現方式不一樣於編碼方式。一個字符的 Unicode 編碼是肯定的。可是在實際傳輸過程當中,因爲不一樣系統平臺的設計不必定相同,以及出於節省空間的目的,對 Unicode 編碼的實現方式有所不一樣。Unicode 的實現方式稱爲 Unicode 轉換格式(Unicode Transformation Format,簡稱爲 UTF)工具
例如,若是一個僅包含基本7位 ASCII 字符的 Unicode 文件,若是每一個字符都使用2字節的原 Unicode 編碼傳輸,其第一字節的8位始終爲0。這就形成了比較大的浪費。 因此,Unicode 就是上文提到的 CCS,諸如 UTF-8 就是一種 CEF。
下面講解 UTF-8 的編碼實現方式,能夠更好地理解字符編碼表,理解 UTF-8 與 Unicode 的轉換關係。
UTF-8 (8-bit Unicode Transformation Format) 編碼爲變長編碼。編碼單位(Code Unit)爲一個字節。一個字節的前1-3個bit爲描述性部分,後面爲實際序號部分。
0
,那麼表明當前字符爲單字節字符,佔用一個字節的空間。0
以後的全部部分(7個bit)表明在 Unicode 中的序號。110
開頭,那麼表明當前字符爲雙字節字符,佔用2個字節的空間。110
以後的全部部分(5個bit)加上後一個字節的除 10
外的部分(6個bit)表明在 Unicode 中的序號。且第二個字節以 10
開頭1110
開頭,那麼表明當前字符爲三字節字符,佔用2個字節的空間。1110
以後的全部部分(4個bit)加上後兩個字節的除 10
外的部分(12個bit)表明在 Unicode 中的序號。且第2、第三個字節以 10
開頭10
開頭,那麼表明當前字節爲多字節字符的第二個字節。10
以後的全部部分(6個bit)和以前的部分一同組成在 Unicode 中的序號。具體每一個字節的特徵可見下表,其中 x
表明序號部分,把各個字節中的全部 x
部分拼接在一塊兒就組成了在Unicode字庫中的序號。
咱們分別看三個從一個字節到三個字節的 UTF-8 編碼例子:
細心的讀者能夠得出如下規律:
E
開頭的C
或 D
開頭的8
小的數字開頭的如下代碼,使用 Navicat for MySQL 環境模擬。
那麼,文章最初提到的 myeclipse 打開文件亂碼,是怎麼產生的呢?如下還原了這個過程。
執行語句:
select hex( convert('這裏是註釋' using utf8) )
獲得結果:
E8BF99E9878CE698AFE6B3A8E9878A
執行語句:
select convert(0xE8BF99E9878CE698AFE6B3A8E9878A using latin1)
latin1 編碼就是 MySQL 中的 Cp1252 編碼
獲得結果:
这里是注释
上一行,就是咱們不肯看到可是出現了的亂碼!
假設咱們獲得了上面的亂碼結果,而後查看 myeclipse 的默認編碼,發現是 Cp1252,接着,咱們知道原文件是用 UTF-8 編碼的(或者說,猜想是 UTF-8 編碼),咱們就能夠進行亂碼的還原。
執行語句:
select hex( convert('这里是注释' using latin1) )
獲得結果:
E8BF99E9878CE698AFE6B3A8E9878A
執行語句:
select convert(0xE8BF99E9878CE698AFE6B3A8E9878A using utf8)
獲得結果:
這裏是註釋
到這裏,正確的文字信息顯示出來了!
注意:有些狀況下,使用錯誤的編碼打開文件,而後再次保存的時候,會出現提示,用當前編碼保存,將會丟失字符。這是由於新編碼沒法徹底解析舊編碼生成的二進制比特流。某些智能的 IDE 能夠提示用戶使用另一種編碼格式保存當前文件。
本文簡單介紹了字符編碼的概念,闡述了亂碼產生的緣由。經過對 UTF-8 編碼方式的介紹,瞭解了一種經常使用的可變長度的字符編碼表。通常狀況下,亂碼會出如今編程開發的 IDE 和文本處理工具中。只要選擇了與文本被保存時相同的編碼,就能夠看到正確的文字。
另外,若是試圖識別亂碼,就須要知道顯示工具所使用的編碼和文件保存時使用的編碼。上文提到的 UTF-8 的編碼規律,能夠用來猜想文本在保存時是否可能使用了 UTF-8 編碼。經過解碼和再編碼的過程,能夠嘗試識別亂碼所要表達的文字。
創做日期:2016-03-05 星期六 8:49:14 PM