程序读取二进制文件并确定文件类型

时间:2019-02-27 12:02:28

标签: c binary fread

我编写了这段代码,它读取文件二进制文件并确定其文件类型(适用于一些测试文件结尾),适用于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 :(得分:4)

您忘了创建缓冲区unsigned char,因此在这些值上得到了符号扩展名。

显然,内置的魔术签名表也应该是const unsigned char,并且应该通过单个memcmp()调用来进行比较。

答案 1 :(得分:1)

unsigned char上使用buffer(也可以对header使用char来避免问题,如果您的 if (header[i][j] == 0x00) { printf("%s: %s","Found file type",filetype[i]); return 1; } 签名并给出负值(与比较) int 就像0x89的第7位已设置)

PNG也有问题,因为PNG的值为:

  

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

不像其他所有情况一样以0结尾,这是必需的,因为您的算法需要找到0来表示您找到了:

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;
}

只需添加一列,PNG也将设为0。

最后:

print (df)
   Flow  DROP   MEAN
0     1     0  0.025
1     2     1  2.900
2     3     2  2.800
3     4     0  0.020