`
wjjxf
  • 浏览: 238108 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解决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];
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics