ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清
目錄
- ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清
- 前言
- ASCII
- Unicode
- UTF
- UTF-8
- UTF-8(without BOM)
- 怎樣區分UTF-8、UTF-16和UTF-32
ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清
前言
Github上下載了一份代碼打算學習,源工程是在linux上開發的,我在Windows上編譯通過不了,很多莫名奇妙的錯誤,最後發現源代碼文件是UTF-8(without BOM)編碼的,Notepad++修改編碼格式為UTF-8編譯通過。
- 為什麽Windows不認識UTF-8(without BOM)?
- 為什麽Linux認識UTF-8(without BOM)和UTF-8?
ASCII
畢竟在電子系混過四年,這個詞不陌生,用一個字節的低7位來表示128個英文字符(0xxxxxxx),可是地球上的文字又不是只有英文,光漢字就好幾萬個,所以每個國家和地區又做了一套符合自身情況的編碼規範,比如簡體中文編碼標準GB2312,使用兩個字節來表示一個漢字,可以表示65536個中文字符。但是如果每個國家都這麽搞那不就亂套了嘛,於是Unicode就應運而生了。
Unicode
Unicode是個符號集,與ASCII類似,只不過容量要大得多,可以理解成一張表,為世界上的每一個字符指定了一個惟一的二進制代碼,但是它並沒有規定這個二進制代碼如何存儲,於是乎UTF-8、UTF-8(without bom)、UTF-16、UTF-32應運而生。
UTF
UTF(Unicode Transformation Format)意為把Unicode字符轉換成某種格式,常見到的有:
UTF-8:使用1至4個字節為每個字符進行編碼,節省空間。
UTF-16:使2或4個字節為每個字符編碼,大多數漢字采用2個字節,少了生僻字使用4個字節,編碼單元為2個字節,所以存在字節序的問題,即大端還是小端。(不常用)
UTF-32:使4個字節為每個字符編碼,編碼單元為4個字節,所以存在字節序的問題,即大端還是小端。(不常用)
UTF-8
UTF-8是Unicode的實現方式之一,最大特點就是根據符號自動變化字節長度,即可變長編碼,編碼方式如下圖所示:
Unicode符號範圍 UTF-8編碼 (十六進制) (二進制) ———————————————————————————————————————————————————————————— 0000 0000 0000 007F | 0xxxxxxx 0000 0080 0000 07FF | 110xxxxx 10xxxxxx 0000 0800 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
對於單字節字符,第一位為0,後面7位位對應的Unicode碼,顯然UTF-8是兼容ASCII的,
對於n(n > 1)字節字符,第一個字節的前n位都設為1,第 n+1位設為0,後面的n-1個字節前兩位一律設為10,其余的字節(圖上的x)即為Unicode碼。
UTF-8(without BOM)
BOM(Byte Order Mark)字節順序標記,即可以用來標記是大端還是小端。在Unicode裏面定義了一個叫做
”ZERO WITH NO-BREAK SPACE“的不可見字符,對應的Unicode編碼是FEFF,有BOM的文件即文件開頭有”ZERO WITH NO-BREAK SPACE“不可見字符,反之則沒有。若是大端編碼,則文件開頭是FEFF,小端則是FFFE。BOM是為了配合UTF-16和UTF-32使用,因為它們編碼編碼單元包含多個字節,涉及字節序的問題。
UTF-8以單字節為編碼單元,不存在字節序的問題,但是可以使用BOM來表明所使用的編碼方式,字符”ZERO WITH NO-BREAK SPACE“在UTF-8中的編碼是EF BB BF,所以當解碼文件時發現開頭的單個字節是EF BB BF即說明是UTF-8編碼,Windows就是使用BOM來標記文本的編碼方式的。
怎樣區分UTF-8、UTF-16和UTF-32
打開文本時根據BOM來區分當前文件的編碼類型
BOM 編碼類型
——————————————————————————————————————
EF BB BF UTF-8
FE FF UTF-16(大端)
FF FE UTF-16(小端)
00 00 FE FF UTF-32(大端)
FF FE 00 00 UTF-32(小端)
ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清