iOS/MacOS中二进制数据的处理

版权声明:本文为博主原创文章,转载时必须注明原文链接 https://blog.csdn.net/zzl819954692/article/details/83619715

iOS/MacOS中二进制数据的处理

何为大小端模式?

在处理二进制数据的时候,首先要注意区分使用大端模式(Big-endian)还是小端模式(Little-endian),何为大小端模式呢?

大端模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;

小端模式:是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。

为何有大小端之分?

在计算机系统中,我们以字节为单位,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(根据编译器决定),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。即数据的低位保存在内存的高地址中,而数据高位保存在内存的低地址中。小端模式刚好相反,将0x22放在低地址0x0010中,0x11放在高地址0x0011中,即数据低位保存在内存的低位地址中,数据的高位保存在内存的高位中。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

判断大小端

//判断设备是否是小端模式
- (int) isLittleEndian
{
    int i = 0x12345678;
    char *c = &i;
    return ((c[0] == 0x78) && (c[1] == 0x56) && (c[2] == 0x34) && (c[3] == 0x12));
}

NSString转Data

/** NSString转NSData */
- (NSData *)dataWithString:(NSString *)string {
    const char *constStr = [string UTF8String];
    return [NSData dataWithBytes:constStr length:strlen(constStr)];
}

Data转NSString

NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

int转Data

int i = 1;
NSData *data = [NSData dataWithBytes:&i length:sizeof(i)];

Data转int

int y;
[data getBytes:&y length:sizeof(y)];

有时我们需要将int类型转为bytes以方便二进制数据的处理,例如替换二进制指定位的数据时需要使用bytes,因此,需要将int转为bytes

int转bytes

//int类型转bytes, 结果为大端模式,默认生成4位
- (void)intToBigBytes:(int)intValue bytes:(Byte *)buffer {
    for (int i = 0; i < 4; i++) {
        buffer[i] = (Byte)(intValue >> (24-i*8));
    }
}

//int类型转bytes, 结果为小端模式,默认生成4位
- (void)intToLittleBytes:(int)intValue bytes:(Byte *)buffer {
    for (int i = 3; i >= 0; i--) {
        buffer[i] = (Byte)(intValue >> (24-i*8));
    }
}

bytes转int

//将小端模式下的bytes转换为int
-(int) lBytesToInt:(Byte*) byte length:(NSUInteger)length {
    if (byte == NULL) {
        return 0;
    }
    int height = 0;
    for (int i = 0; i < length; i++) {
        if (byte[length-i] >= 0) {
            height = height + byte[length-i];
        } else {
            height = height + 256 + byte[length-i];
        }
        height = height * 256;
    }
    if (byte[0] >= 0) {
        height = height + byte[0];
    } else {
        height = height + 256 + byte[0];
    }
    return height;
}

//将大端模式下的bytes转换为int
- (int)heightBytesToInt:(Byte *)byte length:(NSUInteger)length {
    int height = 0;
    for (int i = 0; i < length; i++) {
        if (byte[i] >= 0) {
            height = height + byte[i];
        } else {
            height = height +256 + byte[i];
        }
        height = height * 256;
        if (length >= 3) {
            if (byte[3] >= 0) {
                height = height + byte[3];
            } else {
                height = height + 256 + byte[3];
            }
        }
    }
    return height;
}

其余数据类型与NSData之间的转换在此不再一一列出,以上部分鉴于个人在项目中使用到,总结以便掌握。

猜你喜欢

转载自blog.csdn.net/zzl819954692/article/details/83619715