解決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];
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章