Unicode,UTF-8,GB2312编码的识别
在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。
UCS 建议在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;
如果收到FFFE,就表明这个字节流是Little-Endian的。
因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。
字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。
所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Unicode:FF FE
Unicode big_endian:EF FF
UTF-8: EF BB BF
GB2312是高位在前,Big_endian
/*
* 检查一个字符是否UTF8标志字符。
*
* 0xxxxxxx
* 110yyyxx 10xxxxxx
* 1110yyyy 10yyyyxx 10xxxxxx
* 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
*/
bool IsUtf8StartChar(char c)
{
if((c & 0x80) == 0)
return true;
if((c & 0xE0) == 0xC0)
return true;
if((c & 0xF0) == 0xE0)
return true;
if((c & 0xF8) == 0xF0)
return true;
if((c & 0xFC) == 0xF8)
return true;
if((c & 0xFE) == 0xFC)
return true;
return false;
#if 0
unsigned char d = (unsigned char)c;
if( (d&(0x01<<7))==0 ) //0xxxxxxx
return true;
if( (d&(0x01<<7)) && (d&(0x01<<6)) && (d&(0x01<<5))==0 )
return true;
if( (d&(0x01<<7)) && (d&(0x01<<6)) && (d&(0x01<<5)) && (d&(0x01<<4))==0 )
return true;
if( (d&(0x01<<7)) && (d&(0x01<<6)) && (d&(0x01<<5)) && (d&(0x01<<4)) && (d&(0x01<<3))==0 )
return true;
if( (d&(0x01<<7)) && (d&(0x01<<6)) && (d&(0x01<<5)) && (d&(0x01<<4)) && (d&(0x01<<3)) && (d&(0x01<<2))==0 )
return true;
if( (d&(0x01<<7)) && (d&(0x01<<6)) && (d&(0x01<<5)) && (d&(0x01<<4)) && (d&(0x01<<3)) && (d&(0x01<<2)) && (d&(0x01<<1))==0 )
return true;
return false;
#endif
}