Skip to content

Instantly share code, notes, and snippets.

@alzobnin
Last active March 25, 2021 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alzobnin/5fb9f978cdfb0673efcaa2c2e9c809e2 to your computer and use it in GitHub Desktop.
Save alzobnin/5fb9f978cdfb0673efcaa2c2e9c809e2 to your computer and use it in GitHub Desktop.

Разбор задачи «Magic bytes»

Условие

Многие типы файлов можно определить по наличию определенных байтов в их начале. Например, все pdf-файлы начинаются с байтов 25 50 44 46 в шестнадцатеричной нотации (это коды символов "%PDF"). Все jpg-файлы начинаются с байтов FF D8 FF. А все файлы zip-архивов начинаются с байтов 50 4B.

Напишите функцию со следующим заголовком:

std::string DetectType(const unsigned char* data, size_t size);

Этой функции будет передан на вход указатель на начало блока байтов в памяти и размер блока. Это содержимое некоторого файла. Функция должна проверить несколько первых байтов в этом блоке и вернуть одну из следующих строк: "pdf", "jpg", "zip" или "other" (если файл не похож на три предыдущих формата).

Сдайте в систему только код функции DetectType без функции main. Не забудьте подключить библиотеку string и все другие библиотеки, которые вам понадобятся.

Решение

Самое главное в этой задаче — аккуратно убедиться, что размер блока достаточный.

Ещё важно понимать, что байты можно записывать прямо в шестнадцатеричной нотации, не пытаясь приводить их к символам или в десятичную систему.

#include <string>

std::string DetectType(const unsigned char* data, size_t size) {
    if (size >= 2 && data[0] == 0x50 && data[1] == 0x4B)
        return "zip";
    else if (size >= 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF)
        return "jpg";
    else if (size >= 4 && std::string(data, data + 4) == "%PDF")  // можно было бы проверить 4 байта по отдельности, но так короче
        return "pdf";
    else
        return "other";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment