1、編碼是什麼html
編碼爲了某種目的把信息從一種形式集合轉換爲另外一種形式集合的過程,古時的鳴金收兵,從某種意義上講也是一種編碼,將帥發出了退兵的命令,爲了讓更多的人可以知道這個命令,傳令兵把這個信息轉換爲了鑼聲,傳遞了出去linux
與編碼相對的還有解碼,解碼是根據某種規則將信息恢復到原狀的過程,士兵以前都接收過訓練,在聽到鑼聲以後,明白到鑼聲表明退兵,便開始執行這一命令。git
旗語,電報中的莫斯電碼等等,這些東西里面也包含了編碼github
2、關於字符集和字符編碼web
由於計算機中的信息都是用二進制數表示的,因此咱們必須將漢字、英文按照必定的規則表示出來儲存在計算機中windows
因此字符編碼就是爲了信息處理,將天然語言中的一個集合與另外一個集合如(如號碼和電脈衝)進行配對,創建對應關係,常見的編碼方式有ASCII,GBK,GB2312,utf8,utf16,utf32等網絡
字符集就是是一個系統支持的全部抽象字符的集合,字符是各類文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。,每個抽象字符都會對應一個惟一的codepoint,常見字符集有:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。ide
使用1個字節編碼的字符集,叫作單字節字符集(SBCS - Single-Byte Character Set)。編碼
使用一、二、三、4等不等字節編碼的字符集,叫作多字節字符集(MBCS - Multi-Byte Character Set)。idea
3、編碼的歷史
早期的時候,計算機的字符編碼並無統一的標準,不少都是來自電報時產生的編碼方式,如博多電碼,霍勒內斯碼等,
EBCDIC
1962年 AT&T將第一部商用遠程通信衛星-Telstar I 放入環繞地球的軌道。同年,IBM公司建立了一套編碼標準,EBCDIC,根據早期打孔機式的二進化十進數(BCD, Binary Coded Decimal)排列而成,定義了256種不一樣的8位字符。
ASCII
1963年 ASCII做爲EBDIC替代產品而發展起來。ASCII由96個大小寫字母、數字加上32個非打印字符組成
ASCII編碼只佔用1個字節,標準 ASCII 碼是 7 位編碼,但爲了湊足一字節,多出來的一位,最高位一般設置爲0。
擴展Ascii碼
ASCII的缺點就是表示的東西太少了,只能用於顯示現代美國英語
所以人們便利用ASCII的第8位產生了新的編碼方式,第一個iso-8859-1字符集。又叫:Latin-1 編碼(西歐編碼),擴展ASCII字符集使用8位(bits)表示一個字符,其中0-127字符及位置編碼徹底兼容ascii碼。只是在128-255位置編入了新字符,解決了部份西歐語言的顯示問題。
後來陸續出了iso-8859-2…-15字符集。都徹底兼容ascii碼。
因爲擴展ASCII只是解決了部分西歐語言的顯示問題,表示字符仍是太少,對其餘語言無能爲力,所以各個國家又爲本身國家的文字制定了一系類標準
GB2312
1980年,中國製定了GB2312-80,一共收錄了 7445 個字符,包括 6763 個漢字和 682 個其它符號。
GB2312規定一個小於127的字符的意義與原來相同,但兩個大於127的字符連在一塊兒時,就表示一個漢字,前面的一個字節(稱之爲高字節)從0xA1用到 0xF7,後面一個字節(低字節)從0xA1到0xFE,這樣就能夠組合出大約7000多個簡體漢字了。在這些編碼裏,還把數學符號、羅馬希臘的 字母、日文的假名們都編進去了,連在ASCII裏原本就有的數字、標點、字母都通通從新編了兩個字節長的編碼,這就是常說的"全角"字符,而原來在127號如下的那些就叫"半角"字符了。
GB2312使用了2個字節進行編碼
因爲GB2312只收錄了6763個漢字,一些GB2312推出之後才簡化的漢字「囉」,鎔」和一些罕見字並未收錄進去,1993年,有出現了「GB 13000.1-93」,簡稱爲GB13000。
GB13000使用2個字節進行編碼,收錄中國大陸、臺灣、日本及韓國通用字符集的漢字,總共有20,902個。
GBK是對GB2312的擴展,最先實現於windows95簡體中文版,使用2個字節進行編碼中文字符,英文字符和以前表示同樣,所以想下兼容ASCII,收錄了 21886 個符號,它分爲漢字區和圖形符號區。漢字區包括 21003 個字符。
因爲GBK自身並不是國家標準,只是曾由國家技術監督局標準化司、電子工業部科技與質量監督司公佈爲「技術規範指導性文件」。
而原始GB13000一直未被業界採用,因此2000年,國家推出了GB18030-2000,簡稱GB18030,技術上兼容GBK而非GB13000,取代了 GBK1.0,成了正式的國家標準。
該標準使用1,2,4個字節進行字符編碼
最近版本已經收錄了 70244 個漢字
規定PC平臺必須支持 GB18030 ,對嵌入式產品暫不做要求。所以有的手機、MP3只支持 GB2312。
在技術編碼方面上,演化順序爲:
ASCII ⇒ GB2312 ⇒ GBK ⇒ GB18030
Big5
Big5,又稱爲大五碼或五大碼,是使用繁體中文社區中最經常使用的字符編碼標準,Big5使用2個字節進行編碼,共收錄13,060個漢字。
在這個時候,字符集和字符編碼其實並無徹底區分開,直到UNICODE字符集的出現,字符集和字符編碼這兩個概念才區分的出來
UNICODE
每個國家都有本身的一套編碼方案,這些東西在本地使用並無問題,當時一旦出如今網絡,因爲不兼容,互相訪問的時候便會出現亂碼了,爲了解決這個問題,便產生了Unicode,
Unicode字符集(統一碼、萬國碼、單一碼、標準萬國碼),每一個數字表明惟一的至少在某種語言中使用的符號。(並非全部的數字都用上了,可是總數已經超過了65535,因此2個字節的數字是不夠用的。)被幾種語言共用的字符一般使用相同的數字來編碼,除非存在一個在理的語源學(etymological)理由使之不這樣作。
unicode定義了17個平面,每一個平面包括65536個碼位
平面0 (0000-FFFF)0-65536的碼位叫作基本多文本平面(BMP),其他的16個平面叫作輔助平面,
上述使用4字節的數字來表達每一個字母、符號,或者表意文字(ideograph),每一個數字表明惟一的至少在某種語言中使用的符號的編碼方案,稱爲UTF-32。UTF-32又稱UCS-4是一種將Unicode字符編碼的協定,對每一個字符都使用4字節。就空間而言,是很是沒有效率的。
這種方法有其優勢,最重要的一點就是能夠在常數時間內定位字符串裏的第N個字符,由於第N個字符從第4×Nth個字節開始。雖然每個碼位使用固定長定的字節看似方便,它並不如其它Unicode編碼使用得普遍。
儘管有Unicode字符很是多,可是實際上大多數人不會用到超過前65535個之外的字符。所以,就有了另一種Unicode編碼方式,叫作UTF-16,UTF-16將0–65535範圍內的字符編碼成2個字節,若是真的須要表達那些不多使用的"星芒層(astral plane)"內超過這65535範圍的Unicode字符,則須要使用一些特殊的技巧來實現。UTF-16編碼最明顯的優勢是它在空間效率上比UTF-32高兩倍,由於每一個字符只須要2個字節來存儲(除去65535範圍之外的),而不是UTF-32中的4個字節。
UTF-16的缺點是每一個字符都須要使用了2個字節來表示,所以並不能和ASCII兼容。
關於BOM
由於UTF-32和UTF-16使用4字節或字節進行編碼,所以傳輸的時候便會出現字節序的問題,例如「奎」的Unicode編碼是594E,「乙」的Unicode編碼是4E59。若是咱們收到UTF-16字節流「594E」,那麼這是「奎」仍是「乙」?這是UTF-16文件開頭的BOM就有做用了。爲了解決這個問題,多字節的Unicode編碼方式定義了一個"字節順序標記(Byte Order Mark)",它是一個特殊的非打印字符,你能夠把它包含在文檔的開頭來指示你所使用的字節順序,FEFF。若是收到一個以字節FF FE開頭的UTF-16編碼的文檔,你就能肯定它的字節順序是單向的(one way)的了;若是它以FE FF開頭,則能夠肯定字節順序反向了。
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼(定長碼),也是一種前綴碼。它使用一至四個字節進行字符編碼,能夠用來表示Unicode標準中的任何字符,且其編碼中的第一個字節和ASCII兼容,這使得原來處理ASCII字符的軟件無須或只須作少部份修改,便可繼續使用。所以,它逐漸成爲電子郵件,網頁和其餘儲存或傳送文字的應用中,優先採用的編碼。互聯網工程小組(IETF)要求全部互聯網都必須支持UTF-8編碼。utf8的編碼中也有bom,EF BB BF,不過因爲utf8沒有字節序的問題,因此這個能夠用了確認這個文件是用utf8編碼的
優勢
UTF-8是ASCII的一個超集。因此現存的ASCII文本不須要轉換,也是一個合法的UTF-8字符串,爲傳統的擴展ASCII字符集設計的軟件一般能夠不經修改或不多修改就能與UTF-8一塊兒使用。
缺點
由於每一個字符使用不一樣數量的字節編碼,因此尋找串中第N個字符是一個O(N)複雜度的操做 — 即,串越長,則須要更多的時間來定位特定的字符。同時,還須要位變換來把字符編碼成字節,把字節解碼成字符。
4、UTF-8字符編碼規則
若是一個字節的第一位爲0,那麼表明當前字符爲單字節字符,佔用一個字節的空間。0以後的全部部分(7個bit)表明在Unicode中的序號也就是codepoint。
若是一個字節以110開頭,那麼表明當前字符爲雙字節字符,佔用2個字節的空間。110以後的全部部分(5個bit)加上後一個字節的除10外的部分(6個bit)表明在Unicode中的序號。且第二個字節以10開頭
若是一個字節以1110開頭,那麼表明當前字符爲三字節字符,佔用3個字節的空間。1110以後的全部部分(4個bit)加上後兩個字節的除10外的部分(12個bit)表明在Unicode中的序號。且第2、第三個字節以10開頭
若是一個字節以11110開頭,那麼表明當前字符爲四字節字符,佔用4個字節的空間。11110以後的全部部分(3個bit)加上後兩個字節的除10外的部分(12個bit)表明在Unicode中的序號。且第2、第三個字節以10開頭
Byte1 | Byte2 | Byte3 | Byte4 |
0XXX XXXX | |||
110X XXXX | 10XX XXXX | ||
1110XXXX | 10XX XXXX | 10XX XXXX | |
1111 0XXX | 10XX XXXX | 10XX XXXX | 10XX XXXX |
例如
utf8編碼對應的十六進制 | utf8編碼對應的二進制 | 在Unicode字庫序號的二進制 | 在Unicode字庫序號的十六進制 | |
百 | e799 be | 11100111 10011001 10111110 | 0111 0110 0111 1110 | 767E |
度 | e5ba a6 | 11100101 10111010 10100110 | 0101 1110 1010 0110 | 5EA6 |
關於UTF8和UTF8 mb4
MySQL 5.5.3版本開始 MySQL中支持UTF8和UTF8mb4
UTF8mb4是UTF8的超集,MySQL 5.5.3以前的UTF8最多佔用3個字節,UTF8mb4是對UTF8的擴充,最多佔用4個字節
5、一個實例
咱們建立一個文本文件,內容以下,並把它保存成utf8的格式
而後咱們用UltraEdit打開後查看其16進制的內容
最前面的EF BB BF 表示這個文件是用utf8編碼的
由於UTF-8是ASCII的一個超集。因此現存的ASCII文本不須要轉換,也是一個合法的UTF-8字符串
對應1,2,3,4,5,6,7,8 ,\r\n原有的ASCII就是其合法的編碼
31 32 33 34 35 36 37 38是12345678對應的編碼
0D 0A是windows下的換行符\r\n
61 62 63 64 65 66 67是abcdefg對應的編碼
0D 0A是windows下的換行符\r\n
對於E7 99 BE E5 BA A6經過上面的介紹咱們能夠知道其對應着百度兩個字
utf8編碼對應的十六進制 | utf8編碼對應的二進制 | 在Unicode字庫序號的二進制 | 在Unicode字庫序號的十六進制 | |
百 | e799 be | 11100111 10011001 10111110 | 0111011001111110 | 767E |
度 | e5ba a6 | 11100101 10111010 10100110 | 0101111010100110 | 5EA6 |
6、參考文獻
http://cenalulu.github.io/linux/character-encoding/ 十分鐘搞清字符集和字符編碼
http://tgideas.qq.com/webplat/info/news_version3/804/808/811/m579/201307/218730.shtml 字符編碼的前世此生
http://blog.csdn.net/gqqnb/article/details/6266542 精確解釋Unicode
http://superuser.com/questions/537229/what-character-encodings-were-used-before-1963
https://zh.wikipedia.org/wiki/%E7%BC%96%E7%A0%81
http://www.crifan.com/files/doc/docbook/char_encoding/release/htmls/enc_eascii_iso8859.html