简体   繁体   English

python中的十六进制字符串类型转换

[英]Hex string type conversion in python

Since hours I try to solve this problem - hope anybody can help me.从几个小时以来,我试图解决这个问题 - 希望任何人都可以帮助我。 I parse a hex number out of the output of a program, which I run via Popen in Python.我从程序的输出中解析出一个十六进制数,我通过 Python 中的 Popen 运行该程序。 In the next step, this hex number is used as parameter for another call of the program via Popen.在下一步中,该十六进制数用作通过 Popen 再次调用程序的参数。 The problem is, that I am not able to pass the hex value to Popen, so that it works:问题是,我无法将十六进制值传递给 Popen,因此它可以工作:

cmd = "./my_program"
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
response = p.stdout.read()
hexapattern = r'0x([0-9a-fA-F]+)'
hex_output = re.findall(hexapattern, str(response))[1]  #e.g.: hex_string = 35fe9a30
hex_string = '\\x' + hex_output[6] + hex_output[7] + '\\x' + hex_output[4] + hex_output[5] + '\\x' + hex_output[2] + hex_output[3] + '\\x' + hex_output[0] + hex_output[1]   #e.g.: hex_string = \x35\xfe\9a\x30
payload = '\x41\x41\x41' + hex_string
cmd = "echo -e -n " + payload + " | ./my_program"
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
response = p.stdout.read()
print(response)

The following line does not work the way it should.以下行不按应有的方式工作。 While the first part of the string is correctly interpreted (as 'AAA', ASCII character with number 41), the 'hex_string' is used in bash as '\\x35\\xfe\\9a\\x30'.虽然字符串的第一部分被正确解释(作为“AAA”,数字为 41 的 ASCII 字符),但“hex_string”在 bash 中被用作“\\x35\\xfe\\9a\\x30”。 It is not a problem, that some chars are not printable.这不是问题,有些字符是不可打印的。

payload = '\x41\x41\x41' + hex_string
Output: AAA\x35\xfe\9a\x30

When I change the program to set the value manually to the variable (I don't want to do this), it works without any problems.当我更改程序以手动将值设置为变量时(我不想这样做),它可以正常工作。

payload = '\x41\x41\x41' + '\x35\xfe\9a\x30'
Output: AAA[not printable char][not printable char][not printable char]

I already tried a lot of type conversions but failed.我已经尝试了很多类型转换但都失败了。

ast.literal_eval is a way to make the string like if you typed it literally. ast.literal_eval是一种使字符串像字面上键入一样的方法。

hex_output = "35fe9a30"
hex_string = '\\x' + hex_output[6] + hex_output[7] + '\\x' + hex_output[4] + hex_output[5] + '\\x' + hex_output[2] + hex_output[3] + '\\x' + hex_output[0] + hex_output[1]   #e.g.: hex_string = \x35\xfe\9a\x30
payload = '\x41\x41\x41' + hex_string

import ast

result =  ast.literal_eval('"{}"'.format(payload))

print('\x41\x41\x41' + '\x30\x9a\xfe\x35' == result)

prints True (note that hex_string is the reverted version of hex_output , which doesn't simplify the example...)打印True (注意, hex_string是还原后的版本hex_output ,这并没有简化的例子...)

We just told ast.literal_eval to evaluate the string (hence the formatting with quotes) containing payload我们只是告诉ast.literal_eval评估包含payload的字符串(因此格式化带引号)

There may be simpler solutions with codec , handling the whole data as bytes instead of str : codec可能有更简单的解决方案,将整个数据作为bytes而不是str

import codecs
print(b'\x41\x41\x41' + codecs.decode(hex_output.encode(),"hex"))

prints:印刷:

b'AAA5\xfe\x9a0'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM