UTF-8、GB2312、GBK編碼格式詳解
UTF-8
使用1~4個字節對每個字符進行編碼
- 128個ASCII字符字需要一個字節編碼
- 帶有附加符號的拉丁文、希臘文、西里爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則需要兩個字節進行編碼
- 其他基本多文種平面中的字符(這包含了大部分常用字,如大部分的漢字)使用三個字節編碼
- 其他極少使用的Unicode輔助平面的字符使用四至六字節編碼
GB2312,GBK編碼
- GB2312:一個小於127的字符意義與原來的相同,但是兩個大於127的字符連在一起時,就表示一個漢字;前面的一個字節(高字節)從0xA1用到0xF7,后面一個字節(低字節)從0xA1到0xFE;其中,在ASCII里本來就有個的數字、標點、字母都統統重新編了兩個字節長的編碼,這就是常說的“全角”字符,而原來在127號以下的那些就叫“半角”字符
- GBK:不再要求低字節一定是127號之后的編碼,只要第一個字節是大於127就固定表示這是一個漢字的開始,不管后面跟的是不是擴展字符集里的內容
例子
以下例子使用nodeJS來編寫,具體代碼和相關測試文件可見Github。
聯通
參考文章中給出了一個比較經典的例子,在這里詳細研究一下。
------------------非UTF-8編碼保存的[聯通]數據------------------
<Buffer c1 aa cd a8>
------------------UTF-8編碼保存的[聯通]數據-帶BOM------------------
<Buffer ef bb bf e8 81 94 e9 80 9a>
------------------UTF-8編碼保存的[聯通]數據-不帶BOM------------------
<Buffer e8 81 94 e9 80 9a>
- 可以清楚看到window默認編碼格式GB2312和UTF-8編碼格式的區別:GB2312使用兩個字節對漢字進行編碼,而UTF-8使用三個字節對漢字進行編碼
- UTF-8帶BOM的編碼格式和不帶BOM的編碼格式之間的區別:BOM格式會在頭部添加ef bb bf三個字節作為標志
中英文混合
這個主要是看各個編碼格式對於ASCII編碼的兼容情況
------------------非UTF-8編碼保存的[hello 你好]數據------------------
<Buffer 68 65 6c 6c 6f 20 c4 e3 ba c3>
------------------UTF-8編碼保存的[hello 你好]數據-帶BOM------------------
<Buffer ef bb bf 68 65 6c 6c 6f 20 e4 bd a0 e5 a5 bd>
------------------UTF-8編碼保存的[hello 你好]數據-不帶BOM------------------
<Buffer 68 65 6c 6c 6f 20 e4 bd a0 e5 a5 bd>
- 可以看出,兩種編碼格式對ASCII都能兼容,前面的[hello ]兩者的編碼是一致的,而中文字符編碼則是根據各自不同的編碼規則來得
- 如果只有ASCII字符,則兩種編碼是等價的,GB2312方式打開UTF-8編碼的文件不會出現亂碼,反之亦然
編碼格式區分
- 帶有BOM信息的,可以根據BOM信息進行區分:前三個字節為:ef bb bf的是UTF-8編碼格式
- 沒有BOM信息的,則需要按字節進行區分:如果UTF-8中有中文字符,則可以根據1110XXXX 10XXXXXX 10XXXXXX這種格式來進行區分;如果UTF-8中有其他兩個字節編碼的字符則較難進行區分,希望有人可以給指點