在编程当中常常出现乱码的问题,而由此通常会引起不少惨剧,如读文件不成功、用户名显示乱码等,因此端午节抽了一小点时间好好看了一下编码问题,以备遗忘。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同样,在各个系统的表现形式不同,多加注意就是了。编程