【问题标题】:Python - issue with reading in hex bytePython - 读取十六进制字节的问题
【发布时间】:2015-03-22 17:52:10
【问题描述】:

我正在阅读一个包含十六进制字节的文件,我相信这是我写的:

def ByteToHexToDec( byteStr ):
    hex_list = [ "%02X" % ord(x) if "\\x" in r"%r" % x else x for x in byteStr];
    return hex_list;

with open("file.z","rb") as lines:
    for line in lines:
        print ByteToHexToDec(line);

这是它返回的内容:

['04', '80', 'e', '06', 'C0', 'l', '06', 'F0', ',', '02', '00', 'w', '06', 'F0', 'r', '06', 'C0', 'd', '02', '10', '\n']

我很确定这说的是 hello world(或类似的东西),而且我知道“hello world”的十六进制是这样的:

480065006C006C006F00200077006F0072006C00640021

如果你仔细观察,'48' 与 hex_list 中的前两个元素匹配,除了零在路上,字母 e 的十六进制值是 65...

那么文件中的字节是否有一些错误?还是我读错了字节?

谢谢

文件可以在这里下载: https://drive.google.com/file/d/0B84_Z1V4nj9SS0x4MlR0a2poMkE/view?usp=sharing

【问题讨论】:

  • 文件内容的输出是正确的。
  • 我不确定您是如何生成该文件的,但您在该文件的开头有0480,而不是4800e 被正确地保存为 65 字节,后跟两个字节构成下一个 l06c0。我怀疑您在创建文件时忘记填充字节。

标签: python hex byte


【解决方案1】:

文件中的每个其他字节都用开头和结尾的 0 填充:

  • H04 80 而不是 48
  • e65(正确)
  • l06 c0 而不是 6c
  • l6c(正确)
  • o06 f0 而不是 6f
  • ,2c(正确)
  • (空格)是 02 00 而不是 20

等等。

如果你想让它变回Hello, world,你必须修复这个破损:

def repairbroken(bytestr):
    bytestr = iter(bytestr)
    for byte1, byte2, byte3 in zip(*([bytestr] * 3)):
        # character 1 is bits 4-7 in the first byte and bits 0-3 in the second
        char1 = chr((ord(byte1) & 0xff) << 4 | (ord(byte2) & 0xff) >> 4)
        yield char1
        yield byte3

演示:

>>> binary = '\x04\x80e\x06\xc0l\x06\xf0,\x02\x00w\x06\xf0r\x06\xc0d\x02\x10\n'
>>> print ''.join(repairbroken(binary))
Hello, world!

【讨论】:

  • 或者它可以是压缩的 12 位字符。不确定高位会包含什么。
  • 如果它被打包为 12 位,我将如何以不同的方式读取字节?
  • @WerdnaKof:您仍然需要一次读取 3 个字节并将这 24 位拆分为 12 位。这取决于您每次做什么时前 4 位中的内容跟他们;在这里,我只是丢弃了每次忽略的 4 位。
  • @WerdnaKof:如果前 4 位用于任何用途,则不清楚这些位的确切用途以及它们如何映射到字符。
  • 好的,我想我现在明白了,所以我将第一个字节转换为二进制形式:00000100 10000000 01100101 然后切成两半,000001001000 000001100101 给我 48 和 65! (感谢您的帮助)
【解决方案2】:

文件的十六进制内容:

$ od -t x1z -w16 file.z 
0000000 04 80 65 06 c0 6c 06 f0 2c 02 00 77 06 f0 72 06  >..e..l..,..w..r.<
0000020 c0 64 02 10 0a                                   >.d...<
0000025

你在尝试什么?

$ echo 'hello world' | od -t x1z -w12 
0000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a  >hello world.<
0000014

注意binascii模块中的hexlify/unhexlify https://docs.python.org/2/library/binascii.html

【讨论】:

  • hmm,当我在没有转换的情况下阅读它时,我得到了这个: ['\x04', '\x80', 'e', '\x06', '\xc0', 'l', '\x06', '\xf0', ',', '\x02', '\x00', 'w', '\x06', '\xf0', 'r', '\x06', '\xc0 ', 'd', '\x02', '\x10', '\n'] 我只是想将这些十六进制字节转换为十进制(我可以这样做),但问题是它们没有出现世界。
  • 查看 Martijn 的回复,然后是我这里的最后一行。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 2014-05-06
  • 2017-09-13
  • 2015-08-08
  • 1970-01-01
  • 2022-12-12
  • 2019-08-19
  • 1970-01-01
相关资源
最近更新 更多