我有一个规范,概述了如何通过串行发送指令。
目前我正在制作将通过连接的数据包。
数据包的一个段需要32位(4字节)二进制数。 前31位是'数据',最后一位只是一个标志。
因此,可以适合数据的最大十进制数是:2147483647(2 ^ 31)。数据永远不会比这更大,酷!
我的问题是,如何将数据编码为31位二进制,然后设置最后一位以启用标志?
说我的数据是7AAAAAAA
将此转换为31位二进制文件然后在结尾添加1或0的理想方法是什么?
编辑 - 我正在使用Python 3.4
答案 0 :(得分:2)
我认为你可以使用二进制移位将你的旗帜添加到一个数字:
=query(uploadData!A:M,"Select B, C, H, I, M where not(C) contains '"&JOIN("|",filter!A:A)&"' and B contains 'Incoming' and not B is null and not H is null ",1)
要解压缩,您可以使用掩码和二进制AND,如下所示:
a = 0x7AAAAAAA # 2058005162 = 0b1111010101010101010101010101010
f = 1 # 1 = 0b1
packet = a + (f << 31) # a + 0b10000000000000000000000000000000
bin(packet) # 0b11111010101010101010101010101010
答案 1 :(得分:1)
我唯一想到的就是对字符串进行操作
假设我们有两个变量:
>>> data = '7AAAAAAA'
>>> flag = '1'
将数据十六进制转换为数字
>>> num = int(data, 16)
>>> num
2058005162
将数字转换为字符串二进制表示形式:
>>> bin_num = bin(num)
>>> bin_num
'0b1111010101010101010101010101010'
将标志附加到结尾
>>> bin_num += flag
>>> bin_num
'0b11110101010101010101010101010101'
评估字符串以获取数字并转换回十六进制或任何您需要的内容:
>>> eval(bin_num)
4116010325
<强>#EDIT1 强>
为了将值扩展为4个字节,您可以使用:
>>> final_val = eval(bin_num)
>>> int.to_bytes(final_val, 4, 'big')
b'\xf5UUU'
<强>#EDIT2 强>
def convert(data, flag):
with_flag = eval(bin(int(data, 16)) + flag)
return int.to_bytes(with_flag, 4, 'big')
def unconvert(byte_data):
bin_str = bin(int.from_bytes(byte_data, 'big'))
flag = bin_str[-1]
data = bin_str[:-1]
return (hex(eval(data)), flag)
答案 2 :(得分:0)
查看是否有效,与其他答案类似,但是考虑原始位长。
定义最终位数
>>> bits = 16
以字节文字
开头>>> a = b'10'
转换为int
>>> b = int(a, base = 16)
向左移动到所需的位长度
>>> shift = bits - b.bit_length()
>>> c = b << shift
添加标志
>>> d = c | 1
>>>
>>> a
b'10'
>>> b
16
>>> c
32768
>>> d
32769
>>> bin(b)
'0b10000'
>>> bin(c)
'0b1000000000000000'
>>> bin(d)
'0b1000000000000001'
>>>