文件魔数(File Magic Number)
文件魔数(Magic Number)是文件开头若干字节中固定的标识序列,用于区分文件类型。文件系统、加载器、标准库通过读取这些魔数来判断文件格式,而不是依赖文件扩展名。
常见的文件魔数
| 文件类型 | 魔数(十六进制) | 魔数(ASCII) | 说明 |
|---|---|---|---|
| JPEG | FF D8 FF | ÿØÿ | JPEG 图像文件开头固定为 FF D8 FF |
| PNG | 89 50 4E 47 0D 0A 1A 0A | .PNG.... | PNG 图像,第 2-4 字节为 PNG |
| GIF | 47 49 46 38 39(37) 61 | GIF89a / GIF87a | GIF 图像,分为 89a 和 87a 两个版本 |
| WebP | 52 49 46 46 .... 57 45 42 50 | RIFF....WEBP | WebP 图像基于 RIFF 容器格式 |
| BMP | 42 4D | BM | Windows 位图文件 |
| ICO | 00 00 01 00 | .... | Windows 图标文件 |
25 50 44 46 | %PDF | PDF 文档,开头为 %PDF | |
| ZIP | 50 4B 03 04 | PK\x03\x04 | ZIP 压缩包,PK 为 Phil Katz 缩写 |
| ZIP(空加密) | 50 4B 05 06 | PK\x05\x06 | ZIP 空目录/加密文件尾 |
| GZip | 1F 8B | .. | GZip 压缩文件 |
| 7z | 37 7A BC AF 27 1C | 7z..' | 7-Zip 压缩文件,开头为 7z |
| RAR | 52 61 72 21 1A 07 00 | Rar!... | RAR 压缩文件,开头为 Rar! |
| tar | — | 无固定魔数 | tar 没有全局魔数,但可通过内部块结构识别 |
| ELF | 7F 45 4C 46 | .ELF | Linux / Unix 可执行文件 |
| PE (exe/dll) | 4D 5A | MZ | Windows 可执行文件(Mark Zbikowski 缩写) |
| Mach-O | FE ED FA CE / CE FA ED FE | .... | macOS 可执行文件(Fat Binary) |
| Mach-O(64位) | FE ED FA CF / CF FA ED FE | .... | macOS 64 位可执行文件 |
| Java Class | CA FE BA BE | CAFEBABE | Java 编译后的 Class 文件 |
| Java JAR | 50 4B 03 04 | PK\x03\x04 | JAR 本质是 ZIP 格式,魔数同 ZIP |
| MP3 (ID3v2) | 49 44 33 | ID3 | MP3 文件含 ID3v2 标签时以此为开头 |
| MP3 (无标签) | FF FB / FF F3 / FF F2 | .. | MPEG 音频帧同步头 |
| MP4 | 00 00 00 18 66 74 79 70 | ....ftyp | MP4 基于 ISO Base Media File Format |
| AVI | 52 49 46 46 .... 41 56 49 20 | RIFF....AVI | AVI 基于 RIFF 容器格式 |
| TIFF | 49 49 2A 00 / 4D 4D 00 2A | II*\0 / MM\0* | TIFF 图像(Intel/Byte Order 两版本) |
| WASM | 00 61 73 6D | \0asm | WebAssembly 二进制格式 |
| SQLite | 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 | SQLite format 3\0 | SQLite 数据库文件 |
为什么需要魔数
- 类型识别 — 系统无需依赖易被修改的扩展名,直接读取文件头即可识别类型
- 错误检测 — 文件损坏时通常魔数先损坏,可快速判断文件是否有效
- 安全校验 — 防止文件伪装攻击(如将 exe 改为 .jpg)
魔数在开发中的应用
Linux file 命令
bash
file example.png
# example.png: PNG image data, 800 x 600, 8-bit/color RGBA, non-interlacedfile 命令读取文件开头的魔数来识别类型,而非扩展名。
Java Class 文件校验
JVM 加载 .class 文件时,首先检查前 4 字节是否为 CA FE BA BE(咖啡宝贝),否则拒绝加载。
java
public class MagicNumberCheck {
public static boolean isValidClassFile(byte[] data) {
return data.length >= 4
&& data[0] == (byte)0xCA
&& data[1] == (byte)0xFE
&& data[2] == (byte)0xBA
&& data[3] == (byte)0xBE;
}
}Web 开发中判断文件类型
javascript
function detectFileType(buffer) {
const uint8 = new Uint8Array(buffer);
if (uint8[0] === 0x89 && uint8[1] === 0x50 && uint8[2] === 0x4E && uint8[3] === 0x47)
return 'image/png';
if (uint8[0] === 0xFF && uint8[1] === 0xD8 && uint8[2] === 0xFF)
return 'image/jpeg';
if (uint8[0] === 0x47 && uint8[1] === 0x49 && uint8[2] === 0x46)
return 'image/gif';
if (uint8[0] === 0x25 && uint8[1] === 0x50 && uint8[2] === 0x44 && uint8[3] === 0x46)
return 'application/pdf';
return 'unknown';
}参考资料
- File format - Magic number (Wikipedia)
- List of file signatures (Wikipedia)
file命令的魔数数据库:/usr/share/misc/magic