通过比较签名无法识别MS Office文件

时间:2013-05-29 13:44:09

标签: c++ file

我需要检查文件是.doc.ppt.pdf还是其他任何文件。我写了以下代码:

bool CheckFile(string path)
{
    char * sig;
    sig = new char[8];
    ifstream myfile;
    myfile.open(path.c_str(), ios::in | ios::binary);
    if (myfile.fail())
    {
        MessageBox(0,"File Not Opened","ERROR",MB_OK);
        break;
    }
    myfile.read(sig,8);

    //docx, pptx, xlsx
    if ((sig[0] == (0x50))&&(sig[1] == (0x4B))&&(sig[2] == (0x03))&&(sig[3] == (0x04))&&(sig[4] == (0x14))&&(sig[5] == (0x00))&&(sig[6] == (0x06))&&(sig[7] == (0x00)))
    {
        return true;
    }

    //doc, ppt, xls
    if ((sig[0] == (0xD0))&&(sig[1] == (0xCF))&&(sig[2] == (0x11))&&(sig[3] == (0xE0))&&(sig[4] == (0xA1))&&(sig[5] == (0xB1))&&(sig[6] == (0x1A))&&(sig[7] == (0xE1)))
    {
        return true;
    }

    //pdf
    if ((sig[0] == (0x25))&&(sig[1] == (0x50))&&(sig[2] == (0x44))&&(sig[3] == (0x46)))
    {
        return true;
    }
    delete sig;
    myfile.close();
    return false;
}

我在互联网上查找并发现我们可以比较签名,即MS Office文件的前8个字节和PDFs的前4个字节。在上面的代码中,我也是这样做的。如果CheckFile()和Office 2007格式包括TRUEPDFs,则.docx会返回.pptx,如果FALSE,则会返回.doc.ppt。 a .doc文件的控制台输出是:

FFFFFFD0
FFFFFFCF
11
FFFFFFE0
FFFFFFA1
FFFFFFB1
1A
FFFFFFE1

其中每一行对应于sig中的char的十六进制。请注意,最后一个字节与.doc文件的签名相同。我不知道为什么这些额外的FFFFFF存在于此。可能是什么问题??

1 个答案:

答案 0 :(得分:1)

对于FFFFFFFF的问题,您可能会注意到这些数字的最后一个字节大于0x7f,这意味着它们对于有符号字节是负数。因此,您使用带符号的char,编译器在打印值时对其进行符号扩展。

您应该更改为unsigned char(甚至更好,标准类型uint8_t)。