File signature checker
Reads the first bytes of a file in your browser and tells you the actual format, not the one the extension claims. Includes a reference table of magic numbers.
Runs in your browser
or drop one here
- File
- —
- Size
- —
- Type the browser guessed
- —
- Actual format
- —
- Also matches
- —
This is a container format. The bytes identify the wrapper, not what is inside it — a .docx, a .jar and an .epub are all ZIP files and are identical for the first four bytes.
First bytes
| Offset | Hex | ASCII |
|---|
Signature reference
| Format | Signature | Extensions | MIME type |
|---|---|---|---|
| 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 |
| Oggcontainer | 4F 67 67 53 | .ogg .oga .opus | application/ogg |
| MP4container | 4: 66 74 79 70 | .mp4 .m4a .m4v | video/mp4 |
| Matroska / WebMcontainer | 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)container | 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)container | 50 4B 03 04 | .zip .docx .xlsx .pptx .jar .apk .epub .odt | application/zip |
| ZIP (empty archive) | 50 4B 05 06 | .zip | application/zip |
| gzipcontainer | 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)container | 257: 75 73 74 61 72 | .tar | application/x-tar |
| Debian package / ar archivecontainer | 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 |
Only the first 512 bytes are read, and they are read in your browser. Nothing is uploaded.
The extension is a claim; the bytes are the evidence
A filename ending in .jpg tells you what somebody decided to call the file. It tells you
nothing about what is in it. The first few bytes usually do — most binary formats begin with a
fixed pattern, the magic number, put there precisely so a program can recognise the file
without trusting its name.
Drop a file above and the page reads the first 512 bytes and tells you what they say. It never reads more than that, and it never sends anything anywhere — which is the point, because the usual reason to check a file’s type is that you do not trust it.
What a mismatch means, and what it does not
If the extension and the bytes disagree, the page says so. Common innocent causes:
- Someone renamed a
.pngto.jpgto get past an upload filter. - A download was saved with the wrong extension because the server sent the wrong
Content-Type. - The file is a
.docx, and.docxfiles are ZIP archives. The bytes are right, the expectation was wrong.
Common less innocent causes: a script or executable wearing an image extension, or a polyglot file crafted to be valid as two formats at once. A mismatch is a reason to look, not a verdict.
A match proves less than it looks like it does. The magic number is the first few bytes and
nothing else. A file can start with %PDF- and be almost entirely something else. Signature
checking is a fast filter, not a validator.
The cases that catch people out
PK is not “a ZIP file”
50 4B 03 04 — PK followed by two control bytes, after Phil Katz — is the start of every ZIP
archive. It is also the start of every .docx, .xlsx, .pptx, .odt, .jar, .apk and
.epub, because all of them are ZIP archives with an agreed layout inside. No amount of
reading the first bytes will separate them; you have to open the archive and look at what is in
it.
RIFF and ftyp need a second look
Some formats put a generic container marker first and the actual format a few bytes later:
| Bytes at 0 | Bytes at 8 | Format |
|---|---|---|
RIFF | WEBP | WebP |
RIFF | WAVE | WAV |
RIFF | AVI | AVI |
ISO base media does the same with ftyp at offset 4 and a brand at 8 — which is why MP4,
MOV, HEIC and AVIF all look identical for the first four bytes. Any table with one pattern per
format gets these wrong.
CA FE BA BE is two things
It is the magic number of a Java .class file, chosen in 1991 because it is a pronounceable
hexadecimal word. It is also the magic number of a Mach-O universal binary on macOS. Both are
correct; a tool that picks one is guessing.
tar has its signature 257 bytes in
ustar appears at offset 257, not at the start, because tar predates the convention of putting
a header at the front of the file. Read only the first sixteen bytes and every tar file is
unidentifiable.
Formats with no signature at all
Plain text, CSV, JSON, HTML, JavaScript, Markdown, most source code — none of them have one, because they were never designed to be recognised by a machine reading four bytes. If the page says “no known signature”, that is often the correct answer rather than a failure.
The exception is a byte order mark: EF BB BF at the start of a text file is a UTF-8 BOM,
and it is the reason a CSV occasionally opens with a stray  in the first cell.
Related
Everything happens in your browser. If you want to check a file’s contents rather than its type, the hash generator fingerprints it the same way.