Программа для чтения двоичного файла и определения типа файла - PullRequest
0 голосов
/ 27 февраля 2019

Я написал этот код, который читает двоичный файл и определяет его тип файла (для нескольких тестовых файлов). Он отлично работает для PDF, MP3, но не для jpg.

В чем проблема?Для jpg строка printf("%s[%d]: %x\n", "Buffer", j, buffer[j]); показывает мне несколько байтов (т.е. ffffff вместо одного байта)

#include <stdio.h>


const int header[6][8] =    { 
                            {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A},
                            {0xFF,0xD8,0x00,0x00,0x00,0x00,0x00,0x00},
                            {0xFF,0xFB,0x00,0x00,0x00,0x00,0x00,0x00},
                            {0x49,0x44,0x33,0x00,0x00,0x00,0x00,0x00},
                            {0x25,0x50,0x44,0x46,0x2D,0x00,0x00,0x00},
                            {0x42,0x4C,0x45,0x4E,0x44,0x45,0x52,0x00} 
                            };

const char* filetype[6] = {"PNG","JPG","MP3","MP3v2","PDF","Blender"};

int main()
{
    FILE *fd;
    char buffer[8];


    if ((fd = fopen("C:\\Users\\***\\Desktop\\Unnamed.jpg", "rb")) == NULL) {
        return -1;
    }

    //fread(buffer, sizeof(char), 8, fd);
    fread(buffer, sizeof(buffer), 1, fd);

    for (int i = 0; i < 6; i++) {
        for(int j = 0; j < 8; j++){
            printf("%s[%d][%d]: %x\n","Header",i,j,header[i][j]);
            printf("%s[%d]: %x\n", "Buffer", j, buffer[j]);

            if (header[i][j] == 0x00) {
                printf("%s: %s","Found file type",filetype[i]);
                return 1;
            }
            if (header[i][j] != buffer[j]) {
                break;
            }
        }
    }
    printf("%s", "Couldn't determine filetype - Not in library");
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Используйте unsigned char для buffer (можно также для header), чтобы избежать проблем, если ваши char подписаны и дают отрицательное значение (вы сравниваете с int , например, 0x89, гдеустановлен бит 7)

У вас также есть проблема для PNG, так как значения для PNG:

{0x89,0x50,0x4E, 0x47,0x0D, 0x0A, 0x1A, 0x0A},

здесь не заканчиваются на 0, как во всех других случаях, это необходимо, потому что ваш алгоритм должен найти 0, чтобы указать, что вы нашли:

        if (header[i][j] == 0x00) {
            printf("%s: %s","Found file type",filetype[i]);
            return 1;
        }

Просто добавьтестолбец также имеет 0 также для PNG.

Наконец:

const unsigned char header[6][9] =    { 
                            {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A, 0x00},
                            {0xFF,0xD8,0x00,0x00,0x00,0x00,0x00,0x00, 0x00},
                            {0xFF,0xFB,0x00,0x00,0x00,0x00,0x00,0x00, 0x00},
                            {0x49,0x44,0x33,0x00,0x00,0x00,0x00,0x00, 0x00},
                            {0x25,0x50,0x44,0x46,0x2D,0x00,0x00,0x00, 0x00},
                            {0x42,0x4C,0x45,0x4E,0x44,0x45,0x52,0x00, 0x00} 
                            };

const char* filetype[6] = {"PNG","JPG","MP3","MP3v2","PDF","Blender"};

int main()
{
    FILE *fd;
    unsigned char buffer[sizeof(header[0])];


    if ((fd = fopen("C:\\Users\\***\\Desktop\\Unnamed.jpg", "rb")) == NULL) {
        return -1;
    }

    fread(buffer, sizeof(buffer), 1, fd);

    for (int i = 0; i < ; i++) {
        for(int j = 0; j < sizeof(header[0]); j++){
            printf("%s[%d][%d]: %x\n","Header",i,j,header[i][j]);
            printf("%s[%d]: %x\n", "Buffer", j, buffer[j]);

            if (header[i][j] == 0x00) {
                printf("%s: %s","Found file type",filetype[i]);
                return 1;
            }
            if (header[i][j] != buffer[j]) {
                break;
            }
        }
    }
    printf("%s", "Couldn't determine filetype - Not in library");
    return 0;
}
0 голосов
/ 27 февраля 2019

Вы забыли сделать свой буфер unsigned char, поэтому вы получаете расширение знака для значений.

Очевидно, что таблица встроенных магических сигнатур тоже должна быть const unsigned char, и сравнениедолжно быть сделано с помощью одного memcmp() вызова.

...