Python: редактировать определенные шестнадцатеричные значения в файле - PullRequest
2 голосов
/ 01 октября 2019

Я пытаюсь отредактировать определенную строку данных в файле .m4a (аудиофайл), но я не могу найти способ сделать это в python. Я знаю, что есть другие подобные потоки, но когда я открываю файл .m4a в программе шестнадцатеричного редактора (например, HxD), он дает мне другие шестнадцатеричные данные, чем те, что я получаю из своего скрипта на python. Я немного смущен терминологией. Что мне нужно сделать, так это прочитать файл с помощью python и преобразовать его в формат, который использует мой шестнадцатеричный редактор, заменить данные, затем преобразовать их обратно и записать в файл. Я действительно не знаю, возможно ли это или есть более простой способ сделать это. Я все еще новичок в Python, поэтому я все еще учусь. Мне действительно нужен кто-то, чтобы указать мне правильное направление. Причина этого связана с метаданными файла, которые я пытаюсь изменить.

Моя версия Python: Python 3.7.4

Вот ссылка на рассматриваемый файл: https://drive.google.com/file/d/1m8SpCLSyX265_I00MFT1IyltpTAvxntF/view?usp=sharing

Мой код:

with open(file, 'rb') as f:
    content = f.read().hex()
print(content)

Ниже приведена строка, которую мне нужно отредактировать (из моего шестнадцатеричного редактора)

00 00 01 80 68 69 33 32

(перевод текста: ����hi32)

заменить на:

00 00 00 00 68 69 33 32

Начало моего файла в шестнадцатеричном редакторе выглядит так (HxD):

00 00 00 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 01 0C 60 6D 64 69 61 00 00 00 20 6D 64 68 64 00 00 00 00 D9 98 96 40 D9 B2 F7 52 00 00 AC 44 00 84 EC 00 00 00 00 00 00 00 00 22 68 64 6C 72 00 00 00 00 00 00 00 00 73 6F 75 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 0C 16 6D 69 6E 66 00 00 00 10 73 6D 68 64 00 00 00 00 00 00 00 00 00 00 00 24 64 69 6E 66 00 00 00 1C 64 72 65 66 00 00 00 00 00 00 00 01 00 00 00 0C 75 72 6C 20 00 00 00 01 00 01 0B DA 73 74 62 6C 00 00 80 76 73 74 73 64 00 00 00 00 00 00 00 01 00 00 80 66 6D 70 34 61 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 02 00 10 00 00 00 00 AC 44 00 00 00 00 00 33 65 73 64 73 00 00 00 00 03 80 80 80 22 00 00 00 04 80 80 80 14 40 15 00 18 00 00 04 82 90 00 03 E8 00 05 80 80 80 02 12 10 06 80 80 80 01 02 00 00 00

Началоhex, который я получаю из своего скрипта Python, выглядит так:

d5df0d0ef02daf279fd6b15fae5c6e0bc79bec22095ceeada5e77371afc8ee36f10773b1b2c06b1b1ee4e5cccbf67403b26fd37cc6e3cc9f11019ab604f0071872ec6c092cc20b2a6d4460c55986623b50

1 Ответ

1 голос
/ 02 октября 2019

Различия в чтении в шестнадцатеричном формате

Когда я открываю файл .m4a в программе шестнадцатеричного редактора (например, HxD), он дает мне другие шестнадцатеричные данные, чем те, что я получаю из своего скрипта Python.

Чтение с Python

Это то, что я вижу в Python, показывая первые 32 символа:

with open('01 Choir (Remix).m4a', 'rb') as f:
    content = f.read().hex()
print(content[:32])
00000020667479704d34412000000000

Чтение с xxd

Использование bash, снова выбирая первые 32 символа:

$ xxd -ps 01\ Choir\ \(Remix\).m4a | head -c 32
00000020667479704d34412000000000

Здесь xxd -ps получает шестнадцатеричную строку файла, а head получает первые 32 символа этого вывода.

Обратите внимание, что они одинаковыhex.

Переписывание Hex

Следующая строка, которую мне нужно отредактировать (из моего редактора hex)

0000018068693332

заменить на:

0000000068693332

У вас была половина решения - просто замените строку и перепишите в файл. Имейте в виду, что хотя библиотека регулярных выражений Python, re , более мощная, она также не является необходимой, поскольку все, что вам нужно сделать, - это заменить строку. А замена строк на на порядок быстрее , чем при использовании регулярных выражений.

Если вам нужно использовать регулярное выражение, существует множество способов Редактировать Hex .

# replace_bytes.py
source_str = '0000018068693332'
replace_str = '0000000068693332'

with open('01 Choir (Remix).m4a', 'rb') as f:
    content = f.read().hex()
print(source_str + " in `01 Choir (Remix).m4a`:       ", source_str in content)
content = content.replace(source_str, replace_str)
with open('01 Choir (Remix) edited.m4a', 'wb') as f:
    f.write(bytes.fromhex(content))

with open('01 Choir (Remix) edited.m4a', 'rb') as f:
    new_content = f.read().hex()
print(source_str + " in `01 Choir (Remix) edited.m4a`:", source_str in new_content)

Затем запустите его:

$ python replace_bytes.py
0000018068693332 in `01 Choir (Remix).m4a`:        True
0000018068693332 in `01 Choir (Remix) edited.m4a`: False
...