Как конвертировать int в hex и записать hex в файл? - PullRequest
0 голосов
/ 09 января 2019

Я хочу сделать следующее в Python 2.7.13:

  • Преобразовать значение типа int в шестнадцатеричное (58829405413336430 должно стать d101085402656e)
  • Добавить полезную нагрузку (простая строка, например, c1234) в созданный гекс
  • Запись pure hex в файл

Мой код в настоящее время выглядит так:

mime=58829405413336430
payload="c9999"

fw_file=open('testhex', 'wb')
fw_file.write("%x" % mime)
fw_file.write(str(payload).encode("hex"))
fw_file.close()

И я получаю следующий файл (используя xxd в Debian):

xxd HACKEDTOGETHER
00000000: 6431 3031 3038 3534 3032 3635 3665 3633  d101085402656e63
00000010: 3339 3339 3339 3339                      39393939

что не что мне нужно. Мне нужен файл, который выглядит так:

xxd WORKING
00000000: d101 0854 0265 6e63 3939 3939            ...T.enc9999

Я понимаю следующее:

"%x" % mime преобразовал мой int в hex, но он был записан как String. encode сделал это правильно, но это не работает с целыми числами. Как я могу обойти это поведение и записать «чистый» hex в мой файл? Если это невозможно сделать в Python 2, я также могу использовать Python 3.

Так как это мой первый вопрос по StackOverflow, пожалуйста, скажите мне, если я должен сделать что-то другое.

1 Ответ

0 голосов
/ 09 января 2019

Частично проблема заключается в том, что результатом "%x" % mime является строка пар шестнадцатеричных символов - "d101085402656e" в этом случае - которая представляет значение целого числа mime в этом формат, так что это то, что записывается в файл. Однако необходимы фактические значения байтов, которые составляют само целое число.

В Python 3 это можно легко решить, используя вместо этого встроенный метод с именем to_bytes(), который был добавлен к типу int в этой версии, но в Python 2.x он должно быть сделано по-другому.

Существует аналогичная проблема из-за использования str(payload).encode("hex"), которое также возвращает шестнадцатеричное строковое представление, а не фактические значения байтов каждого символа уже в payload, что и нужно. К счастью, в этом случае то, что должно быть, может быть легко достигнуто с помощью встроенного bytearray класса Python 2.x имеет.

Ниже я написал версию функции, опубликованной как часть ответа на связанный вопрос , который может решить проблему со значением mime.

После этого определения функции приведен код, показывающий, как использовать ее в этом случае вместе с классом bytearray для получения надлежащих двоичных данных, записанных в файл.

def int_to_bytes(n, minlen=0):
    """ Convert integer to bytearray with optional minimum length. 
    """
    if n > 0:
        arr = []
        while n:
            n, rem = n >> 8, n & 0xff
            arr.append(rem)
        b = bytearray(reversed(arr))
    elif n == 0:
        b = bytearray(b'\x00')
    else:
        raise ValueError('Only non-negative values supported')

    if minlen > 0 and len(b) < minlen: # zero padding needed?
        b = (minlen-len(b)) * '\x00' + b
    return b

mime = 58829405413336430
payload = 'c9999'

with open('testhex', 'wb') as fw_file:
    fw_file.write(int_to_bytes(mime))
    fw_file.write(bytearray(payload))

Вот шестнадцатеричный дамп содержимого созданного им файла testhex (с Python 2.7.15):

00000000h: D1 01 08 54 02 65 6E 63 39 39 39 39             ; Ñ..T.enc9999
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...