在做项目的时候,发现一个人,在头像,昵称,评论都为空。体验非常不好,下面的人都在评论见到鬼了。原因如下:
1.这个人的头像为透明图片。
2.这个人的昵称为" ",应该是注册时候传入了空白字符。注意这里其实也存在传入不可见utf-8字符的情况
3.这个人的评论,是不可见字符。
3.1 这个字符真的是utf-8编码的,只是不可见。https://graphemica.com/unicode/characters 这个里面看不到的就都是电脑上
不可见的字符。注意,手机侧和电脑侧还不一样,手机侧可能会有更多的字符不可见。当时他传入的就是https://graphemica.com/%E1%85%A0和https://graphemica.com/%E3%85%A4字符。
3.2 其实在做评论的时候,还需要验证字符格式是否为utf-8.不符合utf-8的字符应该直接返回错误
附相关代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
bool FilterUtf8(unsigned char * string,int length){
if(!string)
{
return false;
}
unsigned char * bytes = string;
unsigned char * end = bytes+length;
//10xxxxxx 应该出现个数
int count_s = 0;
//10xxxxxx 剩余个数
int minus_s = 0;
while(bytes != end)
{
if(bytes[0] > 0xF7)
{
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}
minus_s = 0;
count_s = 0;
bytes[0] = '#';
bytes+=1;
continue;
}
if(bytes[0] <= 0x7F)
{
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}
minus_s = 0;
count_s = 0;
//过滤掉不可见字符
if((bytes[0] == 0x09 || bytes[0] == 0x0A || bytes[0] == 0x0D ||
(0x20 <= bytes[0] && bytes[0] <= 0x7E)))
{
;
}else
{
bytes[0] = '#';
}
bytes+=1;
continue;
}
if((bytes[0] & 0xF8) == 0xF0)
{
// 1111 0XXX
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}
count_s = 3;
minus_s = 3;
bytes+=1;
continue;
}
if((bytes[0] & 0xF0) == 0xE0)
{
// 1110 XXXX
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}
count_s = 2;
minus_s = 2;
bytes+=1;
continue;
}
if((bytes[0] & 0xE0) == 0xC0)
{
// 110X XXXX
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}
count_s = 1;
minus_s = 1;
bytes+=1;
continue;
}
if((bytes[0] & 0xC0) == 0x80)
{
// 10XX XXXX
if(minus_s)
{
--minus_s;
}else
{
bytes[0] = '#';
}
bytes+=1;
continue;
}
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}else
{
bytes[0] = '#';
}
minus_s = 0;
count_s = 0;
bytes+=1;
continue;
}
if(minus_s)
{
int m = count_s-minus_s+1;
memset((void*)(bytes-m),'#',m);
}
return true;
}
int main(int argc, char **argv) {
// unsigned char * x1 = new unsigned char[3];
// x[0]=0xE1;
// x[1]='\0';
string x1="ᅠᅠᅠㅤ";
// x1[0] = 0xE1;
// x1[1] = 0x85;
// x1[2] = 0xA1;
FilterUtf8(const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(x1.c_str())),3);
cout<<x1<<endl;
return 0;
}
上面的代码是判断是否为正常utf-8编码的代码,非正常的字符会被替换为#。
相关需求以后需要注意