2016-11-30 2 views
1

Я хочу прочитать двоичный файл, получить содержимое четыре байта на четыре байта и выполнить int-операции над этими пакетами.Python3 чтение двоичного файла, 4 байта за раз и xor с 4-байтным длинным ключом

Используя фиктивный двоичный файл, открыл этот путь:

with open('MEM_10001000_0000B000.mem', 'br') as f: 
    for byte in f.read(): 
      print (hex(byte)) 

Я хочу, чтобы выполнить шифрование с длинным ключом 4 байта, 0x9485A347, например.

Есть ли простой способ читать мои файлы по 4 байта за один раз и получать их как int или мне нужно поместить их во временный результат с помощью счетчика?

Моя первоначальная идея заключается в следующем:

 current_tmp = [] 
     for byte in data: 
      current_tmp.append(int(byte)) 
      if (len(current_tmp) == 4): 
        print (current_tmp) 
        # but current_tmp is an array not a single int 
        current_tmp = [] 

В моем примере, вместо того, чтобы [132, 4, 240, 215] я предпочел бы 0x8404f0d7

ответ

4

Просто используйте параметр «количество» чтения читать 4 байта за время, и «from_bytes» конструктор в Python 3 int, чтобы получить это происходит:

with open('MEM_10001000_0000B000.mem', 'br') as f: 
    data = f.read(4) 
    while data: 
     number = int.from_bytes(data, "big") 
     ... 
     data = f.read(4) 

Если вы не USI нг Python 3 все же по какой-то причине, int не есть метод from_bytes - тогда можно прибегнуть использовать модуль STRUCT:

import struct 
... 
    number = struct.unpack(">i", data)[0] 
    ... 

Эти методы, однако хороши для пары interations, и может получить медленно для большой файл - Python предлагает способ для вас, чтобы просто заполнить массив целых чисел 4 байт непосредственно в памяти из OpenFile - что более вероятно, что вы должны использовать:

import array, os 
numbers = array.array("i") 
with open('MEM_10001000_0000B000.mem', 'br') as f: 
    numbers.fromfile(f, os.stat('MEM_10001000_0000B000.mem').st_size // numbers.itemsize) 
numbers.byteswap() 

После того, как у вас есть массив, вы можете использовать его с чем-то вроде

from functools import reduce #not needed in Python2.7 
result = reduce(lambda result, input: result^input, numbers, key) 

предоставит вам последовательность numbers со всеми номерами в вашем файле, считанные как 4 байта, большой конец, подписанный ints.

Если файл не является кратным 4 байтам, для первых двух методов может потребоваться некоторая настройка - исправления состояния while будет достаточно.

+0

OP хочет '[132, 4, 240, 215]' конвертировать в '0x8404f0d7', т. Е. Вам нужен большой размер. –

+2

Также остерегайтесь последних байтов, если размер файла не кратен 4 ... –

+0

Спасибо - исправлены обе вещи – jsbueno

 Смежные вопросы

  • Нет связанных вопросов^_^