解决NSData中非法utf-8字节的问题

当用nsdata,按照utf8编码来初始化nsstring时,如果nsdata出现了非法utf-8编码,nsstring就回返回空,这不是我所期望的,对于非法的字节,可以用A代替。
按照utf8格式标准,
U+00000000 - U+0000007F: 0 xxxxxxx 0x - 7x
U+00000080 - U+000007FF: 110 xxxxx 10 xxxxxx Cx 8x - Dx Bx
U+00000800 - U+0000FFFF: 1110 xxxx 10 xxxxxx 10 xxxxxx Ex 8x 8x - Ex Bx Bx
U+00010000 - U+001FFFFF: 11110 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx F0 8x 8x 8x - F7 Bx Bx Bx 很少用
U+00200000 - U+03FFFFFF: 111110 xx 10 xxxxxx 10 xxxxxx 10 xxxxxx 10 xxxxxx F8 8x 8x 8x 8x - FB Bx Bx Bx Bx
U+04000000 - U+7FFFFFFF: 1111110 x 10 xxxxxx 10 xxxxxx 10 xxxxxx 10 xxxxxx 10 xxxxxx FC 8x 8x 8x 8x 8x - FD Bx Bx Bx Bx Bx
如果一个字节小于0x80,那么他就是一个字符,如果大于C0小于E0,表示有2个字节是utf8,第一个是110开头的,第二个是10开头的,如果大于E0小于F0,表示3个字节是utf8,第一个是1110开头的,第二个是10开头的,第三个是10开头的,如果不是表明非法,将非法的字节设置为A,即可。
如何判断一个字节是否是110开头的或者是1110开头的呢?用b & 0xE0 == 0xC0,类推,判断是否是1110开头的,b&0xF0 == 0xE0。
经过这一的转化,nsstring就能初始化了。
代码如下:


//将nsdata中的非法字符替换为A 0x41
char aa[] = {'A','A','A','A','A','A'};
NSMutableData *md = [NSMutableData dataWithData:data];
int loc = 0;
while(loc < [md length]){
char buffer;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
//printf("%d", buffer&0x80);
if((buffer & 0x80) == 0){
loc++;
continue;
}else if((buffer & 0xE0) == 0xC0){
loc++;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0xC0) == 0x80){
loc++;
continue;
}
loc--;
//非法字符,将这1个字符替换为AA
[md replaceBytesInRange:NSMakeRange(loc , 1) withBytes:aa length:1];
loc++;
continue;

}else if((buffer & 0xF0) == 0xE0){
loc++;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0xC0) == 0x80){
loc++;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0xC0) == 0x80){
loc++;
continue;
}
loc--;
}
loc--;
//非法字符,将这个字符替换为A
[md replaceBytesInRange:NSMakeRange(loc , 1) withBytes:aa length:1];
loc++;
continue;

}else{
[md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
loc++;
continue;
}
}
//NSLog(@" new data =>%@", md);
str = [[[NSString alloc] initWithData:md encoding:NSUTF8StringEncoding] autorelease];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值