utf8的规则比较简单:
- 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符;
- 如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
- 如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;
- 如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
- 如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示;
通过二进制表示如下:
0xxxxxxx (一位的情况,为ASCII)
110xxxxx 10xxxxxx (110开头,代表两位)
1110xxxx 10xxxxxx 10xxxxxx (1110开头代表三位)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (11110开头代表四位)
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (111110开头,代表五位)
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (1111110开头,代表六位)
符合以上规则的,就代表为符合utf8编码规则,否则为不符合
代码实现如下:
bool isUTF8(char* rawtext)
{
int score = ;
int i, rawtextlen = ;
int goodbytes = , asciibytes = ; rawtextlen = strlen(rawtext);
for (i = ; i < rawtextlen; i++)
{
if ((rawtext[i] & 0x7F) == rawtext[i])
{
//最高位是0的ASCII字符
//一位编码的情况
asciibytes++;
}
else if (- <= rawtext[i] && rawtext[i] <= -
//两位编码的情况,第一位11000000--11011111
//后一位跟10000000--10111111
&&i + < rawtextlen
&& - <= rawtext[i + ] && rawtext[i + ] <= -)
{
goodbytes += ;
i++;
}
else if (- <= rawtext[i]&& rawtext[i] <= -
//三位编码的情况,第一位11100000--11101111
//后两位跟10000000--10111111
&&i + < rawtextlen
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -)
{
goodbytes += ;
i += ;
}
else if(- <= rawtext[i]&& rawtext[i] <= -
//四位编码的情况,第一位11110000--11110111
//后三位跟10000000--10111111
&&i + < rawtextlen
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -) {
goodbytes += ;
i += ;
}
else if(- <= rawtext[i]&& rawtext[i] <= -
//五位编码的情况,第一位11111000--11111011
//后四位跟10000000--10111111
&&i + < rawtextlen
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -)
{
goodbytes += ;
i += ;
}
else if(- <= rawtext[i]&& rawtext[i] <= -
//六位编码的情况,第一位11111100--11111101
//后五位跟10000000--10111111
&&i + < rawtextlen
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -
&& - <= rawtext[i + ] && rawtext[i + ] <= -)
{
goodbytes += ;
i += ;
}
}
if (asciibytes == rawtextlen)
{
return true;
}
score = * goodbytes / (rawtextlen - asciibytes);
//如果匹配率达到98%以上,则成功
//允许一部分脏数据
if (score > )
{
return true;
}
else if (score > && goodbytes > )
{
return true;
}
else
{
return false;
}
}