我正在编写一个Python程序,在其中逐个字节地处理文件,并且试图编写一个将字节分成上下半部分的函数。详细地说,假设我要在具有十进制值18
和十六进制值12
的字节上运行此函数。我希望将其拆分为两个字节,其值分别为1
和2
。
这是我为此编写的函数:
# split byte into upper and lower halves
def splitByte(b):
lowerMask = b'\x0F'
lowerHalf = bytes(b & lowerMask[0])[0]
upperMask = b'\xF0'
upperHalf = bytes(b & upperMask[0])[0]
upperHalf = upperHalf >> 4
return [upperHalf,lowerHalf]
在这里我要调用函数:
info = stream.read(1)
result = splitByte(info[0])
print(result)
但是,当我仅使用上述代码和函数运行文件时,会发生以下情况:
[0, 0]
[0, 0]
[0, 0]
[0, 0]
Traceback (most recent call last):
File "./test.py", line 8, in <module>
result = splitByte(info[0])
File "<home folder>/byteops.py", line 21, in splitByte
lowerHalf = bytes(b & lowerMask[0])[0]
IndexError: index out of range
该函数不仅会为两个值返回0
,而且还会在某些输入上出错,并出现“索引超出范围”错误。对于上下文,这是我从十六进制编辑器中读取的文件:
00000000: 4C 49 54 35 30 0A 09 09 02 01
我正在使用Python 3.7.1运行Manjaro Linux。我应该如何修复splitByte
函数,或者有一个适合我的库函数?
答案 0 :(得分:2)
您的问题是从int
转换为bytes
。 bytes(2)
是对两个零的字节数组的请求。您可以简单地使用您已经知道的int操作:
# split byte into upper and lower halves
def splitByte(b):
lowerHalf = b & 15
upperHalf = (b >> 4) & 15
return [upperHalf,lowerHalf]
result = splitByte(18)
print(result)
输出:
[1, 2]
我将其保留为整数,因为您的原始程序只需要字节除法,而不需要bytearray
。
答案 1 :(得分:1)
有一种更简单的方法可以做到这一点。您可以使用ord
函数将单个字符转换为其ASCII值(以10为底)。然后,使用hex
函数将此值转换为十六进制值(以字符串形式)。现在,您可以轻松访问值的上部和下部。
这里是一个例子:
val = 'a'
print(hex(ord(val))[2]) # 6
print(hex(ord(val))[3]) # 1
您得到6
和1
,因为a
的十六进制值为0x61。
现在,如果直接获取源文件中每个字符的十进制值,则可以摆脱ord
函数的作用:
val = 97
print(hex(val)[2]) # 6
print(hex(val)[3]) # 1