Как использовать волшебные байты для идентификации файлов с помощью python

#python #file #byte

#python #файл #байт

Вопрос:

Мне была задана проблема, в которой говорилось:

Мы извлекли один из чужих zip-файлов, это набор файлов PNG, но мы думаем, что только один из них допустим. Используйте magic byte, чтобы определить, что это такое. Совет: Найдите и прочитайте правильный файл, чтобы получить флаг.

Все файлы png хранятся в каталоге /tmp. После пары попыток решить проблему я пока только добрался. Мой код работает нормально, но печатает no для каждого файла, ни один из которых не является правильным в соответствии с моим кодом.

Вот мой код на данный момент:

 import glob,os

magic_numbers = {'.png': bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])}
max_read_size = max(len(m) for m in magic_numbers.values()) # get max size of magic numbers of the dict
os.chdir("/tmp")
for x in glob.glob("*.png"):
    with open(x, 'rb') as fd:
            file_head = fd.read(max_read_size)

    if file_head.startswith(magic_numbers['.png']):
            print("It's a PNG File")
    else:
            print("no")
  

Очевидно, что я делаю что-то не так, но я не могу понять, что это. Это проблема с циклом? Как я должен использовать magic bytes для идентификации файлов?

Комментарии:

1. pypi.org/project/filemagic

2. Ваш код работает для меня. Я создал tmp папку с несколькими файлами png в ней, плюс созданный мной текстовый файл (который я переименовал в .png), и ваш код правильно идентифицировал все файлы. (Я использую python 3.7)

3. Эй, приятель, возможно, для тебя уже слишком поздно … но проблема не в логике, которую ты здесь использовал. Вы ожидаете, что вопрос будет более сложным, чем он есть на самом деле. Просто сбросьте заголовки и посмотрите на них.

4. Это проблема домашнего задания?

5. @jtlz2 нет, это не так, не волнуйтесь

Ответ №1:

Ваш код нуждался в небольшой доработке. Добавляя к слову png точку, вы создаете впечатление, что файл имеет расширение. Кроме того, выполните печать file_head . Запустите это:

 import glob, os

magic_numbers = {'png': bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])}
max_read_size = max(len(m) for m in magic_numbers.values()) # get max size of magic numbers of the dict
os.chdir("/tmp")

for x in glob.glob("*png"):
    with open(x, 'rb') as fd:
        file_head = fd.read()
        print(file_head)

    if file_head.startswith(magic_numbers['png']):
        print("It's a PNG File")
    else:
        print("no")
  

Он должен напечатать что-то вроде этого:

 b'x89PNGrnx1anx00x00x00rIHDRx00x00x00x01x00x00x00x01x08x06x00x00x00x1fx15xc4x89x00x00x00nIDATxx9ccx00x01x00x00x05x00x01rn-xb4x00x00x00x00IENDxaeB`x82The flag is: 2NECGNQM4GD3QPD' It's a PNG File
  

Ваш флаг, вероятно, будет отличаться от моего.

Приветствия!

Ответ №2:

вы можете использовать библиотеку python-magic.

python-magic — это интерфейс Python к библиотеке идентификации типов файлов libmagic. libmagic определяет типы файлов, проверяя их заголовки в соответствии с предопределенным списком типов файлов. (из pypi)

эта библиотека использует только магические числа для идентификации типа файла.

 import magic
print(magic.from_file('file.png'))
  

и вывод такой:

 'PNG image data, 2480 x 3437, 8-bit/color RGB, non-interlaced'
  

получайте удовольствие!