如何通过文件头签名(魔数)实现无需手动指定的自动文件类型检测
实现思路
- 无需硬编码指定待校验的文件类型,改为遍历内置的所有魔数规则逐一匹配
- 支持从命令行传入待检测的文件路径,不需要修改代码就能检测不同文件
- 对同魔数的多类文件,会返回所有匹配的候选类型列表
完整实现代码
import sys # 魔数配置可自行扩展 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()) def get_file_type(file_path): try: with open(file_path, 'rb') as fd: file_head = fd.read(max_read_size) except Exception as e: return f"读取文件失败:{str(e)}" matched_types = [] for ext, magic in magic_numbers.items(): if file_head.startswith(magic): matched_types.append(ext) if matched_types: return f"匹配到的文件类型:{', '.join(matched_types)}" else: return "未知文件类型" if __name__ == "__main__": if len(sys.argv) < 2: print("使用方式:python 脚本名.py 待检测文件路径") sys.exit(1) print(get_file_type(sys.argv[1]))
使用方式
- 保存代码为
file_type_detector.py - 命令行执行:
python file_type_detector.py 你要检测的文件路径 - 执行后会直接输出匹配的文件类型
说明
- doc/xls/ppt、docx/xlsx/pptx的魔数完全一致,仅通过魔数无法区分具体类型,若需要精确识别需要额外解析文件内部结构
- 可自行在
magic_numbers字典中新增其他文件类型的魔数规则,扩展支持的检测范围
内容的提问来源于stack exchange,提问作者Alya Mad
相关产品推荐
相关产品推荐

