隨着計算機的發展、普及,世界各國爲了適應本國的語言和字符都會本身設計一套本身的編碼風格,正是因爲這種亂,致使存在不少種編碼方式,以致於同一個二進制數字可能會被解釋成不一樣的符號。爲了解決這種不兼容的問題,偉大的創想Unicode編碼應時而生!!html
Unicode又稱爲統一碼、萬國碼、單一碼,它是爲了解決傳統的字符編碼方案的侷限而產生的,它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,以知足跨語言、跨平臺進行文本轉換、處理的要求。能夠想象Unicode做爲一個「字符大容器」,它將世界上全部的符號都包含其中,而且每個符號都有本身獨一無二的編碼,這樣就從根本上解決了亂碼的問題。因此Unicode是一種全部符號的編碼[2]。工具
Unicode伴隨着通用字符集的標準而發展,同時也以書本的形式對外發表,它是業界的標準,對世界上大部分的文字系統進行了整理、編碼,使得電腦能夠用更爲簡單的方式來呈現和處理文字。Unicode至今仍在不斷增修,迄今而至已收入超過十萬個字符,它備受業界承認,並普遍地應用於電腦軟件的國際化與本地化過程。編碼
咱們知道Unicode是爲了解決傳統的字符編碼方案的侷限而產生的,對於傳統的編碼方式而言,他們都存在一個共同的問題:沒法支持多語言環境,這對於互聯網這個開放的環境是不容許的。而目前幾乎全部的電腦系統都支持基本拉丁字母,並各自支持不一樣的其餘編碼方式。Unicode爲了和它們相互兼容,其首256字符保留給ISO 8859-1所定義的字符,使既有的西歐語系文字的轉換不需特別考量;而且把大量相同的字符重複編到不一樣的字符碼中去,使得舊有紛雜的編碼方式得以和Unicode編碼間互相直接轉換,而不會丟失任何信息[1]。spa
一個字符的Unicode編碼是肯定的,可是在實際傳輸過程當中,因爲不一樣系統平臺的設計不必定一致,以及出於節省空間的目的,對Unicode編碼的實現方式有所不一樣。Unicode的實現方式稱爲Unicode轉換格式(Unicode Transformation Format,簡稱爲UTF)[1]。翻譯
Unicode是字符集,它主要有UTF-八、UTF-1六、UTF-32三種實現方式。因爲UTF-8是目前主流的實現方式,UTF-1六、UTF-32相對而言使用較少,因此下面就主要介紹UTF-8。設計
提到Unicode可能有必要了解下,UCS。UCS(Universal Character Set,通用字符集),是由ISO制定的ISO 10646(或稱ISO/IEC 10646)標準所定義的標準字符集。它包括了其餘全部字符集,保證了與其餘字符集的雙向兼容,即,若是你將任何文本字符串翻譯到UCS格式,而後再翻譯回原編碼,你不會丟失任何信息。3d
UCS不只給每一個字符分配一個代碼,並且賦予了一個正式的名字。表示一個UCS或Unicode值的十六進制數一般在前面加上「U+」,例如「U+0041」表明字符「A」。code
因爲各個系統平臺的設計不一樣,可能會致使某些平臺對字符的理解不一樣(好比字節順序的理解)。這時將會致使贊成字節流可能會被解釋爲不一樣的內容。如某個字符的十六進制爲4E59,拆分爲4E、59,在MAC上讀取時是歐諾個低位開始的,那麼MAC在遇到該字節流時會被解析爲594E,找到的字符爲「奎」,可是在Windows平臺是從高字節開始讀取,爲4E59,找到的字符爲「乙」。也就是說在Windows平臺保存的「乙」跑到MAC平臺上就變成了「奎」。這樣勢必會引發混亂,因而在Unicode編碼中採用了大頭(Big endian)、小頭(Little endian)兩種方式來進行區分。即第一個字節在前,就是大頭方式,第二個字節在前就是小頭方式。那麼這個時候就出現了一個問題:計算機怎麼知道某個文件究竟是採用哪一種編碼方式的呢?orm
Unicode規範中定義,每個文件的最前面分別加入一個表示編碼順序的字符,這個字符的名字叫作"零寬度非換行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。這正好是兩個字節,並且FF比FE大1。 htm
若是一個文本文件的頭兩個字節是FE FF,就表示該文件採用大頭方式;若是頭兩個字節是FF FE,就表示該文件採用小頭方式。
UTF-8是一種針對Unicode的可變長度字符編碼,可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度。它能夠用來表示Unicode標準中的任何字符,且其編碼中的第一個字節仍與ASCII兼容,這使得原來處理ASCII字符的系統無須或只須作少部份修改,便可繼續使用。所以,它逐漸成爲電子郵件、網頁及其餘存儲或傳送文字的應用中,優先採用的編碼。
UTF-8使用一到四個字節爲每一個字符編碼,編碼規則以下:
1)對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的unicode碼。所以對於英語字母,UTF-8編碼和ASCII碼是相同的。
2)對於n字節的符號(n>1),第一個字節的前n位都設爲1,第n+1位設爲0,後面字節的前兩位一概設爲10。剩下的沒有說起的二進制位,所有爲這個符號的unicode碼。
轉換表以下:
Unicode |
UTF-8 |
0000 ~007F |
0XXX XXXX |
0080 ~07FF |
110X XXXX 10XX XXXX |
0800 ~FFFF |
1110XXXX 10XX XXXX 10XX XXXX |
1 0000 ~1F FFFF |
1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX |
20 0000 ~3FF FFFF |
1111 10XX 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX |
400 0000 ~7FFF FFFF |
1111 110X 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX |
根據上面的轉換表,理解UTF-8的轉換編碼規則就變得很是簡單了:第一個字節的第一位若是爲0,則表示這個字節單獨就是一個字符;若是爲1,連續多少個1就表示該字符佔有多少個字節。
以漢字"嚴"爲例,演示如何實現UTF-8編碼[3]。
已知"嚴"的unicode是4E25(100111000100101),根據上表,能夠發現4E25處在第三行的範圍內(0000 0800-0000 FFFF),所以"嚴"的UTF-8編碼須要三個字節,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。而後,從"嚴"的最後一個二進制位開始,依次從後向前填入格式中的x,多出的位補0。這樣就獲得了,"嚴"的UTF-8編碼是"11100100 10111000 10100101",轉換成十六進制就是E4B8A5。
經過上面的例子咱們能夠看到"嚴"的Unicode碼爲4E25,UTF-8編碼爲E4B8A5,他們二者是不同的,須要經過程序的轉換來實現,在Window平臺最簡單的直觀的方法就是記事本。
在最下面的"編碼(E)"處有四個選項:ANSI、Unicode、Unicode big endian、UTF-8。
ANSI:記事本的默認的編碼方式,對於英文文件是ASCII編碼,對於簡體中文文件是GB2312編碼。注意:不一樣 ANSI 編碼之間互不兼容,當信息在國際間交流時,沒法將屬於兩種語言的文字,存儲在同一段 ANSI 編碼的文本中
Unicode:UCS-2編碼方式,即直接用兩個字節存入字符的Unicode碼。該方式是"小頭"little endian方式。
Unicode big endian:UCS-2編碼方式,"大頭"方式。
UTF-8:閱讀上面(UTF-8)。
>>>實例:在記事本中輸入"嚴"字,依次選擇ANSI、Unicode、Unicode big endian、UTF-8四種編碼風格,而後另存爲,使用EditPlus文本工具使用"16進制查看器"進行查看,獲得以下結果:
ANSI:兩個字節"D1 CF"正是"嚴"的GB2312編碼。
Unicode:四個字節"FF FE 25 4E",其中"FF FE"表示小頭存儲方式,真正的編碼爲"25 4E"。
Unicode big endian:四個字節"FE FF 4E 25","FE FF"表示大頭存儲方式,真正編碼爲"4E 25"。
UTF-8:編碼是六個字節"EF BB BF E4 B8 A5",前三個字節"EF BB BF"表示這是UTF-8編碼,後三個"E4B8A5"就是"嚴"的具體編碼,它的存儲順序與編碼順序是一致的。
一、Unicode維基百科:http://zh.wikipedia.org/wiki/Unicode
二、Unicode百度百科:http://baike.baidu.com/view/40801.htm
三、字符編碼筆記:ASCII,Unicode和UTF-8:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
四、UTF-8百度百科:http://baike.baidu.com/view/25412.htm
-----原文出自:http://cmsblogs.com/?p=1458,請尊重做者辛勤勞動成果,轉載說明出處.
-----我的站點:http://cmsblogs.com