在編程當中常常出現亂碼的問題,而由此通常會引起不少慘劇,如讀文件不成功、用戶名顯示亂碼等,因此端午節抽了一小點時間好好看了一下編碼問題,以備遺忘。html
首先是中文編碼,除了臺灣和香港經常使用的BIG5,國內大概都用的是gb2312,這個能夠從各大門戶的首頁源碼中找到一些線索。還有一種叫gbk,這是微軟對gb2312的拓展。主要因爲gb2312只能表示6763個簡體漢字,682個符號,具體可見字符區別。java
而後是編程當中常見的utf編碼,相信不少程序員都暈。好比咱們最近在作android的NDK編程時,就發現因爲寫基礎庫的人沒徹底弄懂編碼,致使中英文轉碼錯誤,從而引起一些列奇葩問題。因爲char、wchar_t在語言層面、系統層面都沒有統一的規範,如char在JAVA和C++中的字節數就不同、wchar_t在win32和linux中的字節數也不同,因此在網絡傳輸時通常都會轉換數據爲utf編碼。linux
多字符(一個字符用多個字節表示,即對應utf八、gb2312編碼)與wchar_t(可能2個字節也可能4個字節,即對應utf編碼中utf16和utf32)之間的轉換主要是mbstowcs,wcstombs,MultiByteToWideChar,MultiByteToWideChar
,前者是C運行時庫,後者是windows的api,在windows下二者等效,前提是前者須要設置locael,不然中文轉換會出問題。具體可見轉換API。在android編程當中若是想在NDK使用轉碼,能夠附加開源庫ICU進行編譯或者加載libicuuc.so,使用JNI回調也是一種方法,但顯得很蠢。ios自帶ICU,不過貌似私有,沒作過調研,熟悉的同窗能夠補充.android
utf8是變長編碼,通常常見的字符能夠在3個字節內表示,最多4個字節,由於4個字節能夠用21(18+3)位來表示字符串,基本能夠覆蓋人類的任何語言了。具體編碼細節網上能夠查到不少資料,編碼規則仍是比較簡單的。ios
utf16其實也是變長編碼,每個語言字都對應一個碼位,一個抽象碼位能夠用1或者2個碼元(code point)來表示,編碼空間爲U+0000到U+10FFFF,具體可參考utf16介紹。其中BMP主要對應於常見的語言字,這個空間內的字符能夠用1個碼元來表示,但只能表示63488個字符,沒法覆蓋人類全部語言。對於輔助平面內的碼位,用BMP中2048個保留的碼位拼成2個碼元來表示。(雖然windows內核能夠正確的處理BMP以外的字符,但windows的api只能處理BMP內的字符,緣由就在於wchar_t的字節固定位爲16位。java在JDK1.5以後對字符進行了增補,具體可見java編碼,好奇的同窗能夠試試打印char值爲0xD800到0xDFFF之間的值)。程序員
另一點是BOM,這個在較先進的編輯器中都會讓用戶選擇,主要是來標示文本是不是大小端表示的。跟CRLF同樣,在各個系統的表現形式不同,多加註意就是了。編程