美文网首页iOS漫步者iosiOS开发笔记
iOS基础之字节处理(NSData,Byte,NSString转

iOS基础之字节处理(NSData,Byte,NSString转

作者: 留个念想给昨天 | 来源:发表于2018-03-15 17:31 被阅读329次
    漫步

    TCP传输协议:前2个子节为一个固定的字符,这里以0x809B为例,接着为4个子节(存放content的长度),然后为传输的内容content

    TCP传输协议

    以下内容都在Demo中,有兴趣可以下载

    一、 拼接方式1---使用Byte数组

    这里以传输一张图片为例

    1.1前期准备---获取一张图片的大小
        NSString  *path=  [[NSBundle mainBundle] pathForResource:@"ceshi" ofType:@"jpeg"];
        NSData* content = [NSData dataWithContentsOfFile:path];
        int value = (int)content.length;
    
    1.2 将长度value转换为4个字节
    Byte byteData[4] = {};
        
    byteData[0] =(Byte)((value & 0xFF000000)>>24);
        
    byteData[1] =(Byte)((value & 0x00FF0000)>>16);
        
    byteData[2] =(Byte)((value & 0x0000FF00)>>8);
        
    byteData[3] =(Byte)((value & 0x000000FF));
    //转换为4个字节
    
    1.3 拼接固定字符并转为NSData
    Byte byte[] = {0x80,0x9B,byteData[0],byteData[1],byteData[2],byteData[3]};
    NSData *temphead = [[NSData alloc]initWithBytes:byte length:6];
    
    1.4 拼接传输的数据(图片)
    //拼接content
    NSMutableData *m_data = [[NSMutableData alloc] init];
    [m_data appendData:temphead];
    [m_data appendData:content];
    

    二、 拼接方式2---使用十六进制转换

    2.1前期准备---获取一张图片的大小
        NSString  *path=  [[NSBundle mainBundle] pathForResource:@"ceshi" ofType:@"jpeg"];
        NSData* content = [NSData dataWithContentsOfFile:path];
        int value = (int)content.length;
    
    2.2 将长度value转换十六进制string
    //将长度转为十进制string
    NSString* decimalString = [NSString stringWithFormat:@"%d",value];
    //将十进制string转为十六进制并保证长度为8
    NSString* firstHex = [decimalString decimalToHexWithLength:8];//私有方法(见Demo)
    
    2.3 将十六进拼接固定字符并转为NSData
    //将十六进制拼接上809B
    NSString* hexString = [NSString stringWithFormat:@"809B%@",firstHex];
    //将十六进制转为NSData
    NSData* temphead = [hexString convertBytesStringToData];
    
    2.4 拼接传输的数据(图片)
    //拼接content
    NSMutableData *m_data = [[NSMutableData alloc] init];
    [m_data appendData:temphead];
    [m_data appendData:content];
    

    三、 解析数据

    这里是模拟服务器返回的数据
    因为发送给服务器内容的格式根服务器返回的内容的格式相同,所以这里我们直接解析我们发送给服务器的数据就可以

    3.1 获取头部数据
    NSData *head = [_receiveData subdataWithRange:NSMakeRange(0, 6)];//取得头部数据
    NSData *lengthData = [head subdataWithRange:NSMakeRange(2, 4)];//取得长度数据
    
    3.2 将4个字节的数据还原为content的长度
    1 将lengthData转为16进制数
    NSString* hexString = [lengthData convertDataToHexStr];
    2 将16进制数转为10进制
    NSInteger length = [[hexString hexToDecimal]integerValue];//得出content长度
    
    3.3 取出content的内容
    NSInteger complateDataLength = length + 6;//算出一个包完整的长度(内容长度+头长度)
    if (_receiveData.length >= complateDataLength)//如果缓存中数据够一个整包的长度
    {
        //这个data即为我们传出去的数据
        NSData *data = [_receiveData subdataWithRange:NSMakeRange(6, length)];//截取一个包的长度(处理粘包)
        //显示到程序上
        [self.resultImage setImage:[UIImage imageWithData:data]];
    }
    
    image.png image.png

    四、 进制、Byte、Byte数组、NSData的相互转换(参考Demo)

    #import "NSString+SwitchData.h"
    
    @implementation NSString (SwitchData)
    /**
     带子节的string转为NSData
     
     @return NSData类型
     */
    -(NSData*) convertBytesStringToData {
        NSMutableData* data = [NSMutableData data];
        int idx;
        for (idx = 0; idx+2 <= self.length; idx+=2) {
            NSRange range = NSMakeRange(idx, 2);
            NSString* hexStr = [self substringWithRange:range];
            NSScanner* scanner = [NSScanner scannerWithString:hexStr];
            unsigned int intValue;
            [scanner scanHexInt:&intValue];
            [data appendBytes:&intValue length:1];
        }
        return data;
    }
    /**
     十进制转十六进制
     
     @return 十六进制字符串
     */
    - (NSString *)decimalToHex {
        long long int tmpid = [self intValue];
        NSString *nLetterValue;
        NSString *str = @"";
        long long int ttmpig;
        for (int i = 0; i < 9; i++) {
            ttmpig = tmpid % 16;
            tmpid = tmpid / 16;
            switch (ttmpig) {
                case 10:
                    nLetterValue = @"A";
                    break;
                case 11:
                    nLetterValue = @"B";
                    break;
                case 12:
                    nLetterValue = @"C";
                    break;
                case 13:
                    nLetterValue = @"D";
                    break;
                case 14:
                    nLetterValue = @"E";
                    break;
                case 15:
                    nLetterValue = @"F";
                    break;
                default:
                    nLetterValue = [[NSString alloc]initWithFormat:@"%lli", ttmpig];
            }
            str = [nLetterValue stringByAppendingString:str];
            if (tmpid == 0) {
                break;
            }
        }
        return str;
    }
    /**
     十进制转十六进制
     length   总长度,不足补0
     @return 十六进制字符串
     */
    - (NSString *)decimalToHexWithLength:(NSUInteger)length{
        NSString* subString = [self decimalToHex];
        NSUInteger moreL = length - subString.length;
        if (moreL>0) {
            for (int i = 0; i<moreL; i++) {
                subString = [NSString stringWithFormat:@"0%@",subString];
            }
        }
        return subString;
    }
    /**
     十六进制转十进制
     
     @return 十进制字符串
     */
    - (NSString *)hexToDecimal {
        return [NSString stringWithFormat:@"%lu",strtoul([self UTF8String],0,16)];
    }
    /*
     二进制转十进制
     
     @return 十进制字符串
     */
    - (NSString *)binaryToDecimal {
        int ll = 0 ;
        int  temp = 0 ;
        for (int i = 0; i < self.length; i ++) {
            temp = [[self substringWithRange:NSMakeRange(i, 1)] intValue];
            temp = temp * powf(2, self.length - i - 1);
            ll += temp;
        }
        NSString * result = [NSString stringWithFormat:@"%d",ll];
        return result;
    }
    /**
     十进制转二进制
     
     @return 二进制字符串
     */
    - (NSString *)decimalToBinary {
        NSInteger num = [self integerValue];
        NSInteger remainder = 0;      //余数
        NSInteger divisor = 0;        //除数
        NSString * prepare = @"";
        
        while (true) {
            remainder = num%2;
            divisor = num/2;
            num = divisor;
            prepare = [prepare stringByAppendingFormat:@"%d",(int)remainder];
            
            if (divisor == 0) {
                break;
            }
        }
        
        NSString * result = @"";
        for (NSInteger i = prepare.length - 1; i >= 0; i --) {
            result = [result stringByAppendingFormat:@"%@",
                      [prepare substringWithRange:NSMakeRange(i , 1)]];
        }
        return [NSString stringWithFormat:@"%08d",[result intValue]];
    }
    @end
    
    @implementation NSData (SwitchData)
    
    /**
     NSData 转  十六进制string
     
     @return NSString类型的十六进制string
     */
    - (NSString *)convertDataToHexStr{
        if (!self || [self length] == 0) {
            return @"";
        }
        NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[self length]];
        
        [self enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
            unsigned char *dataBytes = (unsigned char*)bytes;
            for (NSInteger i = 0; i < byteRange.length; i++) {
                NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
                if ([hexStr length] == 2) {
                    [string appendString:hexStr];
                } else {
                    [string appendFormat:@"0%@", hexStr];
                }
            }
        }];
        
        return string;
    }
    
    /**
     NSData 转 NSString
     
     @return NSString类型的字符串
     */
    - (NSString *)dataToString {
        Byte *bytes = (Byte *)[self bytes];
        NSMutableString *string = [[NSMutableString alloc] init];
        for(int i = 0; i< [self length]; i++) {
            if (i == 0) {
                [string appendString:[NSString stringWithFormat:@"%hhu",bytes[i]]];
            }else {
                [string appendString:[NSString stringWithFormat:@",%hhu",bytes[i]]];
            }
        }
        return string;
    }
    @end
    
    

    写在最后:
    希望这篇文章对您有帮助。当然如果您发现有可以优化的地方,希望您能慷慨的提出来。最后祝您工作愉快!

    相关文章

      网友评论

      • 3b73ac1e6515:你好,当需要转成NSData的数据达不到特定的字节,怎么进行补位呢
        3b73ac1e6515:@采釆一叶秋的iOS漫步
        一个字节数字的每个字节累加和,用1个字节表示,丢弃溢出的高字节,请问这个怎么计算
        留个念想给昨天:可以参考文中
        1.2 将长度value转换为4个字节

        Byte byteData[4] = {};

        byteData[0] =(Byte)((value & 0xFF000000)>>24);

        byteData[1] =(Byte)((value & 0x00FF0000)>>16);

        byteData[2] =(Byte)((value & 0x0000FF00)>>8);

        byteData[3] =(Byte)((value & 0x000000FF));

      本文标题:iOS基础之字节处理(NSData,Byte,NSString转

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