如何在python中将二进制数据从文件转换为可读的二进制二进制文件?

时间:2016-04-02 09:25:49

标签: python python-3.x binary hex bits

在我所在的班级中,我们被分配到一个简单的mips模拟器。我的程序应该处理的指令是在二进制文件中给出的。我不知道如何从该文件中获取任何可用的内容。这是我的代码:

import struct
import argparse

'''open a parser to get command line arguments '''
parser = argparse.ArgumentParser(description='Mips instruction simulator')

'''add two required arguments for the input file and the output file'''
parser.add_argument('-i', action="store", dest='infile_name', help="-i INPUT_FILE", required=True)
parser.add_argument('-o', action="store", dest='outfile_name', help="-o OUTPUT_FILE_NAME", required=True)

'''get the passed arguments'''
args = parser.parse_args()


class Disassembler:
    '''Disassembler for mips code'''
    instruction_buffer = None
    instructions_read = 0

    def __init__(self, filename):
        bin_file = None
        try:
            bin_file = open(filename, 'rb')
        except:
            print("Input file: ", filename, " could not be opened. Check the name, permissions, or path")
            quit()

        while True:
            read_bytes = bin_file.read(4)
            if (read_bytes == b''):
                break
            int_var = struct.unpack('>I', read_bytes)
            print(int_var)

        bin_file.close()


disembler = Disassembler(args.infile_name)

所以,起初我只打印了我读过的4个字节,看看返回了什么。 我希望看到普通的比特(只有1&0; s和0' s)。我得到的是我读过的字节串。所以我试着谷歌搜索我能做些什么。所以我发现我可以使用struct将这些字节字符串转换为整数。以类似于(4294967295,)的格式输出它们。

这仍然很烦人,因为我必须修剪它以使其成为可用的整数,然后我仍然必须将其转换为位(基数2)。很高兴我可以将struct读取为有符号或无符号的字节,因为输入文件输入的一半是带符号的32位数字。

所有这些似乎比从二进制文件中获取位更复杂。有更简单的方法吗?你也可以解释一下,就像你对那些不太熟悉深奥的python代码并且对二进制数据不熟悉的人一样吗?

我的总体目标是从我读过的每4个字节中直接获得32位。该文件的开头是mips操作码列表。所以我需要能够看到这些数字的特定部分,比如前5位,然后是接下来的6位,依此类推。文件末尾包含32位有符号整数值。这两个文件由break操作码分隔。

感谢您提供给我的任何帮助。它让我发疯,我无法通过搜索找到任何直接的答案。如果你想看到二进制文件,告诉我在哪里发布它。

2 个答案:

答案 0 :(得分:1)

请记住,普通的Python整数没有固定的位宽:它们的大小和它们需要的一样大。当您想要将有符号整数转换为位串时,这可能很烦人。我建议您坚持使用目前正在做的事情:使用

将4字节的块转换为无符号整数
n = struct.unpack('>I', read_bytes)[0]

然后使用format(n, '032b')'{0:032b}'.format(n)将其转换为位字符串,如果要打印位。

要访问或修改整数中的位,您不应该为字符串转换而烦恼,而应该使用Python的按位运算符&|,{ {1}},^<<>>。例如,~为您提供(n >> 7) & 1的第7位。

有关这些运算符的详细信息,请参阅Python文档中的Unary arithmetic and bitwise operations和以下部分。

答案 1 :(得分:0)

这样您就可以访问文件中的每个位。

"".join(format(i, "08b") for i in byte_string)

例如:

>>> "".join(format(i, "08b") for i in b"\x23\x54a")
'001000110101010001100001'