首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用头文件签名(幻数)检查文件类型?

如何使用头文件签名(幻数)检查文件类型?
EN

Stack Overflow用户
提问于 2021-10-13 19:42:57
回答 1查看 573关注 0票数 1

通过输入带有其扩展名的文件,我的代码成功地从“魔术数字”中检测出文件的类型。

代码语言:javascript
运行
复制
magic_numbers = {'png': bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
                 'jpg': bytes([0xFF, 0xD8, 0xFF, 0xE0]),
                 #*********************#
                 'doc': bytes([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1]),
                 'xls': bytes([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1]),
                 'ppt': bytes([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1]),
                 #*********************#
                 'docx': bytes([0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00]),
                 'xlsx': bytes([0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00]),
                 'pptx': bytes([0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00]),
                 #*********************#
                 'pdf': bytes([0x25, 0x50, 0x44, 0x46]),
                 #*********************#
                 'dll': bytes([0x4D, 0x5A, 0x90, 0x00]),
                 'exe': bytes([0x4D, 0x5A]),

                 }

max_read_size = max(len(m) for m in magic_numbers.values()) 
 
with open('file.pdf', 'rb') as fd:
    file_head = fd.read(max_read_size)
 
if file_head.startswith(magic_numbers['pdf']):
    print("It's a PDF File")
else:
    print("It's not a PDF file")

我想知道如何在不指定这部分代码的情况下修改它,也就是说,一旦我生成或输入文件,它就会直接显示文件的类型。

代码语言:javascript
运行
复制
if file_head.startswith(magic_numbers['pdf']):
    print("It's a PDF File")
else:
    print("It's not a PDF file")

我希望你能理解我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-13 21:07:06

你最喜欢的就是遍历循环并测试它们。

您也可以通过使用该扩展来优化或提供一些错误检查。如果先去掉扩展名并进行检查,大部分时间都是成功的,否则您可能不想将"baby.png“作为xlsx文件接受。这将是可疑的,值得犯一个错误。

但是,如果忽略扩展名,只需循环遍历条目:

代码语言:javascript
运行
复制
for ext in magic_numbers:
    if file_head.startswith(magic_numbers[ext]):
        print("It's a {} File".format(ext))

您可能希望将它放在一个返回类型的函数中,这样就可以只返回类型,而不是打印出来。

编辑由于一些共享魔术数字,我们需要假设扩展名是正确的,直到我们知道它不是。我会从文件名中提取扩展名。这可以使用Pathlib或仅使用字符串拆分来完成:

代码语言:javascript
运行
复制
ext = filename.rsplit('.', 1)[-1]

然后专门测试它

代码语言:javascript
运行
复制
if ext in magic_numbers:
    if file_head.startswith(magic_numbers[ext]):
        return ext

把ext测试放在第一位,所以把它们放在一起:

代码语言:javascript
运行
复制
ext = filename.rsplit('.', 1)[-1]
if ext in magic_numbers:
    if file_head.startswith(magic_numbers[ext]):
        return ext

for ext in magic_numbers:
    if file_head.startswith(magic_numbers[ext]):
        return ext

return nil
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69561458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档