如何将十六进制数字数组转换为字节数组-python



我在python中有一个十六进制值数组,我想将其转换为分解为单个字节的这些值的数组,存储为字符串。

例如:

给定输入

hexValueAr = [0x085F80, 0x0109A53, 0x0188C6D]

我想要输出

bytesAr = ['08', '5F', '80', ...]

我想知道是否有内置的python函数来进行此转换,或者其他一些简单的方法可以进行转换?

编辑:我的输入值是作为十六进制值存储在数组中的整数。我的输入数组有 48 个这样的整数,我只是缩短了它以使其更易于阅读。希望这有帮助。

你的整数是用十六进制编码的,这一事实与这个问题无关。

hexValueAr = [0x085F80, 0x0109A53, 0x0188C6D]

hexValueAr = [548736, 1088083, 1608813]

结果相同。

Python 整数已经有一种方法可以转换为字节:int.to_bytes.之后转换为字符串非常简单(只需使用str.formathex)。唯一的问题是您需要知道预先使用的字节数。在您的情况下,您可以使用数字 3,也可以使用int.bit_length方法进行计算。

以下是上述方法的一种可能实现:

from math import ceil
bytesAr = []
for num in hexValueAr:
count = ceil(num.bit_length() / 8)
bytes = num.to_bytes(count, 'big')
bytesAr.extend('{:02X}'.format(x) for x in bytes)

这会产生结果

['08', '5F', '80', '10', '9A', '53', '18', '8C', '6D']

这里的顺序是大端序:整数的最高字节位于数组的最低索引中。

如果你想把它作为单行,你可以做:

bytesAr = ['{:02X}'.format(x) for num in hexValueAr for x in num.to_bytes(ceil(num.bit_length() / 8), 'big')]

这里可能需要注意的是,输入中的不同数字可能会在输出中为您提供不同数量的元素。例如,如果您的输入是[0x00AB, 0x109C],第一个元素将产生一个字符串,而第二个元素将产生 2。如果要避免这种情况,请找到对其中一个整数进行编码所需的最大字节数,并使用该字节数代替ceil(num.bit_length() / 8)

byte_count = ceil(max(hexValueAr).bit_length() /  8))
bytesAr = ['{:02X}'.format(x) for num in hexValueAr for x in num.to_bytes(byte_count, 'big')]

在这种情况下,像[0x00AB, 0x109C]这样的输入将导致一堆零,但每个数字的字节数相等:['00', ''AB', '10', '9C']

def int_to_hexbytes(i):
s = '%X' % i
if len(s) % 2:
s = '0' + s
return [s[i:i+2] for i in range(0, len(s), 2)]
def words_to_hexbytes(a):
ret = []
for i in a:
ret += int_to_hexbytes(i)
return ret
assert int_to_hexbytes(0x0123456789ABCDEF) == ['01', '23', '45', '67', '89', 'AB', 'CD', 'EF']
assert int_to_hexbytes(0x123456789ABCDEF0) == ['12', '34', '56', '78', '9A', 'BC', 'DE', 'F0']
assert words_to_hexbytes([0x123, 0x456, 0x78]) == ['01', '23', '04', '56', '78']
assert words_to_hexbytes([0x085F80, 0x0109A53, 0x0188C6D]) == ['08', '5F', '80', '10', '9A', '53', '18', '8C', '6D']

int_to_hexbytes使用%格式运算符将整数参数转换为包含其十六进制表示形式的字符串;然后使用列表推导式将该字符串拆分为每隔一个字符的列表(即每个字节)。请注意,由于最左边的字节可能小于0x10,代码会预先预置一个'0'(即当字符串长度为奇数时)。

words_to_hexbytes只是遍历数组参数并附加int_to_hexbytes的结果。

之后的assert只是测试代码的快速方法,同时向读者展示预期的结果。

hexValueAr=['0x085F80','0x0109A53','0x0188C6D']
stripped = list(map(lambda x: x.split('x')[1], hexValueAr))
byte_list = []
for hex_string in stripped:
for i in range(3):
byte_list += [hex_string[2*i:2*i+2]]
print(byte_list)
hexValueAr=[0x085F80,0x0109A53,0x0188C6D]
bytes = []
for i in hexValueAr:
x = "%6.6x" % i
bytes += [x[0:2], x[2:4], x[4:6]] 

最新更新