需求:下位机通过以太网将数据数据发送到Python上位机中,上位机显示为bytes类型的数据,如下
b'$\xca\x9a;33DDUUffww
我们需要将这个字节串转换为数字。
这中间混有16进制的数据,同时也有ASCII码。为什么传送的字节串中会出现混合的情形呢?
原因如下:
字节串是什么?就是一堆二进制的无编码的字节(1Byte),不表示任何东西。由于1个字节有8bit,所以字节可以使用数字来表示。使用二进制来表示明显过长,一般情况合使用两位数的16进制数表示,由于字节串和字符串本质是对应的关系,所以python中的字节串操作与字符串几乎相同。
由于十六进制的前128(0x00~0x80)个数与ASCII是一一对应的关系,所以在python中,表示字节串的时候将会出现16进制与ASCII码混合出现的情况。如:
>>> b'\x25\x90\x52'
b'%\x90R'
>>> [ hex(x) for x in b'%\x90R' ] #将字节串中的每2个字节(16个bit)转为16进制显示
['0x25', '0x90', '0x52']
字节串转数字的方法:
方法 1 python3.2及以上
大端法:
大端机:存储数据大端在前,第一个字节是最大的
>>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='big')
2043455163
小端法:
小端机:存储数据小端在前,第一个字节是最小的
>>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='little')
3148270713
方法2 导入struct包
- struct的更高级用法,请参考https://docs.python.org/3/library/struct.html
特别要注意的时unpack的第一个参数的确定条件(较难理解)。
import struct
struct.unpack('>L', b'$\xca\x9a;')[0]
输出结果 617257531
方法3 自定义函数实现
调用函数即可
def bytes_to_int(bytes):
result = 0
for b in bytes:
result = result * 256 + int(b)
return result
def int_to_bytes(value, length):
result = []
for i in range(0, length):
result.append(value >> (i * 8) & 0xff)
result.reverse()
return result
参考资料:
- 【python3下的编码与进制转换总结】http://yinflying.top/2017/07/637
- 【Python札记】byte转integer https://blog.csdn.net/yinxingsha/article/details/52953853
- 【Stackoverfolw】https://stackoverflow.com/questions/444591/convert-a-string-of-bytes-into-an-int-python
- 【自定义函数实现】https://coderwall.com/p/x6xtxq/convert-bytes-to-int-or-int-to-bytes-in-python