美文网首页
NSData转NSString失败的处理

NSData转NSString失败的处理

作者: 幸福的尾巴__ | 来源:发表于2020-10-12 17:42 被阅读0次

    一般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
    稍微做了修复,原地址内携带了私有变量,给予正确的赋值.

    相关文章

      网友评论

          本文标题:NSData转NSString失败的处理

          本文链接:https://www.haomeiwen.com/subject/zalppktx.html