使用Python来操作31位

时间:2016-08-08 16:12:17

标签: python binary hex python-3.4 pyserial

我有一个规范,概述了如何通过串行发送指令。

目前我正在制作将通过连接的数据包。

数据包的一个段需要32位(4字节)二进制数。 前31位是'数据',最后一位只是一个标志。

因此,可以适合数据的最大十进制数是:2147483647(2 ^ 31)。数据永远不会比这更大,酷!

我的问题是,如何将数据编码为31位二进制,然后设置最后一位以启用标志?

说我的数据是7AAAAAAA将此转换为31位二进制文​​件然后在结尾添加1或0的理想方法是什么?

编辑 - 我正在使用Python 3.4

3 个答案:

答案 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'
>>>