iOS自定义协议的数据写入与解析
2018-11-07 本文已影响6人
DoflaKaiGo
- 在一些需要兼容多端的开发的时候,可能会遇到使用自定义协议,比如与硬件通信或者使用socket的时候,接受的数据是按约定协议的字节数组,写数据的时候也需要按照协议来发送数据,这时就涉及到byte数组的的写入和解析(很久前记录在quiver上的了,今天有空整理了下,没细看,可能会有错误赘述)
首先简单说下基础概念:
1 byte = 8 bit
,一字节需要用8个二进制数来表示,0x00 = 0000 0000
,一个十六进制数需要四位二进制表示<< n
,左移n位,相当于* 2^n
,&0xFF
:相当于&1111 1111
,
-
正题开始
-
位移操作
<<, >>
>>
:表示向右边位移, 左边补零
<<
:左位移,右边补零
i = 10011100
;
i >> 3
—表示-> 10011100 -> 00010011
向右位移三位,左边补零
i << 3
—表示->10011100 -> 11100000
向左位移三位,右边补零
-
一个字节 = 八位二进制
0xff
:这里一个f 表示四位二进制,即表示 1111 1111
不失一般性:0xff00
: —>表示 1111 1111 0000 0000
当一个 byte &0xff
的时候,表示和 1111 1111
做位与 运算 ,作用是保持二进制原码一致,无符号,截取 低八位,因为 和 1111 1111
做位与 运算的时候,在这个数之前的都会变成 0,所以 起到截取 低位的作用
int 转16 进制
- M_1
int
四字节 数据是32位二进制数 byte 一字节,八位二进制
int a = 2312
;
byte b1 = a &0xff
;没有位移 和 0xff 与运算 取 最低八位
byte b2 = a >> 8 &0xff
;向右位移八位之后 与运算,取 次低八位
byte b3 = a >> 16 &0xff
;向右位移十六位之后 与运算,取 次高八位
byte b4 = a >> 24 &0xff
;向右位移二十四位之后 与运算,取 最高八位 - M_2先进行 与运算
byte b1 = a &0xff >>0
;向右位移0位,因为0xff
是八位二进制,和0xff
与运算 取 最低八位
byte b1 = a &0xff00 >>8
;因为0xff00
是十六位二进制,和0xff00
与运算 取 最低十六位,右移八位,去掉低八位,剩下 16位中的高八位,即原数据集的次低八位
byte b1 = a &0xff0000 >>16
;因为0xff0000
是二十四位二进制,和0xff0000
与运算 取 最低二十四位,右移十六位,去掉低十六位,剩下 24位中的高八位,即原数据集的次高八位
byte b1 = a &0xff000000 >>24
;因为0xff000000
是三十二位二进制,和0xff000000
与运算 取 最低三十二位(因为int是32位,即没有截取),右移24位,去掉低24位,剩下 32位中的高八位,即原数据集的高八位
- 对于二进制 十六进制十进制来说,在计算机中都是二进制表示,所以占多多少字节看是多少位的数,一字节八位 二进制,一位十六进制 在计算机中用 4位 二进制表示,所以:
0x4
这样的一位十六进制 用四位二进制表示,即占0.5字节byte
,0xAA
,这样的两位十六进制用八位二进制表示占一字节,0xABAC
:四位十六进制用十六位二进制表示占两字节,一bit
即代表一个二进制数 一字节八bit
(比特)
-
在计算机中所有的东西都是二进制表示,所以汉字也是用二进制表示,特殊的某个二进制数 对应着某个汉字,所以获取的 data 数据,不管什么进制 只要对应的始汉字的都能转成汉字,汉字也能转成 各种进制的数据,当然,同一个汉字在不同编码下对应的二进制数不同,所以编解码要用同一个编码格式才能保证数据正确显示
-
口水话就差不多吧,可能表述会有问题,下面贴上 几段代码
- 写入数据的时候
-(NSData *)WritMessage
{
Byte chCMD[15];
int cul = 0;
int iTemp;
//boolean bPass = false;
chCMD[cul++] = (Byte)0x18;
chCMD[cul++] = (Byte)0x81;
chCMD[cul++] = (Byte)0x35;
chCMD[cul++] = 852%256;
chCMD[cul++] = 852/256;
//Client ID
iTemp = (int)CNNUserInfo.Client_ID ;
chCMD[cul++] = (Byte)(iTemp & 0xFF);
chCMD[cul++] = (Byte)((iTemp & 0xFF00) >> 8);
chCMD[cul++] = (Byte)((iTemp & 0xFF0000) >> 16);
chCMD[cul++] = (Byte)((iTemp & 0xFF000000) >> 24);
//Group ID
iTemp = (int)CNNUserInfo.Current_GroupID;
chCMD[cul++] = (Byte)(iTemp & 0xFF);
chCMD[cul++] = (Byte)((iTemp & 0xFF00) >> 8);
chCMD[cul++] = (Byte)((iTemp & 0xFF0000) >> 16);
chCMD[cul++] = (Byte)((iTemp & 0xFF000000) >> 24);
chCMD[cul++] = (Byte)0x7F;
chCMD[cul++] = (Byte)0xF7;
return [NSData dataWithBytes:chCMD length:15];
}
- 读取数据
- (id)readData:(NSData *)data
{
NSMutableDictionary *RealTimeDic = [NSMutableDictionary dictionary];
Byte *chRevCP = (Byte*)[data bytes];
NSLog(@"data is %@",RealTimeDic);
int cul = 0;
// cul += 2; //0x18 0x81
cul += 1; //0x22
int local_ack = chRevCP[cul++];
if (local_ack == 0) {
[RealTimeDic setObject:@(0) forKey:kDicKey_SuccessLabel];
}else{
[RealTimeDic setObject:@1 forKey:kDicKey_SuccessLabel];
}
//总数
CNNUserInfo.Logger_Total = chRevCP[cul++];
for(int i=0; i<LLBUserInfo.Logger_Total; i++)
{
Byte nameByte[64];
EquipmentModel *LoggerModel = [EquipmentModel new];
NSMutableArray *passWayArr = [NSMutableArray new];
Byte snByte[10];
for(int j=0; j<10; j++)
{
snByte[j] = chRevCP[cul++];
}
//编号
LoggerModel.EquipmentCode= [[NSString alloc]initWithBytes:snByte length:10 encoding:LLBEncoding];
for(int j=0; j<48; j++)
{
nameByte[j] = chRevCP[cul++];
}
//名称
LoggerModel.EquipmentName = [[NSString alloc]initWithBytes:nameByte length:48 encoding:CNNEncoding];
//数目
LoggerModel.PassWayNumber = chRevCP[cul++];
PassWayModel *onePassWay = [PassWayModel new];
onePassWay.Type = chRevCP[cul++];
float high = ((chRevCP[cul]&0xFF) + (chRevCP[cul+1]&0xFF)*256 + (chRevCP[cul+2]&0xFF)*256*256 + (chRevCP[cul+3]&0xFF)*256*256*256)/(float)10.0;
onePassWay.High = high;
cul += 4;
onePassWay.Low = ((chRevCP[cul]&0xFF) + (chRevCP[cul+1]&0xFF)*256 + (chRevCP[cul+2]&0xFF)*256*256 + (chRevCP[cul+3]&0xFF)*256*256*256)/(float)10.0;
cul += 4;
onePassWay.data_dot = chRevCP[cul++];
Byte chtemp0[8];
for(int j = 0; j < 8; j++)
{
chtemp0[j] = chRevCP[cul++];
}
if (onePassWay.Type==8) {
onePassWay.Symbol = [[NSString alloc]initWithBytes:chtemp0 length:8 encoding:LLBEncoding];
}
}
- 实际上这些都算比较基本的东西,大学数电刚开始的时候也就这些什么进制编码之类的,只是开发的时候可能用到对字节数据操作的比较少,平时用的都是一些封装过的框架或者常见的数据类型,做个记录吧