之前,遇到汉字的utf8编码问题,掌握了处理方法,没做理论方面的深究。如今又遇到了缅甸语的编码问题,现在理清一下理论的问题。
1. utf8是变长编码,也就是一个字符(汉字或是其他文字)所占的字节数不同。
这个主要影响C++里面把一个句子分割成一串字符序列时,substring的参数,也就是一次取几个字节出来,如果字节长度没确定对,会把正确的字切开,导致乱码问题。
字节长度变化范围为:1-6。
ref:http://www.cnblogs.com/chenwenbiao/archive/2011/08/11/2134503.html
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。
如表:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
既然UTF8编码具有如此性质,那判断一个字符的字节长度,只需要判断第一个字节中1的个数,如果有0个1,那么占1个字节,其他有k个1,就占据k个字节。
这需要做位&运算。
1. 与128(10000000)运算,如果:是0,则是1字节字符,负责转到2。
2. 与32(00100000)运算,如果是0,那么是2字节字符,否则转到3。
3. 与16(00010000)运算,如果是0,那么是3字节字符,否则转到4。
4. 与8(00001000)运算,如果是0,那么是4字节字符,否则转到5。
5. 与4(00000100)运算,如果是0,那么是5字节字符,否则转到6。
6. 与2(00000010)运算,如果是0,那么是6字节字符,否则报错。
2. ASCII码是utf8的子集,也就是ASCII中的所有字符都是1字节的。
3. 有的地方写utf8是最长4字节,有的地方写最长6字节,java中修正的utf8编码也有区别。
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html