1、ASCII
阿斯卡码,不知道这么读对不对,使用一个字节,8位进行表示,最高位以前不适用,即最大表示127位,对于我们键盘上的数字,英文足够了,对于英语国家够用了,一个对应关系如下:
0- NUL,1- SOH。。48-0,49-1,65-A。。。
如果我们如下赋值:
char szTest1[] = "A";
char szTest2[] = "1";
我们就会看到szTest1是65,szTest2是49,如果都是英文也是一件很美好的事情,大家不用考虑编码格式了,后面有些特殊符号如@等也有数字对应,总之就是一个1~127的对应表格即可。
2、ANSI
阿斯卡码根本无法表示中文,日文这些文字,ANSI就是各国玩各国的了,中国对应的是GB2312,日本的就是JIT标准。GB2312里面只有6763个汉字,682个符号,就是0代表一个汉字,1代表另外一个,总共有6763个了。而微软有一套GBK,又是在GB2312基础上又增加了很多汉字。实际上此处有个错误,0不会表示一个汉字,为了与ASCII兼容,0必须与ASCII一致,GB2312里面用127以后的进行表示各个汉字,0~127与ACSII保持一致。字节数也进行了扩展,一个字节根本表示不了六千多个中文呀,就用了两个字节,范围从0~65535了(实际上汉字编码范围是0xA1A1 - 0xFEFE),足够了。由于ANSI是各国自己玩的,所以位数也不确定的,有些国家可能两位都不够用。
它有个致命的缺点,同时显示中文,英文,没问题,如果要同时显示中文,日文那就完蛋了。同样是0XAA,该到中文对应的表里面去找呢,还是到日文的里面去找呢?
3、Unicode
终于出现了一个解决办法,把全世界所有的字符都拿过来唯一编码,统一维护。每个值代表为一个的字符,比如0XAA代表一个汉字,0XAB代表一个日文。
一般Unicode用3个字节表示就够了,3个字节即24位,范围是0~16777215。绝对够用了。考虑到4对齐,还是使用了3个字节来表示一个字符。那么Unicode是如何实现的呢?不可能一个一个真的这么对应下去吧,那样查找效率低,而且方法也太挫了点。
实现方案
3.1 、Utf-8
以8位为一个单位来标示字符,即判断这个字符在Unicode的哪个范围内,如a的Unicode编码是97,需要一个字节就够了,则使用一个字节存储,使用一个字节的模板表示,如”汉“的Unicode编码是0x6C49,大于两个字节的值,小于三个字节的值,则使用三个字节模板来表示。这样节省了存储空间。所以看到一个汉字,转成Utf-8后,会发现字节大小是3了。
一个字节模板:0xxxxxxx
两个字节模板:110xxxxx 10xxxxxx 。如果汉字就使用这个模板,对x进行补充填写。
三个字节模板:1110xxxx 10xxxxxx 10xxxxxx
四个字节模板:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
3.2、Utf-16
最优方案,也是最复杂的。大多数都是通过Utf-16的编码来实现Unicode的。以16位为一个单位,99%的都会表示完成,剩余1%可能会扩展到用32位来表示了。即如果字符在Unicode中的值表示<0x10000,那么UTF-16编码就是16位无符号整数。很多地方直接说Unicode编码,往往就是指Utf-16这种类型。
3.3、Utf-32
4个字节直接表示一一对应关系,看着比较简单,但是真的太多冗余了。