A reference of the leading-byte signatures (magic bytes) that identify file formats. Useful for type detection and upload validation.
What are magic bytes?
Most file formats include a fixed byte sequence at the start of the file — the "magic bytes" or "file signature". The OS and applications use this to detect file type. File extensions are easy to spoof; magic bytes are a reliable binary-level identifier, making them essential for trustworthy upload validation.
Linux's file command and PHP's finfo class detect MIME types using this mechanism.
Image files
| Format | Extension | Magic bytes (hex) | ASCII | Offset |
| PNG | .png | 89 50 4E 47 0D 0A 1A 0A | ‰PNG\r\n\x1a\n | 0 |
| JPEG | .jpg/.jpeg | FF D8 FF | — | 0 |
| GIF87a | .gif | 47 49 46 38 37 61 | GIF87a | 0 |
| GIF89a | .gif | 47 49 46 38 39 61 | GIF89a | 0 |
| WebP | .webp | 52 49 46 46 ?? ?? ?? ?? 57 45 42 50 | RIFF????WEBP | 0 |
| BMP | .bmp | 42 4D | BM | 0 |
| TIFF (little-endian) | .tiff/.tif | 49 49 2A 00 | II*\0 | 0 |
| TIFF (big-endian) | .tiff/.tif | 4D 4D 00 2A | MM\0* | 0 |
| AVIF / HEIF | .avif/.heif | 66 74 79 70 | ftyp | 4 |
| ICO | .ico | 00 00 01 00 | — | 0 |
| SVG | .svg | <?xml or <svg | text | 0 (no BOM) |
Documents & archives
| Format | Extension | Magic bytes (hex) | Notes |
| PDF | .pdf | 25 50 44 46 2D | %PDF- |
| ZIP | .zip | 50 4B 03 04 | PK\x03\x04 |
| ZIP (empty) | .zip | 50 4B 05 06 | — |
| GZIP | .gz | 1F 8B | — |
| 7-Zip | .7z | 37 7A BC AF 27 1C | 7z\xBC\xAF'\x1C |
| RAR4 | .rar | 52 61 72 21 1A 07 00 | Rar!\x1A\x07\x00 |
| RAR5 | .rar | 52 61 72 21 1A 07 01 00 | — |
| TAR | .tar | 75 73 74 61 72 | ustar (offset 257) |
| DOCX / XLSX / PPTX | .docx etc. | 50 4B 03 04 | ZIP-based (distinguished by extension) |
| XLS (legacy) | .xls | D0 CF 11 E0 A1 B1 1A E1 | OLE2 container |
| DOC (legacy) | .doc | D0 CF 11 E0 A1 B1 1A E1 | OLE2 container |
Text & data formats
| Format | Extension | Magic bytes / BOM | Notes |
| UTF-8 with BOM | .txt/.csv etc. | EF BB BF | Byte Order Mark |
| UTF-16 LE BOM | .txt etc. | FF FE | Little-endian |
| UTF-16 BE BOM | .txt etc. | FE FF | Big-endian |
| UTF-32 LE BOM | .txt etc. | FF FE 00 00 | — |
| JSON (typical) | .json | 7B or 5B | { or [ |
| CSV (typical) | .csv | plain text (no BOM) | No signature |
| XML | .xml | 3C 3F 78 6D 6C | <?xml |
Audio & video
| Format | Extension | Magic bytes (hex) | Notes |
| MP3 | .mp3 | FF FB / FF F3 / FF F2 | Or ID3 tag: 49 44 33 |
| MP4 / M4A / M4V | .mp4 etc. | 66 74 79 70 | ftyp (offset 4) |
| WAV | .wav | 52 49 46 46 ?? ?? ?? ?? 57 41 56 45 | RIFF????WAVE |
| OGG | .ogg/.ogv | 4F 67 67 53 | OggS |
| FLAC | .flac | 66 4C 61 43 | fLaC |
| AVI | .avi | 52 49 46 46 ?? ?? ?? ?? 41 56 49 20 | RIFF????AVI |
| MKV / WebM | .mkv/.webm | 1A 45 DF A3 | EBML header |
Executables & other
| Format | Extension | Magic bytes (hex) | Notes |
| ELF (Linux executable) | none/.elf | 7F 45 4C 46 | \x7FELF |
| PE (Windows executable) | .exe/.dll | 4D 5A | MZ |
| Mach-O (macOS executable) | none | CF FA ED FE | 64-bit |
| PHP script | .php | 3C 3F 70 68 70 | <?php |
| SQLite | .sqlite/.db | 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 | SQLite format 3\0 |
| ISO | .iso | 43 44 30 30 31 | Offset 32769: CD001 |
Magic byte validation in PHP
['offset' => 0, 'bytes' => "\x89PNG\r\n\x1a\n", 'length' => 8],
'jpg' => ['offset' => 0, 'bytes' => "\xFF\xD8\xFF", 'length' => 3],
'gif' => ['offset' => 0, 'bytes' => "GIF8", 'length' => 4],
'pdf' => ['offset' => 0, 'bytes' => "%PDF-", 'length' => 5],
'zip' => ['offset' => 0, 'bytes' => "PK\x03\x04", 'length' => 4],
'exe' => ['offset' => 0, 'bytes' => "MZ", 'length' => 2],
];
if (!isset($signatures[$expectedType])) {
throw new \InvalidArgumentException("Unknown file type: $expectedType");
}
$sig = $signatures[$expectedType];
$handle = fopen($filePath, 'rb');
if ($sig['offset'] > 0) fseek($handle, $sig['offset']);
$header = fread($handle, $sig['length']);
fclose($handle);
if (substr($header, 0, $sig['length']) !== $sig['bytes']) {
throw new \RuntimeException("Magic bytes do not match (expected: $expectedType)");
}
}
// Usage
validateMagicBytes($_FILES['upload']['tmp_name'], 'png');
echo "Valid PNG file";
Related resources