0

我有一个看起来像的十六进制数组:

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.

希望这是有道理的。任何帮助将不胜感激。

4

6 回答 6

6

将所有内容转换为一个大字符串,然后枚举它。大部分类似于 blaxpirit 的答案,但它不使用[:2]hack。

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]
于 2012-08-08T20:50:36.577 回答
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'with [2:],在开头添加零,因此序列正好是 8 长 ( '110001'.zfill(8) == '00110001')。然后我们将所有位串连接到一个字符串中。

s = ''.join(bin(int(b, 16))[2:].zfill(8) for b in s.split())
# Now `s` is '0011000100110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
  • 上述行的替代方案,适用于 Python 2.5:
    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是位,所以每个位(b)都会有一个对应的位置(i),就像你描述的那样。我们使用列表推导并仅包含符号为 的那些位置'1'

r = [i for i, b in enumerate(s) if b=='1']
# Now `r` is [2, 3, 7, 10, 11, 15]
于 2012-08-08T20:24:26.467 回答
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"]

因此,假设您已经将十六进制放在一个数组中,这将为您提供您正在寻找的答案。

于 2012-08-08T20:23:35.597 回答
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]

如果您的数组实际上是一个十六进制字符串,那么您可以将其转换为字节数组:

>>> import binascii
>>> arr = bytearray(binascii.unhexlify(s.replace(' ', '')))
>>> arr
bytearray(b'11\x00\x00\x00\x00\x00...\x00')
于 2012-08-08T22:13:31.860 回答
0
>>> print int('31', 16)
49

从那里,您可以使用列表推导式或生成器表达式来执行多个值。

于 2012-08-08T20:17:36.970 回答
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]
于 2012-08-08T20:30:54.203 回答