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

标签 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 个字节和 PDF 的前 4 个字节。在上面的代码中,我也在做同样的事情。 CheckFile()PDF 和 Office 2007 格式(包括 .docx.pptx)的情况下返回 TRUE 但在 .doc.ppt 的情况下返回 FALSE.doc 文件的控制台输出为:

FFFFFFD0
FFFFFFCF
11
FFFFFFE0
FFFFFFA1
FFFFFFB1
1A
FFFFFFE1

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

最佳答案

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

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

关于c++ - 通过比较签名无法识别 MS Office 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16815599/

相关文章:

javascript - 如何使用 Javascript 处理上传的文件

c++ - Charm++ 是否支持自适应 MPI 中的设备添加?

c++ - 我怎样才能保留对 move 的东西的引用?

c++ - const void 有什么意义?

c++ - 在模板中, "std::result_of<int&()>"中没有名为 type 的类型

c - 如何在代码不困惑的情况下获取并分析文件中的数据?

c++ - 优化、断言和 Release模式

c# - 有没有办法从锁定的文件中读取数据?

c - 声明一个以 FILE 作为参数的函数原型(prototype)

c - 我应该在这里使用什么格式说明符?