檔案簽章檢查
在你的瀏覽器裡讀取檔案開頭的位元組,判斷它真正的格式,而不是副檔名宣稱的格式。附完整的 magic number 對照表。
在你的瀏覽器中執行
或把檔案拖進來
- 檔案
- —
- 大小
- —
- 瀏覽器猜的類型
- —
- 實際格式
- —
- 同時符合
- —
這是一種容器格式。位元組認出來的是外層包裝,不是裡面的東西——.docx、.jar 與 .epub 都是 ZIP,前四個位元組完全一樣。
開頭位元組
| 位移 | 十六進位 | ASCII |
|---|
檔案簽章對照表
| 格式 | 簽章 | 副檔名 | MIME 類型 |
|---|---|---|---|
| PNG | 89 50 4E 47 0D 0A 1A 0A | .png | image/png |
| JPEG | FF D8 FF | .jpg .jpeg | image/jpeg |
| GIF (87a) | 47 49 46 38 37 61 | .gif | image/gif |
| GIF (89a) | 47 49 46 38 39 61 | .gif | image/gif |
| BMP | 42 4D | .bmp | image/bmp |
| WebP | 52 49 46 46 · 8: 57 45 42 50 | .webp | image/webp |
| TIFF (little-endian) | 49 49 2A 00 | .tif .tiff | image/tiff |
| TIFF (big-endian) | 4D 4D 00 2A | .tif .tiff | image/tiff |
| Photoshop | 38 42 50 53 | .psd | image/vnd.adobe.photoshop |
| Windows icon | 00 00 01 00 | .ico | image/x-icon |
| Windows cursor | 00 00 02 00 | .cur | image/x-icon |
| HEIC | 4: 66 74 79 70 · 8: 68 65 69 63 | .heic | image/heic |
| AVIF | 4: 66 74 79 70 · 8: 61 76 69 66 | .avif | image/avif |
| SVG | 3C 3F 78 6D 6C | .svg | image/svg+xml |
| WAV | 52 49 46 46 · 8: 57 41 56 45 | .wav | audio/wav |
| AVI | 52 49 46 46 · 8: 41 56 49 20 | .avi | video/x-msvideo |
| MP3 with ID3 tag | 49 44 33 | .mp3 | audio/mpeg |
| FLAC | 66 4C 61 43 | .flac | audio/flac |
| Ogg容器 | 4F 67 67 53 | .ogg .oga .opus | application/ogg |
| MP4容器 | 4: 66 74 79 70 | .mp4 .m4a .m4v | video/mp4 |
| Matroska / WebM容器 | 1A 45 DF A3 | .mkv .webm | video/x-matroska |
25 50 44 46 2D | application/pdf | ||
| RTF | 7B 5C 72 74 66 | .rtf | application/rtf |
| Legacy Office (.doc, .xls, .ppt)容器 | D0 CF 11 E0 A1 B1 1A E1 | .doc .xls .ppt .msi | application/x-ole-storage |
| PostScript | 25 21 | .ps .eps | application/postscript |
| ZIP (and .docx, .xlsx, .jar, .apk, .epub, .odt)容器 | 50 4B 03 04 | .zip .docx .xlsx .pptx .jar .apk .epub .odt | application/zip |
| ZIP (empty archive) | 50 4B 05 06 | .zip | application/zip |
| gzip容器 | 1F 8B | .gz .tgz | application/gzip |
| bzip2 | 42 5A 68 | .bz2 | application/x-bzip2 |
| xz | FD 37 7A 58 5A 00 | .xz | application/x-xz |
| Zstandard | 28 B5 2F FD | .zst | application/zstd |
| 7-Zip | 37 7A BC AF 27 1C | .7z | application/x-7z-compressed |
| RAR (1.5–4.x) | 52 61 72 21 1A 07 00 | .rar | application/vnd.rar |
| RAR (5.0+) | 52 61 72 21 1A 07 01 00 | .rar | application/vnd.rar |
| tar (POSIX)容器 | 257: 75 73 74 61 72 | .tar | application/x-tar |
| Debian package / ar archive容器 | 21 3C 61 72 63 68 3E | .deb .a | application/vnd.debian.binary-package |
| ELF (Linux executable) | 7F 45 4C 46 | — | application/x-elf |
| DOS / Windows executable | 4D 5A | .exe .dll | application/vnd.microsoft.portable-executable |
| Mach-O 64-bit | CF FA ED FE | — | application/x-mach-binary |
| Java class — or a Mach-O universal binary | CA FE BA BE | .class | application/java-vm |
| WebAssembly | 00 61 73 6D | .wasm | application/wasm |
| Script with a shebang | 23 21 | .sh .py .pl | text/x-shellscript |
| SQLite database | 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 | .sqlite .db | application/vnd.sqlite3 |
| WOFF font | 77 4F 46 46 | .woff | font/woff |
| WOFF2 font | 77 4F 46 32 | .woff2 | font/woff2 |
| OpenType font | 4F 54 54 4F | .otf | font/otf |
| TrueType font | 00 01 00 00 00 | .ttf | font/ttf |
| Text with a UTF-8 byte order mark | EF BB BF | .txt | text/plain |
| Text with a UTF-16 LE byte order mark | FF FE | .txt | text/plain |
| Text with a UTF-16 BE byte order mark | FE FF | .txt | text/plain |
只讀取開頭 512 個位元組,而且是在你的瀏覽器裡讀的。沒有任何東西被上傳。
副檔名是說法,位元組才是證據
檔名結尾是 .jpg,只說明了有人決定這樣叫它,完全沒有說裡面是什麼。開頭那幾個位元組通常會說:
大多數二進位格式的開頭都是一段固定的樣式,也就是 magic number,放在那裡的用意正是讓程式
不必相信檔名就能認出檔案。
把檔案拖到上面,這個頁面會讀開頭 512 個位元組,告訴你它們說了什麼。它不會多讀,也不會把任何東西 送出去——這正是重點,因為你會想查一個檔案的類型,通常就是因為你不信任它。
不一致代表什麼,不代表什麼
副檔名與位元組不一致時,頁面會直說。無害的常見原因:
- 有人把
.png改名成.jpg,好通過上傳限制。 - 下載時伺服器送錯
Content-Type,存下來的副檔名就跟著錯。 - 檔案其實是
.docx,而.docx本來就是 ZIP。位元組沒錯,是預期錯了。
比較不無害的原因:披著圖片副檔名的腳本或執行檔,或者刻意做成同時是兩種合法格式的 polyglot 檔案。 不一致是「值得看一下」的理由,不是判決。
而相符能證明的,比看起來少得多。 magic number 就只是開頭那幾個位元組。一個檔案可以用 %PDF-
開頭,而其餘幾乎全是別的東西。簽章檢查是一道快速的篩子,不是驗證器。
最容易搞錯的幾個情況
PK 不等於「一個 ZIP 檔」
50 4B 03 04——PK 加兩個控制位元組,取自 Phil Katz——是每一個 ZIP 壓縮檔的開頭。它同時也是
每一個 .docx、.xlsx、.pptx、.odt、.jar、.apk、.epub 的開頭,因為這些本來就是
ZIP,只是內部有約定好的結構。再怎麼讀開頭的位元組都分不出來,只能把壓縮檔打開看裡面有什麼。
RIFF 與 ftyp 要看第二段
有些格式先放一個通用的容器標記,真正的格式在後面幾個位元組:
| 位移 0 | 位移 8 | 格式 |
|---|---|---|
RIFF | WEBP | WebP |
RIFF | WAVE | WAV |
RIFF | AVI | AVI |
ISO base media 也一樣:ftyp 在位移 4,品牌代碼在 8——所以 MP4、MOV、HEIC、AVIF 的前四個
位元組完全相同。任何「一個格式一個樣式」的對照表在這裡都會出錯。
CA FE BA BE 是兩種東西
它是 Java .class 檔的 magic number,1991 年選它是因為那是一個唸得出來的十六進位單字。它同時
也是 macOS 上 Mach-O universal binary 的 magic number。兩個都對;只挑一個講的工具是在猜。
tar 的簽章在第 257 個位元組
ustar 出現在位移 257,不在開頭,因為 tar 比「把標頭放在檔案最前面」這個慣例還早。只讀前十六個
位元組的話,每一個 tar 檔都會認不出來。
根本沒有簽章的格式
純文字、CSV、JSON、HTML、JavaScript、Markdown、大部分原始碼——一個都沒有,因為它們從來不是設計成 讓機器讀四個位元組就認出來的。頁面說「沒有已知的檔案簽章」時,那往往是正確答案,不是失敗。
例外是 byte order mark:文字檔開頭的 EF BB BF 是 UTF-8 BOM,也是 CSV 偶爾在第一格多出
 的原因。
相關
全部在你的瀏覽器裡完成。若要驗證檔案的內容而不是類型, 雜湊產生器用同樣的方式做指紋。