工作中遇到大小端数据存储格式

大小端数据存储

概念:

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

新的需求:

这是移动端日志数据传给服务器的格式:

{“flag”:16,“item”:{“group”:“xxxxxx”,“mirror”:1,“items”:[{“flag”:1,“key”:“log”,“datas”:[“data:application/octet-stream;base64,xxxxxxx”]}]}}

[total_len(4b)][format(4b)][type_len(1b)][type_padding_len(1b)][data_padding_len(1b)] [reserved(1b)][type][data]。
format为格式,固定长度,为4个字节。type_len一种type的实际长度。Type_padding_len为type补位个数。data_padding _len为data补位个数。total_len为整个数据的长度,占4个字节,大端字节序存储。type为存储数据类型,data为存储数据,都建议4字节对齐,末位补/0。

疑惑:

之前不知道大小端数据是咋回事,一头雾水。问了安卓同事才勉强明白,我们先了解下Byte,Object-C里面其实是沿用C++的,下面是Byte的定义:
*********************************************************************************/
//Byte是UInt8的别名
typedef UInt8                           Byte;
typedef SInt8                           SignedByte;
typedef wide *                          WidePtr;
typedef UnsignedWide *                  UnsignedWidePtr;
typedef Float80                         extended80;
typedef Float96                         extended96;
typedef SInt8                           VHSelect;
/*********************************************************************************
/********************************************************************************

    Base integer types for all target OS's and CPU's
    
        UInt8            8-bit unsigned integer 
        SInt8            8-bit signed integer
        UInt16          16-bit unsigned integer 
        SInt16          16-bit signed integer           
        UInt32          32-bit unsigned integer 
        SInt32          32-bit signed integer   
        UInt64          64-bit unsigned integer 
        SInt64          64-bit signed integer   

*********************************************************************************/
//UInt8是unsigned char 别名
typedef unsigned char                   UInt8;
typedef signed char                     SInt8;
typedef unsigned short                  UInt16;
typedef signed short                    SInt16;

#if __LP64__
typedef unsigned int                    UInt32;
typedef signed int                      SInt32;
#else
typedef unsigned long                   UInt32;
typedef signed long                     SInt32;
#endif

下面是iOS的实现:

- (NSString *)logByteFill:(NSString *)data format:(NSString *)format type:(NSString *)type {
    if (data == NULL) {
        return @"";
    }
    int type_padding_len = 0;
    int type_len = (int)type.length;//type的实际长度,都是英文,一个英文单词一个字节
            
    int temp = 4 - type_len % 4;
    if (temp != 4) {
        type_padding_len = temp;
    }
    //JSON字符串的字节长度
    int data_len = (int)[data lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    
    int data_padding_len = 4 - data_len % 4;
    
    if (data_padding_len != 4) {
        data_len = data_len + data_padding_len;
    } else {
        data_padding_len = 0;
    }
    int total_len = 12 + type_len + data_len;
    
    if (type_padding_len != 4) {
        total_len = 12 + type_len + type_padding_len + data_len;
    }
    
    NSMutableString *mutable_cmd = [[NSMutableString  alloc] initWithString:type];
    for (int i = 0; i < type_padding_len; i++) {
        [mutable_cmd appendString:@"0"];
    }
    
    NSMutableString *mutable_data = [[NSMutableString  alloc] initWithString:data];
    for (int i = 0; i < data_padding_len; i++) {
        [mutable_data appendString:@"0"];
    }
    
    Byte finalArray[12];
    //total段
    Byte total_byte[4] = {0};
        
    Byte *total_ptr = total_byte;
        
    //int 转 byte数组
    *(int*)total_ptr = total_len;

    finalArray[0] = total_byte[0];
    finalArray[1] = total_byte[1];
    finalArray[2] = total_byte[2];
    finalArray[3] = total_byte[3];
    
    //format段,固定“json”格式
    Byte format_byte[4];
    Byte *format_ptr = format_byte;
    //int 转 byte数组
    int format_len = (int)format.length;
    *(int*)format_ptr = format_len;
    
    finalArray[4] = format_byte[0];
    finalArray[5] = format_byte[1];
    finalArray[6] = format_byte[2];
    finalArray[7] = format_byte[3];
    
    //type段,占一个字节
    Byte type_byte[1];
    Byte *type_ptr = type_byte;
    //int 转 byte数组
    *(int*)type_ptr = type_len;
    finalArray[8] = type_byte[0];
    
    //type_padding段,占一个字节
    Byte type_padding_byte[1];
    Byte *type_padding_ptr = type_padding_byte;
    //int 转 byte数组
    *(int*)type_padding_ptr = type_padding_len;
    finalArray[9] = type_padding_byte[0];
    
    //type_padding段,占一个字节
    Byte data_padding_byte[1];
    Byte *data_padding_ptr = data_padding_byte;
    //int 转 byte数组
    *(int*)data_padding_ptr = data_padding_len;
    finalArray[10] = data_padding_byte[0];
    
    //reased Byte段,占一个字节
    finalArray[11] = 0x00; //strtoul("0x00",0,16);
    
    //固定12个字节data
    NSData *fiex_data = [[NSData alloc] initWithBytes:&finalArray length:12];
    
    //type数据段
    NSData *type_data = [mutable_cmd dataUsingEncoding:NSUTF8StringEncoding];

    //data数据段
    NSData *data_data = [mutable_data dataUsingEncoding:NSUTF8StringEncoding];

    NSMutableData *all_data = [[NSMutableData alloc] init];
    [all_data appendData:fiex_data];
    [all_data appendData:type_data];
    [all_data appendData:data_data];
    
    NSData *base64Data = [all_data base64EncodedDataWithOptions:0];
    NSString *baseString = [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];

    NSString *base64 = [NSString stringWithFormat:@"data:application/octet-stream;base64,%@",baseString];
    
    return base64;

}
那个Byte数组那里的代码有点重复,我想抽一下,因为Object-C Byte类型不能作为函数值,所以就这样了。int转Byte数组有种C++方式:

测试:

	//json 33 + cmd + 10 +补位json(3)+cmd(2)+固定长度12=60
	NSString *json = @"{\"fileName\":\"log.ios.frfr4.h264\"}";
    NSString *format = @"json";
    NSString *cmd = @"openStream";
    NSString *data = [self logByteFill:json format:format type:cmd];
    NSLog(@"最后DATA == %@",data);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值