我有一个Hex数组,看起来像:
31 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
将此转换为二进制时,这看起来像:0011000100110001
每个位都是与数组中的数字相关的标志。在这种情况下,这个二进制数将等于2,3,7,10,11,15。
我不确定这个符号是否有名称,但是有没有简单的方法来转换十六进制以获得如上所示的十进制数列表。
所以,
每个0x31
等于一个字节或8位。
每个0x31
转换为00110001
。
然后应该解释这个二进制文件的解释方式是。
0 1 2 3 4 5 6 7 8 9 10
0 0 1 1 0 0 0 1 ......
在这里你可以看到我从0x31
得到了小数值2,3,7。
希望这是有道理的。任何帮助将不胜感激。
答案 0 :(得分:6)
将所有内容转换为大字符串,然后枚举它。与blaxpirit的答案大致相似,但它不使用[:2]
黑客。
array = [0x31, 0x31, 0, 0, 0]
[i for i, x in enumerate("".join(format(a, "08b") for a in array)) if x == '1']
结果
[2, 3, 7, 10, 11, 15]
答案 1 :(得分:5)
所以我们在空格分隔的字符串中有十六进制数字。
s = '31 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
现在我们拆分字符串,将每个字节从十六进制字符串转换为int(int('31', 16) == 49
),然后将其转换为二进制字符串(bin(49) == '0b110001'
),然后用{转移'0b'
{1}},在开头添加零,使序列恰好为8长([2:]
)。然后我们将所有位串连接在一起。
'110001'.zfill(8) == '00110001'
trans = {'0':'0000','1':'0001','2':'0010','3':'0011','4':'0100','5':'0101','6':'0110','7':'0111','8':'1000','9':'1001','a':'1010','b':'1011','c':'1100','d':'1101','e':'1110','f':'1111',' ':''} s = ''.join(trans[c] for c in s.lower())
然后我们enumerate
这些位,所以每个位(s = ''.join(bin(int(b, 16))[2:].zfill(8) for b in s.split())
# Now `s` is '0011000100110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
)将具有相应的位置(b
),正如您所描述的那样。我们使用列表推导并仅包含符号为i
的位置。
'1'
答案 2 :(得分:2)
好吧,首先,你需要将十六进制数组转换为整数,然后转换为二进制数组。这在python中非常简单:
myBin = bin(int("".join(hexArray),16))[2:].zfill(len(hexArray)*8) #We slice to get rid of the "0b" prepended by the bin function. zfill puts in leading zeros so we don't miss anything
接下来,我们可以做一些很酷的枚举和列表理解,以获得我们需要的数字:
myInts = [off for x, off in enumerate(myBin) if x == "1"]
所以,假设你已经在一个数组中有了你的十六进制,这将为你提供你正在寻找的答案。
答案 3 :(得分:1)
使用预先计算的位置列表:
arr = [0x31, 0x31, 0, 0, 0]
print [(8*byte_ind + i) for byte_ind, b in enumerate(arr) for i in positions[b]]
# -> [2, 3, 7, 10, 11, 15]
其中positions
将所有(256)个字节映射到相应的位置:
>>> def num2pos(n):
... return [i for i, b in enumerate(format(n, '08b')) if b == '1']
...
>>> positions = map(num2pos, range(0x100))
>>> positions[0x31]
[2, 3, 7]
如果您的数组实际上是十六进制字符串,那么您可以将其转换为bytearray:
>>> import binascii
>>> arr = bytearray(binascii.unhexlify(s.replace(' ', '')))
>>> arr
bytearray(b'11\x00\x00\x00\x00\x00...\x00')
答案 4 :(得分:0)
>>> print int('31', 16)
49
从那里,您可以使用列表推导或生成器表达式来执行多个值。
答案 5 :(得分:0)
我认为以下内容符合您的要求:
def to_int_list(hex_array):
hex_str = ''.join(hex_array)
value = int(hex_str, 16)
i = 4*len(hex_str) - 1
result = []
while value:
if value & 1:
result.append(i)
value = value >> 1
i -= 1
return result[::-1]
>>> to_int_list(['31', '31', '00', '00', '00', '00'])
[2, 3, 7, 10, 11, 15]