如何在python中搜索设定数量的十六进制和非十六进制数据

时间:2015-06-26 22:29:49

标签: python regex hex

我有一个看起来像这样的字符串

'\x00\x03\x10B\x00\x0e12102 G1103543\x10T\x07\x21'

我能够将我想要的数据“12102 G1103543”与此匹配。

re.findall('\x10\x42(.*)\x10\x54', data)

将输出此

'\x00\x0e12102 G1103543'

我遇到的问题是\ x10 \ x54并不总是在我想要的数据的末尾。然而,我注意到前两个十六进制数字对应于数据长度的长度。 I.E. \ x00 \ x0e = 14所以数据长度为14char。

有没有更好的方法来做到这一点,比如匹配第一部分然后削减接下来的14个字符?我还应该说,长度会因为我想要匹配几件事而变化。

还有一种方法可以输出所有十六进制中的字符串,这样我在python shell中工作时更容易阅读。 \ x10B == \ x10 \ x42

谢谢!

编辑:我设法提出了这个有效的解决方案。

newdata = re.findall('\x10\x42(.*)', data)
newdata[0][2:int(newdata[0][0:2].encode('hex'))]

1 个答案:

答案 0 :(得分:0)

请注意,您手边有一个结构化的二进制文件,尝试使用正则表达式从中提取数据是愚蠢的。

首先,你谈到的“十六进制数据”不是“十六进制数据” - 它只是字节 在ASCII范围之外的流中 - 因此Python2会将这些字符显示为\x10,依此类推 - 但在内部它只是一个值为16的单字节(当被视为十进制时)。您编写的\x42对应于ASCII字母B,这就是您在代表中看到B的原因。

所以你最好的选择是获取文件规范,并使用struct模块和字节串切片从那里读取你想要的数据。

如果您不能拥有文件规范,那么查找感兴趣的字段是一项逆向工程工作 - 就像您已经在做的那样。但即便如此,你应该用struct模块编写一些代码来获取你的值,因为字段长度(以及最有可能的偏移量)都是在字节流本身中编码的。

在此示例中,您的标记“\ x10 \ x42”很少会成为标记本身 - 很可能它的位置由文件中的其他因素指示(文件定义中的固定位置,或者早先在文件上偏移。

但是 - 如果您正确使用它作为标记,您可以使用正则表达式来查找“\ x10 \ x42”标记的所有偏移量,并将它们解释为以下两个字节消息长度:

import struct, re

def get_data(data, sep=b"\x10B"):
    results = []
    for match in re.finditer(sep, data):
        offset = match.start()
        msglen = struct.unpack(">H", data[offset + 2: offset + 4])[0]
        print(msglen)
        results.append(data[offset + 4: offset + 4 + msglen])
    return results