一般NSData轉NSString的時候我們直接使用官方API,使用默認的解碼樣式就可以了
//栗子??
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
但是當需要解碼的Data內存在 ? □ ? 這些符號的時候就會解碼失敗,通常這種特殊的符號直接替換為空即可,但是如果是使用的數據,那么就會出現問題,付一下解決方案:
- (NSData *)UTF8Data:(NSData *)tData{
//保存結果
NSMutableData *resData = [[NSMutableData alloc] initWithCapacity:tData.length];
//無效編碼替代符號(常見 ? □ ?)
NSData *replacement = [@"?" dataUsingEncoding:NSUTF8StringEncoding];
uint64_t index = 0;
const uint8_t *bytes = tData.bytes;
while (index < tData.length)
{
uint8_t len = 0;
uint8_t header = bytes[index];
//單字節
if ((header&0x80) == 0)
{
len = 1;
}
//2字節(并且不能為C0,C1)
else if ((header&0xE0) == 0xC0)
{
if (header != 0xC0 && header != 0xC1)
{
len = 2;
}
}
//3字節
else if((header&0xF0) == 0xE0)
{
len = 3;
}
//4字節(并且不能為F5,F6,F7)
else if ((header&0xF8) == 0xF0)
{
if (header != 0xF5 && header != 0xF6 && header != 0xF7)
{
len = 4;
}
}
//無法識別
if (len == 0)
{
[resData appendData:replacement];
index++;
continue;
}
//檢測有效的數據長度(后面還有多少個10xxxxxx這樣的字節)
uint8_t validLen = 1;
while (validLen < len && index+validLen < tData.length)
{
if ((bytes[index+validLen] & 0xC0) != 0x80)
break;
validLen++;
}
//有效字節等于編碼要求的字節數表示合法,否則不合法
if (validLen == len)
{
[resData appendBytes:bytes+index length:len];
}else
{
[resData appendData:replacement];
}
//移動下標
index += validLen;
}
return resData;
}
使用:
// data: 原始數據源
NSData * tData = [self UTF8Data: data];//存在不規則的數據 ? 強制還原這個符號
NSString *str = [[NSString alloc] initWithData: tData encoding:NSUTF8StringEncoding];
原文轉自:
https://my.oschina.net/u/1763048/blog/736460
稍微做了修復,原地址內攜帶了私有變量,給予正確的賦值.