File Header Forensics

Open a file and find out what it actually is, from its own bytes, not from its name. The matched signature bytes are highlighted in a hex dump and explained, the declared extension is audited against them, and PNG, JPEG, ELF, Windows PE and PDF headers are read field by field.

Rendered when the site was built, from the same signature table the analyzer matches against. No JavaScript required. With JavaScript on, you can point it at a file and it will highlight these bytes where it finds them.

526 signatures

526 signatures, curated toward the common types. Offset matters: a TAR archive's magic sits 257 bytes in, an ISO 9660 image's 32,769 bytes in, and a RIFF file's real type tag at byte 8, so a tool that only reads the first few bytes finds nothing in any of them.

Jump to: Images (77) · Audio (48) · Video (35) · Archives (87) · Documents (25) · Executables (44) · Fonts (14) · Disk images (49) · Data (90) · Text (11) · Key material (46)

Images77 signatures
Images file signatures (77)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
PNG image089 50 4E 47 0D 0A 1A 0A.PNG....image/png.png .apngThe first byte is 0x89, high bit set, so a transfer that strips the eighth bit corrupts it detectably. The CR-LF-EOF-LF tail catches line-ending translation the same way.
JPEG image0FF D8 FF...image/jpeg.jpg .jpeg .jpe .jfifA start-of-image marker. The picture's dimensions are not here; they sit in a later SOF segment, which is why a JPEG must be walked rather than read.
GIF image (87a)047 49 46 38 37 61GIF87aimage/gif.gifThe original 1987 version string. No transparency and no animation in this one.
GIF image (89a)047 49 46 38 39 61GIF89aimage/gif.gifThe 1989 revision: this is the one with transparency, animation and the comment blocks people hide data in.
Windows bitmap042 4DBMimage/bmp.bmp .dibTwo bytes only, and both printable, so 'BM' at the start of a text file is a false positive waiting to happen. Check the file size field that follows.
TIFF image (little-endian)049 49 2A 00II*.image/tiff.tif .tiff'II' announces Intel byte order, and the 42 that follows is the format's declared answer to everything. Camera raw files are usually TIFF underneath.
TIFF image (big-endian)04D 4D 00 2AMM.*image/tiff.tif .tiff'MM' announces Motorola byte order: the same 42, written the other way round. One format, two byte orders, chosen by the file.
WebP image857 45 42 50WEBPimage/webp.webpA RIFF container: 'RIFF' sits at offset 0 and says nothing, and this tag at offset 8 is what makes it an image.
Windows icon000 00 01 00....image/x-icon.icoFour bytes, three of them zero, so weak evidence. The image count that follows should be small and non-zero if this is real.
Photoshop document038 42 50 538BPSimage/vnd.adobe.photoshop.psd .psbAdobe's tag. The version word after it separates a PSD from the large-document PSB variant.
AVIF image861 76 69 66avifimage/avif.avifAn ISO base-media brand: 'ftyp' at offset 4 says which family, this brand at offset 8 says which member. Same box format as an MP4, holding AV1 frames.
HEIC image868 65 69 63heicimage/heic.heic .heifApple's still-image container: again the MP4 box format, this time holding HEVC frames.
JPEG 2000 image000 00 00 0C 6A 50 20 20 0D 0A 87 0A....jP ....image/jp2.jp2 .jpx .j2kA JPEG 2000 signature box: the length, then 'jP ', then a carriage-return/line-feed pair that catches the same text-mode corruption PNG's signature guards against.
JPEG XL image000 00 00 0C 4A 58 4C 20 0D 0A 87 0A....JXL ....image/jxl.jxlThe container form of JPEG XL, sharing JPEG 2000's box framing so only the 'JXL ' tag at offset 4 tells the two apart. A raw codestream starts 0xFF 0x0A instead.
DirectDraw surface044 44 53 20DDS image/vnd-ms.dds.ddsA texture format for games: the 'DDS ' tag with a trailing space, followed by a header describing the mip levels and the pixel packing a GPU uploads directly.
OpenEXR image076 2F 31 01v/1.image/x-exr.exrThe high-dynamic-range format from film work: a four-byte magic before a header of attributes, storing light values well beyond the 0-to-255 an ordinary image can hold.
Apple icon image069 63 6E 73icnsimage/icns.icnsmacOS bundles every size of an app's icon into one file, each resolution its own sub-image under a four-character tag, which is why an icon file is far larger than what you see.
GIMP image067 69 6D 70 20 78 63 66 20gimp xcf image/x-xcf.xcfGIMP's working format keeps every layer, mask and path unflattened, so the file is the editable project rather than the single picture an export produces.
Canon raw photo843 52 02 00CR..image/x-canon-cr2.cr2A Canon raw sits inside a TIFF, so its own 'CR' marker and version are 8 bytes in, after the TIFF byte-order and magic that a plain TIFF reader would stop at.
Fujifilm raw photo046 55 4A 49 46 49 4C 4D 43 43 44 2D 52 41 57FUJIFILMCCD-RAWimage/x-fuji-raf.rafFujifilm spell the format out in ASCII rather than a terse magic, so the header reads as plain text before the sensor data that only their software fully develops.
Radiance HDR image023 3F 52 41 44 49 41 4E 43 45#?RADIANCEimage/vnd.radiance.hdr .picThe original high-dynamic-range format: a text header, then pixels that pack a shared exponent so one byte of range serves the red, green and blue of each pixel.
FITS astronomy image053 49 4D 50 4C 45 20 20 3DSIMPLE =image/fits.fits .fit .ftsAstronomy's archival format is all human-readable header cards, beginning with the SIMPLE keyword, so a telescope image from decades ago is still openable in a text editor.
Windows metafile0D7 CD C6 9A....image/wmf.wmfA placeable metafile records drawing commands rather than pixels, so it scales without blur; the magic is the placeable wrapper Windows added around the raw command list.
Windows cursor000 00 02 00....image/x-icon.curThe same directory format as an icon file, with a 2 in the type field where an icon puts a 1. One format, two extensions, and a single byte between them.
DICOM medical image12844 49 43 4DDICMapplication/dicom.dcm .dicomA 128-byte preamble comes first, and the standard lets it hold anything at all so a scan can be made to open as some other format too. The real magic starts only after it.
PCX image00A 05 01...image/x-pcx.pcxZSoft's manufacturer byte, then version 5, then run-length encoding switched on. Older versions put a 0, 2 or 3 in the second byte, so this names the variant nearly every file uses.
SVG image03C 73 76 67<svgimage/svg+xml.svgSVG is XML, so a great many SVG files open with an XML declaration instead and this pattern never sees them. When the root element does come first, these four bytes are the whole magic.
JPEG XR image049 49 BC 01II..image/vnd.ms-photo.jxr .wdp .hdp'II' for Intel byte order, exactly as TIFF writes it, and then 0xBC where TIFF puts 42. Microsoft borrowed the framing and changed one number.
Canon raw photo (CR3)863 72 78 20crx image/x-canon-cr3.cr3Canon's newer raw format left TIFF for the MP4 box layout, so a still photograph now shares its framing with video. The trailing space pads the brand to four characters.
Olympus raw photo049 49 52 4FIIROimage/x-olympus-orf.orfTIFF's little-endian 'II' mark, then the maker's initials where the 42 belongs. Most raw formats are a TIFF underneath with the version number repurposed as a brand.
Panasonic raw photo049 49 55 00IIU.image/x-panasonic-rw2.rw2The same trick again: 'II' for byte order, then 0x55 standing in for TIFF's 42. Read it as a plain TIFF and you get the preview thumbnail and none of the sensor data.
Sigma raw photo046 4F 56 62FOVbimage/x-sigma-x3f.x3fNamed for the Foveon sensor, which records three colours at every pixel rather than one, and one of the few raw formats that is not a TIFF in disguise.
Minolta raw photo000 4D 52 4D.MRMimage/x-minolta-mrw.mrwA zero byte and then 'MRM'. The leading zero belongs to a block marker rather than to the name, which is why the readable part starts one byte in.
HEIF image86D 69 66 31mif1image/heif.heif .heicThe generic still-image brand: an ISO base-media file holding a picture without committing to a codec. Plenty of files named .heic carry this brand rather than the 'heic' one.
HEIF image sequence86D 73 66 31msf1image/heif-sequence.heifs .heicsThe sequence brand: several related pictures in one file, which is how a phone stores the short burst that plays back when you press and hold a photo.
AVIF image sequence861 76 69 73avisimage/avif-sequence.avifsAVIF's answer to the animated GIF: the same AV1 frames a still AVIF holds, with a brand that says there is more than one of them.
JPEG XL codestream0FF 0A..image/jxl.jxlThe bare codestream with none of the container boxing around it. Two bytes is thin evidence, and that is the price of a format that also ships in a boxed form.
Enhanced metafile4020 45 4D 46 EMFimage/emf.emfA Windows drawing stored as a list of commands rather than as pixels. The signature sits 40 bytes in, after the first record's header, the bounding box and the drawing frame.
Windows animated cursor841 43 4F 4EACONapplication/x-navi-animation.aniAnother RIFF form type: a list of cursor frames and how long to show each. It sits in the same container as a WAV file, and only these four bytes tell them apart.
WebP image (lossy)1256 50 38 20VP8 image/webp.webp'WEBP' at offset 8 says only that this RIFF file is a picture. The chunk tag at 12 says how it was coded, and this one is the ordinary lossy coding, a still frame of VP8 video.
WebP image (lossless)1256 50 38 4CVP8Limage/webp.webpThe lossless coding, which is a different compressor entirely rather than a quality setting. A file saved this way is byte for byte the picture that went in.
WebP image (extended)1256 50 38 58VP8Ximage/webp.webpThe extended form, and the only one that can animate, carry transparency alongside lossy colour, or hold a colour profile. A flags byte after the tag says which of those are used.
Animated PNG3300 00 00 08 61 63 54 4C....acTLimage/apng.apng .pngA PNG signature is 8 bytes and the header chunk that must follow is 25 more, so the next chunk starts at 33. An animation control chunk there is what makes a PNG move, and its length is part of the pattern because that chunk always carries exactly 8 bytes: how many frames, and how many times to play them.
JPEG image (JFIF)64A 46 49 46 00JFIF.image/jpeg.jpg .jpeg .jfifThe start-of-image marker says nothing about who wrote the file. The identifier six bytes in, past the application marker and the segment length, is the interchange convention that carries the pixel density and the thumbnail.
JPEG image (Exif)645 78 69 66 00 00Exif..image/jpeg.jpg .jpegThe same slot, filled by a camera instead: an Exif block, which is a whole TIFF directory holding the lens, the exposure and often the place the photograph was taken. Worth knowing before sharing the file.
Canon raw photo (CIFF)049 49 1A 00 00 00 48 45 41 50 43 43 44 52II....HEAPCCDRimage/x-canon-crw.crwCanon's first raw format borrows TIFF's little-endian mark and then puts 26 where TIFF puts 42, so a TIFF reader stops at the second field rather than misreading the picture.
BigTIFF image (little-endian)049 49 2B 00II+.image/tiff.tif .tiff .btf .svs .ndpi43 where an ordinary TIFF writes 42, and that one number changes every internal pointer from 32 bits to 64. It is how a microscope slide or a satellite scene passes four gigabytes.
BigTIFF image (big-endian)04D 4D 00 2BMM.+image/tiff.tif .tiff .btfThe same 43, written the other way round behind the Motorola byte-order mark. One format, two byte orders, exactly as plain TIFF has always done it.
DPX image (big-endian)053 44 50 58SDPXimage/x-dpx.dpxThe film industry's frame format: one picture per file, thousands of files per reel. The magic is readable, and reversing it is how the file announces the other byte order.
DPX image (little-endian)058 50 44 53XPDSimage/x-dpx.dpxThe same four characters backwards, which is what a big-endian magic looks like when a little-endian machine writes it. A reader that sees this knows to swap every field.
Radiance HDR image (exposure)023 3F 52 47 42 45#?RGBEimage/vnd.radiance.hdr .rgbeThe same high-dynamic-range format under its other opening line. Radiance only requires the first two characters, so tools have written whatever they liked after them for decades.
Khronos texture (KTX)0AB 4B 54 58 20 31 31 BB 0D 0A 1A 0A.KTX 11.....image/ktx.ktxA container for pixels already in the form a graphics card wants, so nothing has to be decoded before upload. The high bit, the version, and PNG's carriage-return guards are all in one twelve-byte signature.
Khronos texture (KTX2)0AB 4B 54 58 20 32 30 BB 0D 0A 1A 0A.KTX 20.....image/ktx2.ktx2Version 20 in the same wrapper. This is the one glTF models carry, because it can hold a texture that every kind of graphics card can transcode rather than one fixed encoding.
ASTC texture013 AB A1 5C...\image/astc.astcThe value 0x5CA1AB13 stored little-endian, which reads as 'scalable' in the hexadecimal alphabet. A compressed texture whose block size is chosen per file rather than by the format.
PowerVR texture050 56 52 03PVR.image/x-pvr.pvrVersion 3 of the texture container for the graphics cores in most phones. The version is a raw byte rather than a digit, so the fourth byte is not printable.
X PixMap image02F 2A 20 58 50 4D 20 2A 2F/* XPM */image/x-xpixmap.xpmA picture stored as a C source file, one string per row of pixels, so it could be compiled straight into a program. The magic is a comment, because the whole file has to stay valid C.
CorelDRAW drawing843 44 52CDRapplication/vnd.corel-draw.cdr .cdtAnother RIFF form type, and the fourth character of it is the version: a space for the early releases, then digits and letters. The version number is inside the tag itself.
Photoshop large document038 42 50 53 00 028BPS..image/vnd.adobe.photoshop.psbThe same Adobe tag as a PSD with a 2 in the version field where a PSD writes 1. That single byte raises the size limit from 30,000 pixels a side to 300,000.
Krita image306D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 6B 72 69 74 61mimetypeapplication/x-kritaapplication/x-krita.kra .krzA ZIP local file header is exactly 30 bytes wide, and Krita copies OpenDocument's trick of storing an uncompressed 'mimetype' member first, so the media type is pinned at this offset.
OpenRaster image306D 69 6D 65 74 79 70 65 69 6D 61 67 65 2F 6F 70 65 6E 72 61 73 74 65 72mimetypeimage/openrasterimage/openraster.oraThe open interchange format for layered paintings, using the same legislated first member. Inside are ordinary PNG layers and one XML file describing how they stack.
Paint.NET image050 44 4E 33PDN3image/x-paintnet.pdnPaint.NET's own layered format. The 3 is the file version rather than the program version, and it has not moved in the years since, which is a sign of a format that settled.
Paint Shop Pro image050 61 69 6E 74 20 53 68 6F 70 20 50 72 6F 20 49 6D 61 67 65 20 46 69 6C 65Paint Shop Pro Image Fileimage/vnd.corel.psp.psp .pspimageTwenty-five readable characters, which is one of the longest plain-text magics in the table and about as close to impossible to hit by accident as a signature gets.
Clip Studio Paint image043 53 46 43 48 55 4E 4BCSFCHUNKapplication/x-clip-studio.clipThe illustration program's working file: a chain of eight-character chunks, one of which is an entire SQLite database describing the layers. Every number in it is big-endian.
X11 cursor058 63 75 72Xcurimage/x-xcursornoneA mouse pointer on Linux and the BSDs: every size of the cursor, plus the frames and delays if it animates, in one file. It has no extension of its own, only a place on disk.
GIMP brush2047 49 4D 50GIMPimage/x-gimp-gbr.gbrFive 32-bit header fields come first, so the tag sits 20 bytes in. Two of those fields are the width and height, which is why a brush is a small greyscale picture and nothing more.
GIMP pattern2047 50 41 54GPATimage/x-gimp-pat.patThe same header layout with a different tag at the same offset, because a fill pattern and a brush differ in how they are used rather than in how they are stored.
NIfTI-1 brain scan3446E 2B 31 00n+1.image/x.nifti.niiNeuroimaging's working format keeps a 348-byte header inherited from a 1990s standard, and the magic is the last four bytes of it. A '+' means the picture follows in the same file.
NIfTI-1 header3446E 69 31 00ni1.image/x.nifti.hdrThe same slot without the plus, meaning the header is alone and the voxels live beside it in a matching .img file. One byte decides whether the scan is one file or two.
NIfTI-2 brain scan46E 2B 32 00 0D 0A 1A 0An+2.....image/x.nifti.niiVersion 2 moved the magic to the front and borrowed PNG's guards: a carriage return, a line feed and an end-of-file byte, so a scan mangled by a text-mode transfer fails loudly.
NRRD imaging data04E 52 52 44 30 30 30NRRD000image/x.nrrd.nrrd .nhdrA format for scans and volumes whose header is plain text key-value lines, so the shape and spacing of the data can be read and fixed without any special tool. A version digit follows the zeros.
JPEG 2000 codestream0FF 4F FF 51.O.Qimage/x-jp2-codestream.j2k .j2c .jpcThe compressed picture with none of the box framing a .jp2 wraps around it. The markers echo JPEG's 0xFF pairs, because JPEG 2000 kept the marker idea and replaced everything else.
JPEG 2000 extended (JPX)206A 70 78 20jpx image/jpx.jpx .jpfJPEG 2000 puts a 12-byte signature box before its file-type box, so the brand lands at 20 rather than at the 8 an MP4 uses. Same idea, twelve bytes further in.
Netpbm bitmap050 34P4image/x-portable-bitmap.pbmOne bit per pixel, packed. The magic is a letter and a digit, and the spec then requires any one whitespace byte, which needs a regular expression rather than a fixed pattern. file(1) writes exactly that; a byte-exact table has to stop at the two characters.
Netpbm greymap050 35P5image/x-portable-graymap.pgmGrey levels, one or two bytes each, after a header of decimal numbers in text. The same two-byte weakness as its siblings, so treat a lone match as a hint.
Netpbm pixmap050 36P6image/x-portable-pixmap.ppmRed, green and blue with no compression and almost no header, which is why it is the format image programs write when they want something any twenty-line program can read. P1 to P3 are the same three formats spelled out in decimal text instead.
HEIF image (heix brand)868 65 69 78heiximage/heif.heic .heifThe brand Apple writes for a still photograph coded at the higher of HEVC's two profiles. Same container, same pixels, and a brand that records which rules the encoder followed.
QOI image071 6F 69 66qoifimage/qoi.qoiThe Quite OK Image format: a whole lossless codec specified on one page, which encodes and decodes far faster than PNG in exchange for larger files. Proof a format need not be big.
Audio48 signatures
Audio file signatures (48)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
WAV audio857 41 56 45WAVEaudio/wav.wav .wave .bwfThe RIFF form type at offset 8. This is the pattern that turns a generic container into a sound file, and it is the reason the offset field exists. A Broadcast Wave (.bwf) is this with one extra chunk of production notes, so the two are one format under two names.
AIFF audio841 49 46 46AIFFaudio/aiff.aif .aiffApple's interchange format opens with FORM rather than RIFF, but uses the same idea: a container tag first, the real type at offset 8.
MP3 audio (ID3 tagged)049 44 33ID3audio/mpeg.mp3This is the metadata tag, not the audio. The first MPEG frame begins after the tag's own declared size, so the sound may start thousands of bytes in.
FLAC audio066 4C 61 43fLaCaudio/flac.flacFree Lossless Audio Codec. The mixed case is deliberate and part of the magic: a case-insensitive match would also fire on the word 'flac' in prose.
Ogg container04F 67 67 53OggSapplication/ogg.ogg .ogxA page header. What is inside (Vorbis, Opus, Theora, FLAC, Speex) is named a few bytes further in, so these four bytes identify the wrapper only, and every one of those codec rows matches the same file, which is a refinement rather than a second format.
MIDI sequence04D 54 68 64MThdaudio/midi.mid .midi .karA header chunk. MIDI stores performance instructions rather than sound, so the file is tiny and what you hear depends on the synthesiser. A karaoke .kar is the same file with the lyrics carried in text events, which is why any MIDI player opens one.
M4A audio84D 34 41 20M4A audio/mp4.m4aAn MP4 container holding audio only. The trailing space is part of the brand, and the capital letters distinguish it from the video brands.
Monkey's Audio04D 41 43 20MAC audio/x-ape.apeA lossless codec whose 'MAC ' tag stands for Monkey's Audio Compressor; it trades slower decoding for smaller files than FLAC, which is why it stayed a niche.
WavPack audio077 76 70 6Bwvpkaudio/x-wavpack.wv .wvcWavPack can store a lossy file plus a correction stream that restores the lossless original, so one format is both, decided at playback rather than at encode.
Sun/NeXT audio02E 73 6E 64.sndaudio/basic.au .sndThe old Unix sound format: a '.snd' header giving the offset to the samples, so the audio could start anywhere after a variable-length text annotation.
Core Audio format063 61 66 66caffaudio/x-caf.cafApple's container removes WAV's 4 GB size limit by using 64-bit chunk lengths, which is why long or high-rate recordings are stored here rather than in a plain WAV.
AMR speech023 21 41 4D 52 0A#!AMR.audio/amr.amrThe codec mobile networks used for voice: tuned for speech at very low bitrates, so music through it sounds thin. RFC 4867 makes the newline part of the magic, because '#!AMR' on its own is also the opening of the wideband and multi-channel headers.
Musepack audio04D 50 43 4BMPCKaudio/x-musepack.mpcA lossy codec aimed at transparency at higher bitrates; the SV8 stream tag is 'MPCK', where older SV7 files instead begin 'MP+'.
M4B audiobook84D 34 42 20M4B audio/mp4.m4bThe same audio an .m4a holds, with a brand that tells a player to remember your place and to read the chapter list. A file format as a bookmark.
RIFF MIDI852 4D 49 44RMIDaudio/midi.rmiA MIDI sequence wrapped in a RIFF container so Windows could carry it beside sound and video. The form type at offset 8 is the only thing that says which.
Opus audio (in Ogg)284F 70 75 73 48 65 61 64OpusHeadaudio/opus.opus .oggAn Ogg page header is 27 bytes plus a one-byte segment table, so the codec finally names itself at byte 28. The 'OggS' at offset 0 says only that something is packetised.
Vorbis audio (in Ogg)2801 76 6F 72 62 69 73.vorbisaudio/vorbis.ogg .ogaThe identification header of the first packet: a 1 for 'this is the header', then the codec's name. Same position as Opus, because both are riding the same page layout.
ProTracker module10804D 2E 4B 2EM.K.audio/x-mod.modThe deepest tag in this table that is not a disc image: 20 bytes of title, then 31 sample headers of 30 bytes each, then the pattern order, and only then these four bytes.
Scream Tracker 3 module4453 43 52 4DSCRMaudio/x-s3m.s3mA 28-character title comes first, then a handful of counts, so the tag lands at byte 44. Tracker formats put the human-readable part before the machine-readable one.
FastTracker II module045 78 74 65 6E 64 65 64 20 4D 6F 64 75 6C 65 3A 20Extended Module: audio/x-xm.xmSeventeen bytes of English, trailing space included, and then the song title. A magic number that is simply a sentence, which makes a truncated match very unlikely.
Impulse Tracker module049 4D 50 4DIMPMaudio/x-it.itFour characters for a format that stores instructions for a software synthesiser rather than recorded sound, which is why a whole song fits in a few tens of kilobytes.
MP3 audio (bare frame)0FF FB..audio/mpeg.mp3An MPEG-1 Layer III frame with no tag in front of it: eleven bits of sync, then the generation and layer. Two bytes is weak evidence, and an ID3 tag is the usual stronger one.
MP3 audio (MPEG-2 frame)0FF F3..audio/mpeg.mp3The same sync word with the version bits saying MPEG-2, the half-rate variant used for low bitrates. The two generations are one extension and two patterns.
AAC audio (ADTS stream)0FF F1..audio/aac.aacAAC borrowed MPEG's sync word and changed the bits after it, so an .aac and an .mp3 differ in the fourth nibble of the second byte and nowhere earlier.
Dolby Digital audio00B 77.waudio/ac3.ac3A sync word chosen to be rare in audio data rather than to spell anything. Two bytes, so treat a lone match as a hint and check that frames repeat at a regular spacing.
DTS audio07F FE 80 01....audio/vnd.dts.dtsThe competing cinema sound format's sync word, and a longer one than Dolby's, so a match here is worth more. The same stream also hides inside WAV files on some discs.
DSD audio044 53 44 20DSD audio/x-dsf.dsfDirect Stream Digital, the format on a Super Audio CD: one bit per sample at a very high rate instead of many bits at a low one, which is why the files are enormous.
M4P protected audio84D 34 50 20M4P audio/mp4.m4pThe brand the iTunes Store wrote on purchases until 2009: exactly the audio an .m4a holds, with the samples encrypted and the key held somewhere else. The container stays readable and the sound does not, which is the whole design.
SoundFont 2 bank873 66 62 6Bsfbkaudio/x-soundfont.sf2A RIFF form holding recorded instrument samples and the rules for stretching them across a keyboard. It is what turns a MIDI file, which stores only instructions, into a sound two people can hear the same way.
Steinberg Cubase project84E 55 4E 44 52 4F 4F 54NUNDROOTaudio/x-cubase.cpr .nprEight characters where a RIFF form type is normally four, because Steinberg used the whole chunk name as the identifier. The project stores the arrangement and the settings; the recorded audio lives beside it in a folder, which is why a project alone is silent.
AIFF-C compressed audio841 49 46 43AIFCaudio/x-aiff.aifc .aifThe 1991 revision of Apple's interchange format, which added a four-character compression name to every sound chunk. An .aifc whose name is 'NONE' is a plain AIFF that simply says out loud that nothing was compressed.
RF64 broadcast WAV052 46 36 34 FF FF FF FF 57 41 56 45 64 73 36 34RF64....WAVEds64audio/wav.wav .rf64A WAV's size field is 32 bits, so the format stops dead at 4 GB, about six hours of CD quality. This writes all ones there to mean 'look elsewhere' and names the chunk holding the real 64-bit length. Offset 8 still says WAVE, so ordinary tools open it until they ask how long it is.
Sony Wave64 audio072 69 66 66 2E 91 CF 11 A5 D6 28 DB 04 C1 00 00riff......(.....audio/x-w64.w64Sony answered the same 4 GB problem the other way: every four-character chunk name became a sixteen-byte identifier and every length a 64-bit number. The identifier *begins* with the old name in lower case, so a case-insensitive RIFF matcher fires and then reads every field at the wrong place.
DSDIFF audio1244 53 44 20DSD audio/x-dff.dffThe same four bytes the .dsf row carries at offset 0, twelve bytes further in, where they are an IFF form type behind 'FRM8' and a 64-bit length. Two containers for one kind of audio, told apart by nothing but where the word sits.
FLAC audio (in Ogg)287F 46 4C 41 43.FLACaudio/ogg.oga .oggThe lossless codec the .flac row identifies, repacked into Ogg pages so it can be streamed and carried beside other tracks. The 0x7F in front is deliberately unprintable, so this header cannot be confused with the word FLAC written in text.
Speex audio (in Ogg)2853 70 65 65 78 20 20 20Speex audio/speex.spx .oggA codec built for speech at very low bitrates, retired in favour of Opus in 2012 and still under a great many old voice recordings. The name is padded to eight characters with three spaces, in the same slot Vorbis and Opus use.
True Audio lossless054 54 41 31TTA1audio/x-tta.ttaA lossless codec deliberately cheap to decode, because it was aimed at the portable players of the early 2000s. It compresses less than FLAC and asks far less of the processor, which is the trade every lossless format has to pick a side of.
TAK lossless audio074 42 61 4BtBaKaudio/x-tak.takTom's lossless Audio Kompressor. The mixed case is part of the magic and the capitals spell the author's initials: a signature that is a private joke, which is commoner in this table than the formats admit.
Musepack audio (SV7)04D 50 2BMP+audio/x-musepack.mpc .mp+The stream version 7 header, three bytes where the newer SV8 writes 'MPCK'. One codec, two framings that no single decoder reads, and therefore two rows: the version is not a detail inside the file, it is which file this is.
AAC audio (ADIF)041 44 49 46ADIFaudio/aac.aacAudio Data Interchange Format: one header at the front and then nothing but frames. The ADTS rows are the opposite trade, a header on every frame, which wastes space but lets a listener join a broadcast that is already running.
AAC audio (MPEG-2 ADTS)0FF F9..audio/aac.aacThe same twelve sync bits as its MPEG-4 sibling with the next bit set to say MPEG-2. Both leave the two layer bits at zero, a value MPEG-1 audio reserved and never used, and that reserved value is the whole of what keeps AAC and MP3 apart in these two bytes.
MP2 audio (bare frame)0FF FD..audio/mpeg.mp2 .m2aLayer II of the standard MP3 came from, still the sound on European digital television and radio because it survives being cut and re-joined at any frame boundary. The layer number lives in two bits of this second byte, and that is the entire difference.
DTS audio (little-endian)0FE 7F 01 80....audio/vnd.dts.dts .cptThe sync word the .dts row carries, with each 16-bit half written the other way round, because the stream was lifted straight off a disc that stores samples in that order. One codec, two byte orders, and a decoder has to be willing to try both.
DTS-HD extension substream064 58 20 25dX %audio/vnd.dts.hd.dtshd .dtsThe high-definition extension carried on Blu-ray, whose sync word happens to spell 'dX %'. A disc usually stores the ordinary DTS core and this substream together, so an older receiver plays the core and never notices the rest.
AMR-WB speech023 21 41 4D 52 2D 57 42 0A#!AMR-WB.audio/amr-wb.awb .amrThe wideband version of the mobile speech codec, carrying about twice the frequency range, which is what a phone means by 'HD Voice'. RFC 4867 makes the trailing newline part of the magic on purpose, because without it the narrowband header is a prefix of this one.
NES sound file04E 45 53 4D 1ANESM.audio/x-nsf.nsfNot a recording: a dump of the 6502 code a Nintendo game ran to drive its sound chip, plus the address to call for each track. Playing it means emulating the console, which is how a whole soundtrack fits in a few kilobytes.
SNES SPC700 sound file053 4E 45 53 2D 53 50 43 37 30 30 20 53 6F 75 6E 64 20 46 69 6C 65 20 44 61 74 61 20 76SNES-SPC700 Sound File Data vaudio/x-spc.spcTwenty-nine characters of plain English and then a version number: a magic that is simply a sentence, like the tracker rows. The file is a snapshot of the Super Nintendo's audio processor: its 64 KiB of memory and its registers, frozen mid-tune.
FL Studio project046 4C 68 64FLhdaudio/x-flp.flpA header chunk named after IFF's, then a data chunk of events. The project records the arrangement and every plugin's settings but none of the sound, so a project opened without its samples and plugins plays silence.
Video35 signatures
Video file signatures (35)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
AVI video841 56 49 20AVI video/x-msvideo.avi .divxThe RIFF form type for video. Note the trailing space: four-character codes are padded, and dropping the pad is a classic matcher bug.
Matroska / WebM01A 45 DF A3.E..video/x-matroska.mkv .webm .mka .mks .mk3d .webaAn EBML header. WebM is a constrained profile of Matroska and shares these exact bytes, so the extension is the only hint of which one you have. Which it is is written in a DocType element a few bytes in, but the elements before it vary in size, so it has to be searched for rather than read at a fixed offset, and this table only states fixed offsets.
ISO base-media container466 74 79 70ftypvideo/mp4noneThe file-type box, and it starts at offset 4 because the box's own length comes first. The brand at offset 8 says what this really is.
MP4 video (isom brand)869 73 6F 6Disomvideo/mp4.mp4The ISO base media brand: the most common MP4 flavour, and the one most muxers write.
QuickTime movie871 74 20 20qt video/quicktime.mov .qtApple's brand, padded to four characters with two trailing spaces. Same container as MP4, different brand.
ASF / WMV / WMA030 26 B2 75 8E 66 CF 110&.u.f..video/x-ms-asf.asf .wmv .wmaThe first eight bytes of a sixteen-byte Microsoft GUID. Audio and video share the container, so the extension is a hint rather than a fact.
Flash video046 4C 56FLVvideo/x-flv.flvThe container that carried most web video before HTML5: a three-byte 'FLV' tag then flags for whether audio and video streams are present.
MPEG program stream000 00 01 BA....video/mpeg.mpg .mpeg .vobA DVD-era stream multiplexing audio and video for playback: the pack header start code 0x000001BA marks the beginning of a group the player reads in step.
MPEG video stream000 00 01 B3....video/mpeg.mpv .m1v .m2vA bare elementary video stream: the sequence-header start code 0x000001B3, with no container and no audio, which is why these rarely appear on their own.
RealMedia02E 52 4D 46.RMFapplication/vnd.rn-realmedia.rm .rmvbRealNetworks' streaming format from the dial-up era, built to degrade gracefully on a slow link; the '.RMF' tag opens a chunked header much like RIFF's.
MP4 video (mp42 brand)86D 70 34 32mp42video/mp4.mp4The version-2 brand most cameras and Windows tools write. Nothing about the picture changes between this and 'isom'; the brand records which rules the muxer promised to follow.
3GPP mobile video833 67 70 343gp4video/3gpp.3gpThe same box format again, profiled for phones. Later releases write '3gp5' and '3g2a', so the digit is a generation rather than part of the name.
M4V video84D 34 56 20M4V video/x-m4v.m4vApple's video brand, padded to four characters. An .m4v and an .mp4 can hold identical video; the extension exists so one player claims it and another does not.
Theora video (in Ogg)2880 74 68 65 6F 72 61.theoravideo/ogg.ogv .oggTheora marks its header packets by setting the top bit of the type byte, then names itself exactly where Vorbis does. One container, three payloads, one offset.
MXF media container006 0E 2B 34 02 05 01 01..+4....application/mxf.mxfThe start of a 16-byte SMPTE universal label: broadcast formats identify themselves with registered keys rather than with words, so nothing here is readable and that is deliberate.
MP4 video (mp41 brand)86D 70 34 31mp41video/mp4.mp4The first MP4 brand, from the 2001 edition, and still what some older Apple exports write. Nothing about the pictures changes between this and 'mp42': a brand records which edition of the rules the muxer promised to follow, not what is inside.
MP4 video (iso2 brand)869 73 6F 32iso2video/mp4.mp4The 2005 base-media brand. Most files carry it a little further in as well, in the list of brands they are merely *compatible* with: a writer declares the one set of rules it was built for and every older set it will still open under.
MP4 streaming segment (dash brand)864 61 73 68dashvideo/mp4.mp4 .m4sThe brand a player checks before it will fetch a video in pieces: it promises the file is indexed so any piece can be read without the pieces before it. That promise is what makes a stream switch quality mid-play without starting again.
3GPP mobile video (3gp5 brand)833 67 70 353gp5video/3gpp.3gpRelease 5 of the phone profile, the generation that allowed MPEG-4 video beside H.263. The digit is a release number, so this brand ages with the mobile network rather than with the container it sits in.
Sony XAVC video858 41 56 43XAVCvideo/mp4.mp4Sony's professional recording format: an ordinary MP4 whose brand tells an editing system which frame sizes, rates and bit depths the camera guaranteed to stay inside, so the edit can be planned before a single frame is decoded.
QuickTime movie (index first)46D 6F 6F 76moovvideo/quicktime.mov .qtAn older QuickTime file has no file-type box at all, so the first box is whatever the writer put first, and its name sits at 4 because the box's own length comes before it. 'moov' first means the index is at the front, so playback can start before the download ends.
QuickTime movie (pictures first)46D 64 61 74mdatvideo/quicktime.mov .qtThe same container with the pictures first and the index at the end, which is what a camera writes because it cannot know the index until recording stops. Streaming one means fetching the end of the file before the beginning.
QuickTime movie (wide placeholder)477 69 64 65widevideo/quicktime.mov .qtAn eight-byte reservation left in front of the pictures so the length field beside them can later grow from four bytes to eight without moving a single sample. A hole kept open on purpose, in case the recording turns out to be longer than 4 GB.
Fragmented MP4 segment473 74 79 70stypvideo/iso.segment.m4sA segment-type box: the file-type box's name with one letter changed, opening each piece of a video delivered in pieces. A player that already holds the opening file can begin at any of these, which is what adaptive streaming actually ships.
REDCODE raw video452 45 44 31RED1video/x-red-r3d.r3dA digital cinema camera's own recording, in the same length-then-name box layout an MP4 uses. It keeps compressed sensor readings rather than a finished picture, so the colour is decided in the edit and a shooting day runs to hundreds of gigabytes.
YUV4MPEG2 video stream059 55 56 34 4D 50 45 47 32YUV4MPEG2video/x-yuv4mpeg2.y4mUncompressed frames behind a one-line text header naming the size, rate and colour layout, with the literal word FRAME before each picture. It exists so two encoders can be judged on identical input, and it is vast: a minute of high definition runs to gigabytes.
IVF video stream044 4B 49 46DKIFvideo/x-ivf.ivfA 32-byte header and then each compressed frame with its length and timestamp, about the thinnest container that can hold video at all, and the one VP8, VP9 and AV1 encoders are tested with. 'DK' is Duck, the company whose codecs became VP8.
DV video (raw)01F 07 00...video/x-dv.dv .difThe header of the first 80-byte block on a digital videotape; the file is simply the tape's blocks in order. Only three bytes are fixed, and the fourth carries the flag that says 50 Hz or 60 Hz, so this is weak evidence taken alone.
Leitch/Harris LXF video04C 45 49 54 43 48 00 00LEITCH..application/x-lxf.lxfA broadcast playout server's own recording format. The identifier is eight bytes wide and the company name is six, so the two zero bytes after it are as much a part of the pattern as the letters are.
GXF broadcast container000 00 00 00 01 BC......application/x-gxf.gxfSMPTE's General eXchange Format, for moving finished material between broadcast servers. Every packet opens with five bytes of leader and then a type, and four of those five are zero, so a careful reader checks the packet's trailing bytes as well before believing it.
DVD video manager044 56 44 56 49 44 45 4F 2D 56 4D 47DVDVIDEO-VMGvideo/x-ifo.ifo .bupVIDEO_TS.IFO, the top of a DVD's structure: which title sets exist and what the disc does when you put it in. Every .ifo is written twice: the .bup beside it is a byte-for-byte backup, because a scratch here costs the whole disc.
DVD title set044 56 44 56 49 44 45 4F 2D 56 54 53DVDVIDEO-VTSvideo/x-ifo.ifo .bupOne film or episode's own table of contents: chapter marks, camera angles, audio and subtitle tracks, and where each begins inside the .vob files. The pictures are next door; this is the map that makes them navigable.
Blu-ray playlist04D 50 4C 53MPLSvideo/x-bluray-playlist.mplsA disc's PLAYLIST folder holds one of these for every route through the material, and studios add dozens of decoys of the same running time to make the real film hard to find. Choosing the right .mpls is the first thing any player or ripper does.
Blu-ray clip information048 44 4D 56HDMVvideo/x-bluray-clipinfo.clpiThe index for one .m2ts stream: which codecs it carries and a table of seek points, so a player can jump to a time without scanning. 'HDMV' names the disc's high-definition movie mode rather than this file.
Blu-ray index049 4E 44 58INDXvideo/x-bluray-index.bdmvindex.bdmv, the first file a player reads: it lists the disc's titles and says which one starts on insertion. The same four letters also name an unrelated structure inside NTFS, which is a standing reminder that four printable bytes are not much evidence.
Archives87 signatures
Archives file signatures (87)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
ZIP archive050 4B 03 04PK..application/zip.zip'PK' is Phil Katz. A great many things presented as their own formats are a ZIP with agreed file names inside, which is why so many extensions map here legitimately.
ZIP archive (empty)050 4B 05 06PK..application/zip.zipAn end-of-central-directory record with no local file headers before it: a ZIP that contains nothing at all.
RAR archive (4.x and earlier)052 61 72 21 1A 07 00Rar!...application/vnd.rar.rarThe older RAR signature. That final zero byte is the whole difference from RAR 5, so a six-byte match tells you nothing about which generation you have.
RAR archive (5.x)052 61 72 21 1A 07 01 00Rar!....application/vnd.rar.rarRAR 5 appended a version byte, so the two generations are distinguishable from the header alone, one of the few formats that planned for this.
7-Zip archive037 7A BC AF 27 1C7z..'.application/x-7z-compressed.7zSix bytes with no printable run, so a false positive is very unlikely. Solid compression means you cannot list it without reading the end of the file.
gzip stream01F 8B..application/gzip.gz .gzipTwo bytes only. A gzip stream carries exactly one member, so a .tar.gz is a tar archive inside one: two formats stacked, which is why the extension has two parts.
bzip2 stream042 5A 68BZhapplication/x-bzip2.bz2 .tbz2'BZh' then an ASCII digit giving the block size in hundreds of kilobytes: the parameter is inside the magic.
XZ stream0FD 37 7A 58 5A 00.7zXZ.application/x-xz.xz .txzThe 0xFD lead byte was chosen precisely so the file cannot be mistaken for text, and the 'ZXZ' that follows is readable in a hex dump.
Zstandard stream028 B5 2F FD(./.application/zstd.zst .zstdThe frame magic 0xFD2FB528 written little-endian: read the bytes backwards and the constant appears.
LZ4 frame004 22 4D 18."M.application/x-lz4.lz4The LZ4 *frame* format's magic. Raw LZ4 blocks have no magic at all, so an unrecognised LZ4 payload is entirely normal.
TAR archive25775 73 74 61 72ustarapplication/x-tar.tarTAR has no header of its own: the archive begins with the first member's 512-byte record, and the format's magic sits 257 bytes into it. Read only the first sixteen bytes and you will conclude a tar file is nothing at all.
Unix ar archive021 3C 61 72 63 68 3E!<arch>application/x-archive.a .ar .libUsed for static libraries, and for .deb packages, which are an ar archive of exactly three members. Members are named in plain text, so the header is readable.
Microsoft Cabinet04D 53 43 46MSCFapplication/vnd.ms-cab-compressed.cabMicrosoft's installer archive. A Windows update package and a troubleshooter pack are a cabinet with agreed contents and nothing else, the same relationship a .deb has with ar.
RPM package0ED AB EE DB....application/x-rpm.rpmA lead record whose four bytes spell 'edabeedb' in hex, one of the oldest jokes in the format-design business.
XAR archive078 61 72 21xar!application/x-xar.xar .pkgThe archive under a macOS installer package: a table of contents up front, so a tool can list the contents without reading the whole file, unlike a solid archive.
lzip stream04C 5A 49 50LZIPapplication/x-lzip.lzAn LZMA container that puts integrity checks and the uncompressed size in the header, chosen over .xz by projects that wanted a simpler, long-term-stable format.
compress (.Z) stream01F 9D..application/x-compress.zThe original Unix 'compress': two bytes then LZW-coded data. Patent worries around LZW are the whole reason gzip was written to replace it.
Windows imaging archive04D 53 57 49 4D 00 00 00MSWIM...application/x-ms-wim.wim .swm .esdThe file-based image Windows installs from: 'MSWIM' then zero padding, storing one copy of each unique file so several Windows editions share most of their bytes.
ARJ archive060 EA`.application/x-arj.arjA DOS-era archiver whose 0x60 0xEA marker opens each header; it could span floppy disks, which mattered when a program did not fit on one.
StuffIt archive053 74 75 66 66 49 74StuffItapplication/x-stuffit.sit .sitxThe Mac archive format for decades, so 'StuffIt' in a header usually means the file crossed from a classic Macintosh where it was the default way to bundle downloads.
LHA/LZH archive22D 6C 68-lhapplication/x-lzh-compressed.lzh .lhaThe compression method tag sits 2 bytes in, after the header size and checksum, so '-lh5-' at offset 2 names the algorithm rather than the file. Still common in Japan.
Chrome extension043 72 32 34Cr24application/x-chrome-extension.crxA Chrome extension is a ZIP with a signed header bolted on the front: 'Cr24', a version, then a public key and signature, then the ordinary archive.
cpio archive (newc)030 37 30 37 30 31070701application/x-cpio.cpioThe portable ASCII cpio header writes every field as hex text beginning '070701', so an archive stays readable across machines that disagree on byte order. Used inside RPMs.
Debian package864 65 62 69 61 6E 2D 62 69 6E 61 72 79debian-binaryapplication/vnd.debian.binary-package.deb .udebAn ar archive whose first member is required to be called 'debian-binary', and member names are stored in plain text right after the 8-byte archive magic. The name is the signature.
ACE archive72A 2A 41 43 45 2A 2A**ACE**application/x-ace-compressed.aceThe magic sits at byte 7, after a checksum, a header size and a header type, so the format puts its own integrity check before its own name.
cpio archive (binary)0C7 71.qapplication/x-cpio.cpioThe original cpio header wrote its fields as raw 16-bit numbers, and 0x71C7 is octal 070707 stored little-endian. The same value the text forms spell out, in machine byte order.
cpio archive (portable ASCII)030 37 30 37 30 37070707application/x-cpio.cpioThe same 070707, this time written as six characters so the archive survives a move between machines that disagree about byte order. A format that chose text to be portable.
cpio archive (newc with CRC)030 37 30 37 30 32070702application/x-cpio.cpioThe new ASCII format with per-file checksums, distinguished from plain newc by the final digit alone. This is the flavour a Linux initramfs is usually built with.
LZMA stream (alone)05D 00 00]..application/x-lzma.lzmaBarely a header: one byte of coder properties, and 0x5D is simply the default setting nearly every encoder uses. XZ exists largely because this format could not identify itself.
lzop stream089 4C 5A 4F 00 0D 0A 1A 0A.LZO.....application/x-lzop.lzoA deliberate copy of PNG's idea: a high-bit byte first so a seven-bit transfer corrupts it detectably, then a CR-LF-EOF-LF tail that catches line-ending translation.
lrzip archive04C 52 5A 49LRZIapplication/x-lrzip.lrzLong-range zip, which looks for repeated data across a whole huge file before compressing, so it wins on things like disk images that repeat themselves far apart.
Zoo archive05A 4F 4F 20ZOO application/x-zoo.zooA 1980s archiver whose header opens with its name and a human-readable notice, so the first thing in the file is a sentence for whoever ended up holding it.
Snappy framed stream0FF 06 00 00 73 4E 61 50 70 59....sNaPpYapplication/x-snappy-framed.szA stream-identifier chunk: a chunk type, a length, and then the name in alternating case. Compression tuned for speed rather than size, which is why data pipelines use it.
Zstandard dictionary037 A4 30 EC7.0.application/zstd.dictNot compressed data at all: a shared dictionary that a compressor and a decompressor both load first, so that very small messages have something to refer back to.
ZIP archive (spanned)050 4B 07 08PK..application/zip.zip .z01The marker that says this archive was split across several volumes, so the rest of your data is in another file. The same four bytes also appear mid-archive as a data descriptor.
InstallShield cabinet049 53 63 28ISc(application/x-installshield.cab .hdrNot a Microsoft cabinet despite the extension it usually wears, which is exactly the kind of claim this tool exists to check.
Btrfs send stream062 74 72 66 73 2D 73 74 72 65 61 6Dbtrfs-streamapplication/x-btrfs-stream.btrfs .streamWhat a btrfs send produces: not a mountable image but a list of the differences between two snapshots, meant to be piped into a receive on another machine. That is an archive, not a disk, and the family field says so.
ZFS send stream800 00 00 02 F5 BA CB AC........application/x-zfs-stream.zfs .zstreamA ZFS send stream opens with a record type and a length, so its 64-bit magic is the third word rather than the first. Like the btrfs stream beside it this is a list of changes to replay, not a filesystem anything can mount.
ZIP archive (spanning marker)050 4B 30 30 50 4B 03 04PK00PK..application/zip.zipPKZIP writes 'PK00' in front of a one-volume archive that was made with the split-across-disks option and then never needed splitting. The archive proper begins four bytes later.
Mozilla omni archive450 4B 01 02PK..application/x-mozilla-archive.jaFirefox ships its own code as a ZIP with the central directory moved to the front, so the browser can read the index without seeking to the end of the file on every start.
TAR archive (POSIX ustar)25775 73 74 61 72 00 30 30ustar.00application/x-tar.tarThe five-byte magic is followed by a two-character version field, and POSIX writes a null then the digits '00'. Read eight bytes rather than five and you learn which tar wrote it.
TAR archive (GNU)25775 73 74 61 72 20 20 00ustar .application/x-tar.tarGNU tar puts two spaces and a null where POSIX puts a null and '00', in the same field. One format, two dialects, three bytes apart, and GNU's is what plain `tar -cf` produces.
GNU tar incremental snapshot047 4E 55 20 74 61 72 2DGNU tar-application/x-tar-snapshot.snarNot an archive at all: the list of what was already backed up, which `tar --listed-incremental` reads to decide what changed. Lose it and the next incremental becomes a full.
Unix ar archive (thin)021 3C 74 68 69 6E 3E 0A!<thin>.application/x-archive.a .ar .libA thin archive stores member *paths* instead of member bytes, so it is a few kilobytes listing files it does not contain. The Linux kernel's built-in.a is one of these.
cpio archive (binary, big-endian)071 C7q.application/x-cpio.cpioThe same octal 070707 the other cpio rows spell out, written most-significant-byte-first. Beside the little-endian row it is the byte-order lesson in two bytes.
zlib stream (no compression)078 01x.application/zlib.zz .zlibTwo bytes, but not two arbitrary bytes: read as one 16-bit number they must divide by 31, and the low nibble of the first must be 8 for deflate. This pair says 'fastest setting'.
zlib stream (fast)078 5Ex^application/zlib.zz .zlibCompression levels 2 to 5. The second byte carries both the level and the check bits that make the pair divisible by 31, which is why the four legal values look unrelated.
zlib stream (default)078 9Cx.application/zlib.zz .zlibBy far the most common of the four. Every PNG image row, every Git loose object and every compressed PDF stream begins with these bytes somewhere inside the file.
zlib stream (best)078 DAx.application/zlib.zz .zlibLevels 7 to 9. A raw deflate stream has no header at all, so these two bytes are the only difference between something a tool can recognise and something it cannot.
LZ4 legacy frame002 21 4C 18.!L.application/x-lz4.lz4The pre-1.0 frame, kept alive because the Linux kernel's own build compresses itself with it. 0x184C2102 written little-endian, one digit away from the modern frame's 0x184D2204.
Zstandard or LZ4 skippable frame050 2A 4D 18P*M.application/zstd.zst .lz4A frame a decoder is required to step over and carry on past, so a compressed file can open with metadata that is none of the decompressor's business. Zstandard and LZ4 chose the same marker on purpose. Fifteen further values differ only in the last nibble.
bzip3 stream042 5A 33 76 31BZ3v1application/x-bzip3.bz3The 2022 successor to bzip2: the same block-sorting idea with a much larger block and a modern entropy coder. It put a version inside the magic, which bzip2 never did.
LZFSE stream062 76 78 32bvx2application/x-lzfse.lzfseApple's compressor, tuned to spend as little battery as possible per byte saved. The magic is really a block type, so a file names its own internals in its first four characters.
LZVN stream062 76 78 6Ebvxnapplication/x-lzfse.lzvn .lzfseA different, faster algorithm sharing LZFSE's container: this is what a macOS kernel cache is packed with. One block type apart from its sibling, and a completely different coder.
Apple pbzx payload070 62 7A 78pbzxapplication/x-pbzx.pbzxThe payload inside a macOS installer package: XZ streams cut into fixed chunks so the installer can decompress several at once. Four characters, then a 64-bit flags field.
Mozilla LZ4 store06D 6F 7A 4C 7A 34 30 00mozLz40.application/x-lz4+json.mozlz4 .jsonlz4Firefox's bookmark backups and session store. A deliberately non-standard LZ4 header, so the `lz4` command refuses these even though the compressed data inside is ordinary LZ4.
rzip stream052 5A 49 50RZIPapplication/x-rzip.rzThe idea lrzip was built from: look for repeats across hundreds of megabytes first, then compress what is left. Good on data that repeats itself far apart, such as a disk image.
qpress stream071 70 72 65 73 73 31 30qpress10application/x-qpress.qpBuilt for speed over ratio and used by MySQL backup tooling, where the compressor must not be the thing that slows the backup window down.
MS Compress archive (SZDD)053 5A 44 44 88 F0 27 33SZDD..'3application/x-ms-compress-szdd.dl_ .ex_What every DOS and early Windows install disk was full of. Files are named with the last character of the extension replaced by an underscore, so a compressed DLL is a .dl_ file.
MS Compress archive (KWAJ)04B 57 41 4A 88 F0 27 D1KWAJ..'.application/x-ms-compress-kwaj.dl_ .ex_The same three-byte constant as SZDD and a different fourth byte, because it is a second tool from the same shop with a header that can also record the original file name.
LHA archive (stored)22D 6C 68 30 2D-lh0-application/x-lzh-compressed.lzh .lhaMethod 0 is no compression at all. The tag sits at 2 because a one-byte header size and a one-byte checksum come first, and it names the algorithm rather than the file.
LHA archive (8 KiB window)22D 6C 68 35 2D-lh5-application/x-lzh-compressed.lzh .lhaThe method almost every .lzh in circulation uses. The number is the sliding window in kilobytes, so the magic tells a decompressor how much memory to allocate before it starts.
LHA archive (32 KiB window)22D 6C 68 36 2D-lh6-application/x-lzh-compressed.lzh .lhaA larger window, added when 32 KiB of working memory stopped being an unreasonable ask. Older decompressors simply refuse it, which is the cost of putting a parameter in a magic.
LHA archive (64 KiB window)22D 6C 68 37 2D-lh7-application/x-lzh-compressed.lzh .lhaThe largest window LHA defines. Still the default in Japan, where the format never went away, so a modern .lzh is usually one of this row or the 8 KiB one above.
LHA archive (directory entry)22D 6C 68 64 2D-lhd-application/x-lzh-compressed.lzh .lhaNot a compression method: the marker for a directory, which has a name and no contents. An archive of a folder can begin with one, which is why it turns up at the front of a file.
MoPaQ archive04D 50 51 1AMPQ.application/x-mpq.mpq .w3x .sc2mapBlizzard's game archive, with a hash table instead of a directory so a game can ask for a file by name without reading a listing. The 0x1A is DOS end-of-file, so `type` stops early.
ALZip archive041 4C 5A 01ALZ.application/x-alz-compressed.alzThe default archiver in Korea for years, so a download from a Korean site is as likely to be this as a ZIP. The fourth byte is a format version, not part of the name.
EGG archive045 47 47 41EGGAapplication/x-egg.eggALZip's later format, with an open specification and support for splitting and solid compression. The version numbers live in the two bytes after the name, minor first.
ZPAQ archive037 6B 53 747kStapplication/x-zpaq.zpaqAn append-only archive that stores the decompression program inside itself, so a future tool can read it without knowing today's algorithms. Slow, and deliberately so.
PAR2 recovery set050 41 52 32PAR2application/x-par2.par2Not an archive but its insurance: redundancy blocks that rebuild whatever parts of a set went missing. Written for Usenet, where a post routinely arrived with holes in it.
StuffIt archive (classic)053 49 54 21SIT!application/x-stuffit.sitThe four-byte mark of StuffIt 1 to 5, which is what most .sit files in old Mac archives actually are. The spelled-out 'StuffIt' of the later versions is a different header.
Java module04A 4D 01 00JM..application/x-java-jmod.jmodA ZIP with a four-byte header bolted on the front, holding one module's classes, native libraries and legal notices. You link these into a runtime; you never run one directly.
Java runtime image0CA FE DA DA....application/x-java-image.jimageThe single file that replaced rt.jar: every class in a linked runtime, indexed for lookup without decompression. Named to rhyme with the class file's 0xCAFEBABE, deliberately.
Java pack200 archive0CA FE D0 0D....application/x-java-pack200.packA JAR rearranged so that gzip could find the repetition in it, which mattered when applets arrived over a modem. Removed from the JDK in 2020, so a file like this is an artefact.
Git bundle023 20 76 32 20 67 69 74 20 62 75 6E 64 6C 65 0A# v2 git bundle.application/x-git-bundle.bundleA whole repository, or part of one, as a single file you can send by email. The header is a readable line so that a person who received one by accident can tell what it is.
Mercurial bundle048 47 31 30HG10application/x-mercurial-bundle.hgMercurial's equivalent of a Git bundle. The two characters after the version say how the payload is compressed, so the header names its own encoding before any of it is read.
Subversion dump053 56 4E 2D 66 73 2D 64 75 6D 70 2D 66 6F 72 6D 61 74 2D 76 65 72 73 69 6F 6E 3ASVN-fs-dump-format-version:application/x-subversion-dump.dump .svndumpA repository's whole history as a stream of records, which is how a Subversion repository moves between servers or into Git. The magic is the first header field's own name.
Android backup041 4E 44 52 4F 49 44 20 42 41 43 4B 55 50 0AANDROID BACKUP.application/x-android-backup.abWhat `adb backup` writes: readable header lines saying the version, whether it is deflated and whether it is encrypted, then a tar stream. The header stays plain text either way.
Android OTA payload043 72 41 55CrAUapplication/x-android-ota-payload.binThe update image inside an Android over-the-air zip, and the name is inherited from Chrome OS, where the updater was written. A big-endian version number follows the four bytes.
Bacula volume1242 42 30 32BB02application/x-bacula-volume.baculaA backup volume opens with a block header: a checksum, the block size and the block number, four bytes each, so the format's own name is only the fourth word in the file.
Acronis True Image backup0CE 24 B9 A2 20 00 00 00.$.. ...application/x-acronis-tib.tibA consumer whole-machine backup. Eight bytes with no printable run, which is the usual sign of a format that never expected a person to look at it in a text editor.
dump archive (big-endian)2400 00 EA 6C...lapplication/x-dump.dumpThe Unix filesystem dump writes a record type, two dates, a volume number, a tape address and an inode number before it identifies itself, so the magic is the seventh 32-bit field.
dump archive (little-endian)246C EA 00 00l...application/x-dump.dumpThe same number at the same offset in the other byte order, because the field was written in whatever order the machine used. One format needing two rows is the cost of that.
xfsdump archive078 46 53 64 75 6D 70 30xFSdump0application/x-xfsdump.dump .xfsdumpXFS ships its own dump tool rather than using the generic one, because it needs to record extended attributes and extent layouts the older format has nowhere to put.
Blocked GNU zip (BGZF)1242 43 02 00BC..application/x-bgzf.bgz .bgzf .bam .tbiA gzip file with a mandatory extra field naming each block's length, which turns a format you must read from the start into one you can seek inside. Every BAM alignment file is one.
AppleSingle encoded file000 05 16 00....application/applefilenoneA Macintosh file is really two files, a data fork and a resource fork, plus a pile of Finder metadata. AppleSingle packs all of that into one ordinary stream so it can cross a filesystem that has never heard of forks.
AppleDouble encoded file000 05 16 07....application/applefilenoneThe same header with the last byte changed, and a completely different arrangement: the data fork stays where it is and everything else moves into a companion file beside it. Those are the ._name files that appear on a USB stick after a Mac has touched it.
Documents25 signatures
Documents file signatures (25)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
EPUB book306D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 65 70 75 62 2B 7A 69 70mimetypeapplication/epub+zipapplication/epub+zip.epubEPUB requires an uncompressed 'mimetype' entry as the first archive member, which pins this string at offset 30 of the surrounding ZIP. A rare case of a format legislating its own magic into a container.
PDF document025 50 44 46 2D%PDF-application/pdf.pdfThe version digits follow the dash. PDF is a mostly-textual format that tolerates leading junk in practice, which is why it is such a popular host for polyglot files.
Microsoft OLE2 compound file0D0 CF 11 E0 A1 B1 1A E1........application/x-ole-storage.doc .xls .ppt .msgThe pre-2007 Office container, and also .msi installers, Outlook .msg files, Visio drawings and the jump lists Windows keeps per program, so these eight bytes do not mean 'document'. It is a whole filesystem in a file. Which of those it holds is recorded in the root directory entry, and that entry is reached by following a sector pointer rather than sitting at a fixed offset, which is why the subtypes cannot be rows of their own.
Rich Text Format07B 5C 72 74 66 31{\rtf1application/rtf.rtfRTF is plain text with markup, so it can be read (and edited, and injected into) with any text editor. That readability is also its attack surface.
PostScript program025 21 50 53%!PSapplication/postscript.ps .epsPostScript is a full stack-based programming language, not a page image. A 'document' that is a program is a category worth noticing.
DjVu document041 54 26 54 46 4F 52 4DAT&TFORMimage/vnd.djvu.djvu .djvA scanned-document format from AT&T that separates text, background and foreground layers so a colour page scan stays small; the header is an IFF FORM tagged by AT&T.
Mobipocket e-book6042 4F 4F 4B 4D 4F 42 49BOOKMOBIapplication/x-mobipocket-ebook.mobi .prcThe pre-Kindle e-book format lives inside an old Palm database, so its own 'BOOKMOBI' identifier is 60 bytes in, after the Palm record header wrapping it.
Compiled HTML help049 54 53 46ITSFapplication/vnd.ms-htmlhelp.chmWindows help files are a small filesystem of compressed HTML under an 'ITSF' header, which is why a .chm opens like a tiny website rather than a single page.
WordPerfect document0FF 57 50 43.WPCapplication/vnd.wordperfect.wpd .wpThe word processor that ran the legal world: 0xFF then 'WPC', followed by a pointer to the document area, with formatting stored as reveal-codes between the text.
TeX DVI document0F7 02..application/x-dvi.dviTeX's device-independent output: 0xF7 then version 2, a page of typesetting commands with positions but no fonts embedded, resolved to paper or PDF by a later step.
Web archive (WARC)057 41 52 43 2FWARC/application/warc.warcThe format web crawlers store captures in: each record begins 'WARC/' with its own headers, so one file holds a whole crawl of requests and responses in order.
OpenDocument text306D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 6F 61 73 69 73 2E 6F 70 65 6E 64 6F 63 75 6D 65 6E 74 2E 74 65 78 74mimetypeapplication/vnd.oasis.opendocument.textapplication/vnd.oasis.opendocument.text.odtOpenDocument requires an uncompressed 'mimetype' member first, which pins the format's own name 30 bytes into the surrounding ZIP. A standard that legislated its own magic number.
OpenDocument spreadsheet306D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 6F 61 73 69 73 2E 6F 70 65 6E 64 6F 63 75 6D 65 6E 74 2E 73 70 72 65 61 64 73 68 65 65 74mimetypeapplication/vnd.oasis.opendocument.spreadsheetapplication/vnd.oasis.opendocument.spreadsheet.odsThe same rule as the text document, with the media type that says spreadsheet. The four OpenDocument kinds differ in exactly this string and nowhere else in the header.
OpenDocument presentation306D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 6F 61 73 69 73 2E 6F 70 65 6E 64 6F 63 75 6D 65 6E 74 2E 70 72 65 73 65 6E 74 61 74 69 6F 6Emimetypeapplication/vnd.oasis.opendocument.presentationapplication/vnd.oasis.opendocument.presentation.odpThe presentation flavour. Reading the media type out of the archive beats trusting the extension, because all four are the same ZIP with different XML inside.
OpenDocument drawing306D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 6F 61 73 69 73 2E 6F 70 65 6E 64 6F 63 75 6D 65 6E 74 2E 67 72 61 70 68 69 63 73mimetypeapplication/vnd.oasis.opendocument.graphicsapplication/vnd.oasis.opendocument.graphics.odgThe drawing flavour, and the one people are most surprised to find is a ZIP full of XML rather than a picture.
Office Open XML package305B 43 6F 6E 74 65 6E 74 5F 54 79 70 65 73 5D 2E 78 6D 6C[Content_Types].xmlapplication/zipnoneMicrosoft's packages name themselves the other way round: no declared media type, just a content-type map that producers put first by convention. Convention, not law, so its absence proves nothing and its presence is still only a strong hint.
Palm document6054 45 58 74 52 45 41 64TEXtREAdapplication/vnd.palm.pdbA Palm database records a four-character type and creator at byte 60, which is the same field a Mobipocket e-book uses for 'BOOKMOBI'. One header, a whole family of formats.
Encapsulated PostScript (binary)0C5 D0 D3 C6....application/postscript.epsThe DOS wrapper around an EPS: a small binary header giving the offsets of the PostScript and of a preview image, so a word processor could show the picture without interpreting it.
PDF forms data025 46 44 46 2D%FDF-application/vnd.fdf.fdfThe answers to a PDF form, carried without the form. It borrows PDF's shape and version line but not its signature, so it is a separate format rather than a kind of PDF.
OneNote section0E4 52 5C 7B 8C D8 A7 4D.R\{...Mapplication/onenote.oneThe first half of a 16-byte Microsoft GUID, written little-endian, so the readable order of the identifier is not the byte order on disk.
InDesign document006 06 ED F5 D8 1D 46 E5......F.application/x-indesign.indd .indtAnother GUID, this one marking the first of the fixed-size pages InDesign writes its database of objects into. The layout on disk is a database rather than a document.
Microsoft Reader book049 54 4F 4C 49 54 4C 53ITOLITLSapplication/x-ms-reader.litTwo four-character tags run together, from the same family of Microsoft storage formats as compiled help. The books it holds were encrypted per reader, which is why so few open now.
AutoCAD drawing041 43 31 30AC10image/vnd.dwg.dwg'AC10' and then two digits naming the release, so AC1015 is the 2000 format and AC1032 the 2018 one. The version is the magic, which is why a drawing opens in some versions only.
Windows Write document031 BE 00 001...application/x-mswrite.wriThe word processor that shipped with Windows 3. Two of the four bytes are zero, so pair a match here with the file being small and old before believing it.
Encapsulated PostScript1545 50 53 46EPSFapplication/postscript.eps .epsf .epsi'%!PS-Adobe-3.0 ' is fifteen characters exactly, and what follows says this program draws one figure to be placed in a page rather than a document to be printed. It matches the generic PostScript row too, and the longer match has to lead.
Executables44 signatures
Executables file signatures (44)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
DOS/Windows executable (MZ)04D 5AMZapplication/vnd.microsoft.portable-executable.exe .dll .sys .scr .com .ocx .cpl .drv .efi .mui .msstyles .pyd .node .ax .acmMark Zbikowski's initials, and still the first two bytes of every Windows binary: each one begins with a 16-bit DOS program whose only job is to say it cannot run in DOS. A Python extension module (.pyd) and a Node native addon (.node) are ordinary DLLs under another name, which is why they are listed here rather than graded as a disguise.
ELF binary07F 45 4C 46.ELFapplication/x-elf.elf .so .o .ko .axf .node0x7F then 'ELF'. The high bit on the first byte keeps the magic out of the printable range on purpose, so an ELF cannot be mistaken for a script. A core dump is one of these too, which is why .core is listed here rather than on the rows below: every ELF matches this one, whatever its word size or byte order, so one entry covers a dump from any machine.
Mach-O binary (64-bit)0CF FA ED FE....application/x-mach-binary.dylib .bundle .o .so .node0xFEEDFACF stored little-endian, or 'feed face', with the trailing F marking 64-bit. Read the bytes in order and the joke is inside out. CPython names its extension modules .so even on macOS, where they are Mach-O bundles, so that name belongs here and not only to ELF.
Mach-O binary (32-bit)0CE FA ED FE....application/x-mach-binary.dylib .bundle .o .so .node0xFEEDFACE little-endian: the 32-bit ancestor, one bit different from its successor.
Mach-O universal binary0CA FE BA BE....application/x-mach-binary.dylib .o0xCAFEBABE, and a genuine collision: a Java class file begins with exactly the same four bytes, so only the word that follows can tell the two apart.
Java class file0CA FE BA BE....application/java-vm.class0xCAFEBABE again: Java picked it in 1995, Apple picked it later for fat binaries. This is what a real magic-number collision looks like.
WebAssembly module000 61 73 6D.asmapplication/wasm.wasmA zero byte then 'asm', so no text editor will ever mistake a module for source. The version word follows immediately.
Android DEX bytecode064 65 78 0A 30 33 35 00dex.035.application/x-dex.dex'dex', a newline, then the format version as ASCII digits: the version number is inside the magic, so old and new files are distinguishable at a glance.
Windows shortcut04C 00 00 00 01 14 02 00L.......application/x-ms-shortcut.lnkA shortcut carries an arbitrary command line and its own icon, which is exactly why .lnk files arrive as email attachments pretending to be documents.
Script with a shebang023 21#!text/x-shellscript.sh .bash .py .pl .rb .zsh .fishTwo bytes that tell the kernel which interpreter to run. This is executable content living inside a plain text file, the cheapest disguise there is. Two bytes is also very little: the AMR speech format opens with the same pair on purpose, so its header reads as a line of text, and that overlap is recorded here rather than reported as a second format.
LLVM bitcode042 43 C0 DEBC..application/x-llvm-bitcode.bcThe intermediate form a compiler emits before machine code: 'BC' then a two-byte magic. It is code, but for LLVM's virtual instruction set rather than any real processor.
Lua bytecode01B 4C 75 61.Luaapplication/x-lua-bytecode.luac .luaPre-compiled Lua: an escape byte then 'Lua'. The bytecode is tied to one interpreter build, so a chunk compiled elsewhere often will not load, which trips people up.
Shockwave Flash (uncompressed)046 57 53FWSapplication/x-shockwave-flash.swf'FWS' is an uncompressed Flash movie: a header then a timeline of tags, some of which are ActionScript bytecode, which is why a .swf was treated as executable content.
Shockwave Flash (zlib)043 57 53CWSapplication/x-shockwave-flash.swf'CWS' is the same Flash movie zlib-compressed after the eight-byte header; the letter is the only difference, so one format has three magics for its three compressions.
Shockwave Flash (LZMA)05A 57 53ZWSapplication/x-shockwave-flash.swf'ZWS' is the LZMA-compressed Flash variant added late in Flash's life; a player that only knew 'FWS' and 'CWS' would reject it, which stranded some content.
Erlang BEAM bytecode842 45 41 4DBEAMapplication/x-beam.beamA compiled Erlang module inside an IFF container: 'FOR1', a length, then 'BEAM' at offset 8, holding bytecode for the virtual machine that runs telephone switches and messaging.
Emacs Lisp bytecode03B 45 4C 43;ELCapplication/x-elc.elcCompiled Emacs Lisp opens with a ';ELC' comment so an old Emacs that cannot read the bytecode still treats the first line as a harmless comment rather than an error.
ELF binary (32-bit, little-endian)07F 45 4C 46 01 01.ELF..application/x-elf.elf .so .o .ko .axf .nodeThe two bytes that say how to read the rest live inside the magic's own 16-byte identification block, at 4 and 5, so a reader learns the word size and the byte order before it has to interpret a single field.
ELF binary (64-bit, little-endian)07F 45 4C 46 02 01.ELF..application/x-elf.elf .so .o .ko .axf .nodeClass 2, byte order 1: the shape of nearly every Linux binary on a desktop or a server. The generic four-byte ELF pattern still matches, and the longer row leads.
ELF binary (32-bit, big-endian)07F 45 4C 46 01 02.ELF..application/x-elf.elf .so .o .ko .axf .nodeByte order 2 is most-significant-byte-first, which is what PowerPC, SPARC and older MIPS wrote. A parser that assumed the other order reads every length in this file backwards.
ELF binary (64-bit, big-endian)07F 45 4C 46 02 02.ELF..application/x-elf.elf .so .o .ko .axf .nodeStill shipping: IBM's s390x mainframes are 64-bit and big-endian, which is why this combination is a live format and not a museum piece.
Mach-O binary (32-bit, big-endian)0FE ED FA CE....application/x-mach-binary.dylib .bundle .oThe same 0xFEEDFACE the little-endian row carries, written the way it reads. The magic is a number, so its byte order on disk is itself the declaration of the file's byte order.
Mach-O binary (64-bit, big-endian)0FE ED FA CF....application/x-mach-binary.dylib .bundle .oPowerPC 64-bit Macs, and the reason a matcher cannot simply look for 'feed face' in either direction: all four spellings are real files and each means something different.
Mach-O universal binary (64-bit offsets)0CA FE BA BF....application/x-mach-binary.dylib .oOne bit away from the CAFEBABE that a Java class file also claims, and that one bit is enough to end the ambiguity: nothing else uses 0xCAFEBABF.
Windows executable (DOS stub message)7854 68 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D 6F 64 65This program cannot be run in DOS modeapplication/vnd.microsoft.portable-executablenoneThe real Windows header sits wherever a little-endian number at 0x3C points, so it has no fixed offset and cannot be a row at all. This message can: the linker writes a 64-byte DOS header, a 14-byte real-mode program, then the sentence that program prints.
Java archive304D 45 54 41 2D 49 4E 46 2FMETA-INF/application/java-archive.jar .war .earA ZIP local file header is 30 bytes wide, and the runtime reads the archive as a stream, so the manifest has to arrive before the classes that depend on it. That practice, not a rule, is what pins the name here.
Python 3.11 bytecode0A7 0D 0D 0A....application/x-python-code.pycA little-endian counter that CPython bumps every time the bytecode changes, so a cached file compiled by another release is refused outright instead of crashing on an opcode the interpreter no longer has.
Python 3.12 bytecode0CB 0D 0D 0A....application/x-python-code.pycThe carriage return and newline after the counter are the same trap PNG sets: a transfer that helpfully translates line endings breaks the file where it can be seen, rather than somewhere in the middle.
Python 3.13 bytecode0F3 0D 0D 0A....application/x-python-code.pycThe number counts bytecode revisions, not releases, and climbs many times during a development cycle. Only the value a release ships with ends up in files, which is why a table like this one lists releases rather than every number ever assigned.
Python 3.14 bytecode02B 0E 0D 0A+...application/x-python-code.pycSince 3.11 each release starts at 2900 plus fifty times the minor version, so 3.14 begins at 3600 and its counter crosses into a new high byte. Anything reading only the second byte to spot a .pyc stopped working here.
WebAssembly component000 61 73 6D 0D 00 01 00.asm....application/wasm.wasmA core module says version 1 in the four bytes after the preamble; a component splits that word into a version and a layer and sets the layer to 1, so an older runtime rejects it at byte 8 instead of mis-reading its sections. The version is still pre-standard.
LLVM bitcode (wrapped)0DE C0 17 0B....application/x-llvm-bitcode.bcThe wrapper's magic is the number 0x0B17C0DE, which spells BITCODE, and because it is a number it lands on disk back to front. The bare bitcode magic beside it is two characters then two bytes, so that one reads forwards. Same file family, opposite conventions.
a.out executable (OMAGIC)007 01..application/x-executable.outOctal 0407, and on a PDP-11 that value is the instruction 'branch forward twenty bytes': the kernel could jump straight to byte 0 and the header stepped out of the way. This is where the phrase magic number comes from. Two bytes is weak evidence today.
a.out executable (ZMAGIC)00B 01..application/x-executable.outOctal 0413, the demand-paged variant: the header is padded out to a page so the text segment can be mapped straight from the file instead of copied. The layout of the file became an argument about virtual memory, not about disk.
Android DEX bytecode (038)064 65 78 0A 30 33 38 00dex.038.application/x-dex.dexVersion 038 arrived with Android 8 and added the instructions Java 8 default methods needed. Because the digits are inside the magic, an older runtime stops at byte 8 rather than part way through a method it cannot decode.
Android optimised DEX064 65 79 0A 30 33 36 00dey.036.application/x-odex.odexOne letter changes, 'dex' to 'dey', and the meaning changes completely: this has been rewritten for one device's runtime and is not portable to another. A whole compatibility boundary carried by a single byte.
AppImage (type 1)841 49 01AI.application/x-appimage.appimageThe first generation, which carried an ISO 9660 image. The mark goes at offset 8 because that is where ELF's identification block keeps a version byte and padding nobody uses.
AppImage (type 2)841 49 02AI.application/x-appimage.appimageA Linux application as one runnable file: an ELF loader with a SquashFS image appended. Both rows still match as ELF, and they should, because that is exactly what they are.
Shell archive1023 20 54 68 69 73 20 69 73 20 61 20 73 68 65 6C 6C 20 61 72 63 68 69 76 65# This is a shell archiveapplication/x-shar.sharAn archive that is a program: run it with a shell and it writes the files back out. The magic sits at 10 because '#!/bin/sh' and a newline come first, and it really does run.
Compiled AppleScript046 61 73 64 55 41 53FasdUASapplication/x-applescript.scptA .scpt is not the text you wrote, it is the compiled form, and osascript runs it. That makes it executable content under a name most people read as a document, which is why the audit treats a renamed one as a security finding rather than a filing error.
Linux kernel image (x86 bzImage)51448 64 72 53HdrSapplication/x-linux-kernelnoneThe kernel every PC boots. The tag is at 514 because the first 512 bytes are a boot sector, ending in the 0x55 0xAA signature at 510, and the setup code that follows opens with a two-byte jump over its own header. That sector once held real code, which printed 'Use a boot loader' if you tried to start a kernel from a floppy; the code is gone and the 512 bytes stayed, and a machine booting through EFI now finds a complete Windows executable header living in them. One file, three eras of firmware.
Linux kernel image (arm64)5641 52 4D 64ARMdapplication/x-linux-kernelnoneThe kernel inside every Android phone and every 64-bit Raspberry Pi. Two instructions, a load address, an image size, a flags word and three reserved slots come first, so the name lands at 56: the file says where to put it and how big it is before it says what it is. Those first two instructions are chosen so that their opcode spells 'MZ', which is how one image is both a kernel and an EFI application.
Linux kernel image (RISC-V)5652 53 43 05RSC.application/x-linux-kernelnoneThe same slot, 56 bytes in, on a completely different processor, because RISC-V copied the arm64 boot header field for field rather than inventing one. It got it wrong the first time: an earlier eight-byte identifier at 48 was meant to line up with arm64's and did not, so a second one was added at the offset that does, and the documentation says as much. The old field is deprecated and this is the one to read.
Linux kernel image (32-bit ARM zImage)3618 28 6F 01.(o.application/x-linux-kernelnoneThe self-extracting kernel a 32-bit ARM board loads. It opens with eight instructions that do nothing, on purpose: old boot loaders assumed a 32-byte header on the front and jumped straight over it, so thirty-two bytes of no-ops mean those loaders land on real code anyway. A branch follows, and the identifying word sits at 36 behind both.
Fonts14 signatures
Fonts file signatures (14)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
TrueType font000 01 00 00 00.....font/ttf.ttfVersion 1.0 written as a 16.16 fixed-point number, then the start of the table count: the magic is a version, not a name.
OpenType font (CFF outlines)04F 54 54 4FOTTOfont/otf.otfOpenType carrying PostScript outlines announces itself; OpenType carrying TrueType outlines uses the version number instead, so one format has two magics.
WOFF web font077 4F 46 46wOFFfont/woff.woffA compressed wrapper around an OpenType font, invented so fonts could be served over the web without shipping the installable original.
WOFF2 web font077 4F 46 32wOF2font/woff2.woff2The Brotli-compressed successor to WOFF; one character of the magic changed, which is how you can tell a server is serving the older one.
TrueType/OpenType collection074 74 63 66ttcffont/collection.ttcA collection bundles several fonts that share glyph outlines, so one file can carry a whole family without repeating the shapes every weight has in common.
TrueType font (Apple 'true')074 72 75 65truefont/ttf.ttfApple's alternative version tag for the same table format Microsoft's 0x00010000 version number introduces. One file layout, two ways of announcing it, and both are still current.
Embedded OpenType font344C 50LPapplication/vnd.ms-fontobject.eotThe magic is 34 bytes in, after the sizes, the flags and the ten-byte PANOSE description of the letterforms, and it is stored back to front because the field is a little-endian number.
PostScript Type 1 font (ASCII)025 21 50 53 2D 41 64 6F 62 65 46 6F 6E 74%!PS-AdobeFontapplication/x-font-type1.pfaA PostScript program that happens to draw letters, so it also matches the generic PostScript pattern. The longer match wins, which is the whole reason specificity is ranked.
PostScript Type 1 font (binary)080 01..application/x-font-type1.pfbThe same font wrapped in length-prefixed segments: 0x80 starts a segment and the 1 says this one is text. Two bytes, so weak on its own.
BDF bitmap font053 54 41 52 54 46 4F 4E 54 20STARTFONT application/x-font-bdf.bdfA bitmap font written entirely as readable text, one line per property and one block of hex digits per character, so the file can be edited in anything at all.
PCF bitmap font001 66 63 70.fcpapplication/x-font-pcf.pcfThe compiled form of a BDF font, and the name is spelled backwards because the four bytes are read as one little-endian number. The X Window System's screen fonts are these.
FontForge source053 70 6C 69 6E 65 46 6F 6E 74 44 42 3ASplineFontDB:application/vnd.font-fontforge-sfd.sfdNot a font a system can install: it is the editable source, with the curves as curves, from which a TrueType or OpenType file is later built.
Adobe font metrics053 74 61 72 74 46 6F 6E 74 4D 65 74 72 69 63 73StartFontMetricsapplication/x-font-afm.afmWidths and spacing only, with no letter shapes at all: this is what a typesetter needed to lay out a line before it ever had to draw one.
PC Screen Font (version 2)072 B5 4A 86r.J.application/x-font-linux-psf.psf .psfuThe font a Linux text console draws with before any graphical system starts: a bitmap per character and, in version 2, a table mapping them to Unicode. Four bytes with the high bit set in three of them, against version 1's two, which is why only this one earns a row.
Disk images49 signatures
Disk images file signatures (49)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
ISO 9660 disc image3276943 44 30 30 31CD001application/x-iso9660-image.isoThe primary volume descriptor sits 32 KiB in, past a system area reserved for boot code: a signature you cannot find by reading the first sector, or the first hundred.
GPT partition table51245 46 49 20 50 41 52 54EFI PARTapplication/x-gpt-image.img .gpt .rawThe GUID Partition Table header is the *second* 512-byte sector; the first holds a protective MBR that exists only to stop old tools from helpfully reformatting the disk.
QEMU QCOW image051 46 49 FBQFI.application/x-qemu-disk.qcow .qcow2'QFI' then 0xFB, with the format version immediately after, so qcow and qcow2 are told apart by a number, not by the magic.
VMware disk image04B 44 4D 56KDMVapplication/x-vmdk.vmdk'VMDK' with the bytes the other way round, because the header field is read as a little-endian word. Byte order leaks into the magic.
Hyper-V disk image076 68 64 78 66 69 6C 65vhdxfileapplication/x-vhdx.vhdxHyper-V's second-generation virtual disk; the 'vhdxfile' signature opens a log-structured format that survives a host crash mid-write far better than the original VHD.
SquashFS image068 73 71 73hsqsapplication/x-squashfs.squashfs .sqshA read-only compressed filesystem: 'hsqs' is 'sqsh' seen little-endian. Router firmware and Linux live images mount it directly, decompressing files as they are read.
cramfs image045 3D CD 28E=.(application/x-cramfs.cramfsA tiny read-only filesystem for embedded devices with very little storage; it predates SquashFS and caps files at a size that felt generous when it was written.
Master boot record51055 AAU.application/x-mbr.img .bin .mbrThe 0x55 0xAA boot signature ends the first 512-byte sector. It is only two bytes so it appears by chance too, which is why it sits at offset 510, not at the start.
FAT32 filesystem8246 41 54 33 32 20 20 20FAT32 application/x-fat.img .rawThe filesystem type string sits 82 bytes into the boot sector, past the jump instruction and the parameter block, so a FAT volume names itself well after its first byte.
NTFS filesystem34E 54 46 53 20 20 20 20NTFS application/x-ntfs.img .rawWindows' filesystem writes its OEM name 3 bytes in, right after the boot sector's jump, so 'NTFS' padded with spaces marks the volume without disturbing the boot code.
ext2/ext3/ext4 filesystem108053 EFS.application/x-ext.img .raw .ext4Unix filesystems leave the first 1024 bytes alone for a boot block, and this superblock's own magic is 56 bytes into it, so the two bytes that say ext land at 1080. One row covers ext2, ext3 and ext4: which one it is depends on flag words further on, not on the magic.
Minix filesystem10407F 13..application/x-minix-fs.img .rawMinix put its superblock at 1024 first and ext copied the convention, which is why these two rows sit forty bytes apart inside the same reservation. Two bytes is thin evidence on its own; the offset is what makes the row worth having.
F2FS filesystem102410 20 F5 F2. ..application/x-f2fs.img .rawA filesystem written for flash memory, so it never rewrites a block in place: the chip underneath erases in large groups, and changing one byte the ordinary way would cost a whole erase block.
EROFS filesystem1024E2 E1 F5 E0....application/x-erofs.img .raw .erofsA read-only compressed filesystem Android ships system partitions in. It claims the same 1024 boundary F2FS does, so a matcher looking there has to compare all four bytes rather than assume what it found.
XFS filesystem058 46 53 42XFSBapplication/x-xfs.img .rawOne of the few filesystems that names itself at byte zero: the superblock is the first thing on the volume with no boot reservation at all. Every number in it is big-endian, which is a trace of the IRIX workstations it was written for.
Btrfs filesystem656005F 42 48 52 66 53 5F 4D_BHRfS_Mapplication/x-btrfs.img .rawThe superblock is 64 KiB in and the magic is 64 bytes into that, behind a 32-byte checksum and a 16-byte filesystem id. The checksum comes first because everything after it is verified before any of it is believed.
ReiserFS filesystem (3.6)6558852 65 49 73 45 72 32 46 73ReIsEr2Fsapplication/x-reiserfs.img .rawTwelve bytes before the Btrfs magic, in the same 64 KiB superblock that two unrelated filesystems happened to choose. The version is inside the pattern: 3.5 spelled it ReIsErFs and the last release spelled it ReIsEr3Fs.
JFS filesystem327684A 46 53 31JFS1application/x-jfs.img .rawIBM's journalling filesystem, superblock at 32 KiB. The magic still says 1 while the format on disk is version 2: the pattern was frozen for compatibility and the version number moved to a field after it.
bcachefs filesystem4120C6 85 73 F6 66 CE 90 A9 D9 6A 60 CF 80 3D F7 EF..s.f....j`..=..application/x-bcachefs.img .rawThe magic is a 128-bit identifier generated once rather than a word chosen to be readable, so nothing can collide with it by accident. It sits at sector 8, 24 bytes into the superblock. A reader must also accept the older identifier inherited from bcache.
UFS filesystem (v1, little-endian)956454 19 01 00T...application/x-ufs.img .raw .ufsThe number is a date, 19 January 1954, the birthday of the engineer who wrote the filesystem. It sits 1372 bytes into a superblock that starts at 8192, which is how a four-byte pattern ends up at an offset nobody would guess.
UFS filesystem (v1, big-endian)956400 01 19 54...Tapplication/x-ufs.img .raw .ufsThe same date the other way round, because the superblock is written in the byte order of the machine that made the filesystem and a reader has to be willing to try both.
UFS filesystem (v2, little-endian)6690819 01 54 19..T.application/x-ufs.img .raw .ufsVersion 2 moved the superblock to 64 KiB and shuffled the same date into a different number, so a version 1 reader looking at 8192 finds nothing and stops rather than misreading a newer volume as an older one.
UFS filesystem (v2, big-endian)6690819 54 01 19.T..application/x-ufs.img .raw .ufsBig-endian version 2, as FreeBSD wrote it on SPARC and PowerPC. Four rows for one filesystem is what modelling both the superblock's location and the machine's byte order honestly costs.
SquashFS image (big-endian)073 71 73 68sqshapplication/x-squashfs.squashfs .sqshRead forwards this spells the name; the little-endian row beside it spells hsqs. One four-byte number, and which way round it lands tells you how to read every length in the rest of the image.
romfs image02D 72 6F 6D 31 66 73 2D-rom1fs-application/x-romfs.romfs .imgA read-only filesystem small enough to hold a rescue system in a few kilobytes, with no compression and no writing at all. The dashes are part of the pattern, so no ordinary word at the start of a text file can be mistaken for it.
JFFS2 filesystem085 19..application/x-jffs2.jffs2 .imgA journalling filesystem for raw flash, where every node carries this marker, so the pattern repeats all through the image instead of appearing once. Two bytes at offset zero is weak evidence and this row is honest about it.
UBI flash image055 42 49 23UBI#application/x-ubi.ubi .imgThe layer underneath a flash filesystem, which spreads writes over the chip so no block wears out first. Every erase block opens with this header, so the pattern marks both the image and each block inside it.
ReFS filesystem000 00 00 52 65 46 53 00...ReFS.application/x-refs.img .rawWhere NTFS keeps a jump instruction in the first three bytes, ReFS keeps zeros: it was never meant to be booted from, so the space a boot sector reserves for code is simply left empty and the name follows in the usual field.
exFAT filesystem345 58 46 41 54 20 20 20EXFAT application/x-exfat.img .rawThe same offset-3 name field NTFS uses, three trailing spaces included, because both are boot sectors and the field is eight bytes wide. This is what an SD card larger than 32 GB arrives formatted with.
HFS+ volume102448 2BH+application/x-hfsplus.img .hfs .dmgTwo printable bytes at the same 1024 boundary the Unix filesystems use, because a Mac volume also reserves its first two sectors for boot blocks. The version number follows immediately, and it is the version that says HFS+ rather than the letters.
HFSX volume102448 58HXapplication/x-hfsplus.img .hfs .dmgThe same filesystem with case-sensitive file names, and the entire difference is one letter in the same slot. It shares a media type with the row above, which is what keeps a volume named for either one quiet in the audit.
APFS container324E 58 53 42NXSBapplication/x-apfs.img .dmg .rawEvery object in Apple's newer filesystem opens with the same 32-byte header of checksum, identifiers and type, the container itself included, so the format's own name cannot appear before byte 32 however early you look.
LUKS encrypted volume04C 55 4B 53 BA BELUKS..application/x-luks.luks .img .rawLUKS then 0xBABE. The header is deliberately in the clear: it holds the key slots and the settings needed to unwrap them, so a disk can say it is encrypted, and how, without giving away anything that helps.
LVM2 physical volume5364C 56 4D 32 20 30 30 31LVM2 001application/x-lvm2-pv.img .rawA volume label may sit in any of the first four sectors, and the eight bytes naming the format are 24 bytes into that label, after its own id, the sector number it claims to be in and a checksum. Sector 1 is where the tools actually write it.
Linux swap area (4 KiB pages)408653 57 41 50 53 50 41 43 45 32SWAPSPACE2application/x-linux-swap.swap .img .rawThe signature is the last ten bytes of the first page, so everything before it can hold the header the kernel reads. On a machine with 4 KiB pages that puts it at 4086, and the page size is therefore part of the answer.
Linux swap area (64 KiB pages)6552653 57 41 50 53 50 41 43 45 32SWAPSPACE2application/x-linux-swap.swap .img .rawByte for byte the same pattern on a machine with 64 KiB pages, which is how IBM's POWER systems are usually set up. A swap area formatted for one page size is not usable on the other, and only the offset says which you have.
UDF disc image3276942 45 41 30 31BEA01application/x-udf-image.udf .iso .imgThe descriptor slot ISO 9660 made famous, one byte into sector 16, holding a different format's name. UDF is what a DVD or a Blu-ray actually uses; on a disc that carries both, this descriptor moves further along to make room.
High Sierra disc image3277743 44 52 4F 4DCDROMapplication/x-iso9660-image.iso .imgISO 9660's draft ancestor, in the same sector but eight bytes later, because its descriptor opens with the block's own address written in both byte orders before it gets round to naming the format.
Virtual PC disk image063 6F 6E 65 63 74 69 78conectixapplication/x-vhd.vhdNamed after the company Microsoft bought the format from. A fixed-size disk keeps this footer only at the end of the file; a growing one keeps a copy at the front, and that copy is what this row finds.
VirtualBox disk image647F 10 DA BE....application/x-virtualbox-vdi.vdiThe first 64 bytes are a sentence of English describing the file, so the number that identifies it begins where that fixed-size field ends. The number is 0xBEDA107F and it lands back to front, because it is a number and not a name.
EnCase evidence file045 56 46 09 0D 0A FF 00EVF.....application/x-ewf.e01 .ewf .s01The evidence container forensic tools write: a disk copied into numbered segments with checksums and a record of the case. The carriage return, newline and high-bit byte after the name are the usual trap for a transfer that translates line endings.
DwarFS image044 57 41 52 46 53DWARFSapplication/x-dwarfs.dwarfsA read-only image that deduplicates whole files and blocks before compressing, then mounts like a folder. Built for collections where the same bytes appear thousands of times.
Android sparse image03A FF 26 ED:.&.application/x-android-sparse.imgA partition image with its empty regions replaced by 'this many zero blocks', so a phone image transfers in minutes rather than hours. Not mountable until it is expanded again.
Compressed ISO image043 49 53 4FCISOapplication/x-compressed-iso.cso .ciso .zsoA disc image whose 2 KiB sectors are compressed one at a time, so a player can still seek. Three unrelated projects chose these four characters, and only later fields tell them apart.
MAME compressed hunks04D 43 6F 6D 70 72 48 44MComprHDapplication/x-mame-chd.chdMAME's archival disc and drive image: fixed-size hunks, each compressed independently and checksummed, so a twenty-year-old dump can still be verified block by block.
Encrypted disk image065 6E 63 72 63 64 73 61 00 00 00 02encrcdsa....application/x-apple-diskimage.dmg .sparseimageAn ordinary .dmg cannot appear in this table because its descriptor is a trailer at the end of the file. Encrypting one moves the header to the front, and the version number after the name is why: version 1 wrote the same eight characters reversed, at the end. Finding these bytes at offset 0 is itself the version.
System Deployment Image024 53 44 49 30 30 30 31$SDI0001application/x-ms-sdi.sdiboot.sdi, on every Windows installation disc and every recovery partition. It is an empty RAM disk that the boot loader fills with a WIM image, which is how Windows manages to install itself onto the disk it is currently running from.
Linux software RAID superblock (1.1)0FC 4E 2B A9.N+.application/x-linux-raid.img .rawThe record that says this disk is one member of an array, and which member. Version 1.1 puts it at the very start. The number is stored little-endian whatever the machine, which is the fix for version 0.90 writing it in the host's own order and leaving a big-endian array unreadable on a little-endian rescue system.
Linux software RAID superblock (1.2)4096FC 4E 2B A9.N+.application/x-linux-raid.img .rawThe identical four bytes 4 KiB in, which is where mdadm puts them unless told otherwise. There is a third choice as well, version 1.0, which writes the record at the end of the device instead and so cannot have a row here at all. Same pattern, three placements, and the offset is the only thing that says which layout wrote the disk.
Data90 signatures
Data file signatures (90)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
RIFF container052 49 46 46RIFFapplication/x-riffnoneA generic chunk container that says nothing at all about content. The four-character form type at offset 8 is what decides whether this is sound, video or a picture.
SQLite 3 database053 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00SQLite format 3.application/vnd.sqlite3.sqlite .sqlite3 .dbSixteen bytes including the terminating zero, one of the most specific signatures in common use, and a reminder that many apps' 'data files' are just databases. A great many formats are simply this one with rules about the tables inside, and several of them stake their claim in the application id field 68 bytes further in.
Git pack file050 41 43 4BPACKapplication/x-git-packed-objects.packThe object bundle Git transfers over the wire and stores in .git/objects/pack. Four printable bytes, so treat a lone match with suspicion.
Microsoft Access (Jet)453 74 61 6E 64 61 72 64 20 4A 65 74 20 44 42Standard Jet DBapplication/x-msaccess.mdbThe older Access database names its engine 4 bytes in: 'Standard Jet DB'. The engine string is how you tell a legacy .mdb from the newer .accdb without opening Access.
Microsoft Access (ACE)453 74 61 6E 64 61 72 64 20 41 43 45 20 44 42Standard ACE DBapplication/x-msaccess.accdbThe current Access format says 'Standard ACE DB' where the old one said Jet, a one-word change in the header that marks the engine switch behind the .accdb extension.
Outlook data file021 42 44 4E!BDNapplication/vnd.ms-outlook.pst .ostA whole Outlook mailbox in one file: '!BDN' opens a header for an internal node-and-block database, which is why a single corrupt .pst can lose years of mail at once.
NES ROM (iNES)04E 45 53 1ANES.application/x-nes-rom.nesThe iNES header a NES cartridge dump carries: 'NES' then 0x1A, followed by the sizes of the program and character banks an emulator needs to map the game into memory.
Packet capture (little-endian)0D4 C3 B2 A1....application/vnd.tcpdump.pcap.pcap .capA tcpdump/Wireshark capture written on a little-endian machine: the 0xA1B2C3D4 magic comes out byte-reversed, so the magic itself tells a reader which way to read every length.
Packet capture (big-endian)0A1 B2 C3 D4....application/vnd.tcpdump.pcap.pcap .capThe same capture written big-endian: the magic reads forwards. Each record that follows is one captured packet with a timestamp and the bytes seen on the wire.
Packet capture (pcapng)00A 0D 0D 0A....application/x-pcapng.pcapng .ntarThe modern capture format: a block-structured header whose magic doubles as a newline test, able to record several interfaces and comments the old single-stream pcap could not.
HDF5 dataset089 48 44 46 0D 0A 1A 0A.HDF....application/x-hdf5.h5 .hdf5 .he5A self-describing container for large scientific arrays; the signature copies PNG's high-bit and CR-LF trick, and inside is a filesystem of datasets with their own metadata.
NetCDF dataset043 44 46 01CDF.application/x-netcdf.nc .cdfClimate and ocean data's classic format: 'CDF' then a version byte. It stores gridded arrays with named dimensions so a file says what its axes mean, not just their sizes.
NumPy array093 4E 55 4D 50 59.NUMPYapplication/x-numpy.npyA single saved NumPy array: a high byte then 'NUMPY', then a short text header giving the data type and shape, so the raw numbers that follow can be read back exactly.
Apache Parquet050 41 52 31PAR1application/vnd.apache.parquet.parquetA columnar data format for analytics: 'PAR1' bookends the file at both ends, and storing each column together is what lets a query read only the fields it needs.
Apache Avro04F 62 6A 01Obj.application/avro.avroA row-oriented data format that embeds its own schema in the header, so a consumer can read records written years earlier without being told their layout separately.
MATLAB MAT-file04D 41 54 4C 41 42 20MATLAB application/x-matlab-data.matMATLAB's workspace save: a text description beginning 'MATLAB ' followed by version and byte-order marks, wrapping the matrices and structs a session held.
Esri shapefile000 00 27 0A..'.application/x-shapefile.shpThe core geometry file of a GIS shapefile: the big-endian file code 9994, then a header giving the bounding box of every point, line or polygon that follows.
GRIB weather data047 52 49 42GRIBapplication/x-grib.grib .grb .grb2The format weather models exchange forecasts in: 'GRIB' opens each record of a gridded field, heavily packed because a global run produces an enormous number of them.
Windows registry hive072 65 67 66regfapplication/x-ms-registry.dat .hivA registry hive on disk: 'regf' opens a database of the settings Windows and its programs keep, which is why these files are a first stop in a forensic examination.
Windows event log045 6C 66 46 69 6C 65 00ElfFile.application/x-ms-evtx.evtxThe modern Windows event log: 'ElfFile' then a zero byte, a chunked binary-XML store of logons, service starts and errors that investigations reconstruct a timeline from.
Windows prefetch453 43 43 41SCCAapplication/x-ms-prefetch.pfWindows records what a program loaded so it can start faster; the 'SCCA' tag sits 4 bytes in, after a version word, and the file's mere existence shows the program was run.
ICC colour profile3661 63 73 70acspapplication/vnd.iccprofile.icc .icmA colour profile's 'acsp' signature is 36 bytes into its header, after the size and device fields, describing how a monitor or printer's colours map to standard ones.
BitTorrent metainfo064 38 3A 61 6E 6E 6F 75 6E 63 65d8:announceapplication/x-bittorrent.torrentA .torrent is a bencoded dictionary, and 'd8:announce' is that dictionary opening with an 8-character 'announce' key: the tracker URL a client contacts first.
Windows program database04D 69 63 72 6F 73 6F 66 74 20 43 2F 43 2B 2B 20 4D 53 46 20 37 2E 30 30 0D 0A 1A 44 53 00 00 00Microsoft C/C++ MSF 7.00...DS...application/x-ms-pdb.pdbMSF is Multi-Stream Format: a debug database is a small filesystem in a file, with its own block size and page map, which is why tools open a .pdb rather than parse it. The carriage return, newline and end-of-file byte are the usual transfer trap.
Game Boy ROM260CE ED 66 66 CC 0D 00 0B 03 73 00 83 00 0C 00 0D 00 08 11 1F 88 89 00 0E DC CC 6E E6 DD DD D9 99 BB BB 67 63 6E 0E EC CC DD DC 99 9F BB B9 33 3E..ff.....s................n.......gcn.........3>application/x-gameboy-rom.gb .gbcForty-eight bytes of the Nintendo logo, at 0x104 because the four bytes before them are the cartridge's entry point. The boot ROM scrolls this in and then compares it, and halts if it differs, so the check is a trademark lock as much as a format tag.
Game Boy Advance ROM424 FF AE 51 69 9A A2 21$..Qi..!application/x-gba-rom.gba .agbThe same idea one console on: a logo the boot code verifies, this time at 4, because the first four bytes are an ARM branch instruction jumping over the header into the game.
Nintendo DS ROM19224 FF AE 51 69 9A A2 21$..Qi..!application/x-nintendo-ds-rom.nds .dsiByte for byte the Game Boy Advance logo, moved to 0xC0 to make room for a title and a game code at the front. Identical patterns in two formats, told apart by nothing but where they sit: the clearest argument in this table for modelling the offset.
Nintendo 64 ROM (big-endian)080 37 12 40.7.@application/x-n64-rom.z64 .n64A bus-configuration word the console reads before anything else, stored the way the cartridge holds it. This is the native order, and the reason the other two rows exist.
Nintendo 64 ROM (byte-swapped)037 80 40 127.@.application/x-n64-rom.v64The same word with each pair of bytes swapped, because the Doctor V64 copier read the cartridge sixteen bits at a time and wrote them out in its own order. A dump can be shaped by the machine that made it rather than by the format.
Nintendo 64 ROM (little-endian)040 12 37 80@.7.application/x-n64-rom.n64The same word again, fully reversed, as a PC-side tool wrote it. Three files can hold identical game data and share no leading bytes at all, which is why an emulator byte-swaps on load instead of trusting the extension.
Mega Drive ROM25653 45 47 41 20 4D 45 47 41 20 44 52 49 56 45 20SEGA MEGA DRIVE application/x-genesis-rom.md .gen .smdThe header cannot start before 0x100 because the 68000 reserves the first 256 bytes for its exception vectors, sixty-four addresses of four bytes each. The hardware's memory map decided where the format's name goes.
Genesis ROM25653 45 47 41 20 47 45 4E 45 53 49 53SEGA GENESISapplication/x-genesis-rom.gen .md .binThe same console under its American name, in the same sixteen-byte field. One machine, two markets, two signatures, and a matcher that knows only one of them misses half the shelf.
Master System ROM3275254 4D 52 20 53 45 47 41TMR SEGAapplication/x-sms-rom.sms .ggTucked into the last sixteen bytes of the first 32 KiB, so the header lives at the end of a memory bank rather than the start of a file. The boot ROM checks three such places; this is the one nearly every cartridge uses.
Anki deck package3063 6F 6C 6C 65 63 74 69 6F 6E 2E 61 6E 6B 69 32collection.anki2application/x-anki-package.apkg .colpkgA ZIP local file header is exactly 30 bytes wide, so a format that legislates its first member pins that member's name at 30. EPUB does it with 'mimetype'; Anki does it with the card database's file name.
Apple binary property list062 70 6C 69 73 74 30 30bplist00application/x-bplist.plist .bplist .webarchive .xcuserstate .icloudEvery setting on a Mac or an iPhone is a property list, and a property list is either XML or this. The version digits are inside the magic, so a reader learns which layout it is looking at before it reads a field. The object table sits at the end of the file, which is why a truncated one is unreadable even though its first bytes are perfect.
macOS Desktop Services Store000 00 00 01 42 75 64 31....Bud1application/x-apple-ds-storenoneThe file the Finder leaves in every folder it has ever displayed, recording icon positions and window sizes. It is named .DS_Store, so it has no extension at all: the whole name is the leading dot and a word. 'Bud1' names the buddy allocator the store is built on, four bytes after a version number of 1.
Apple bill of materials042 4F 4D 53 74 6F 72 65BOMStoreapplication/x-apple-bom.car .bomA store of named blocks inherited from NeXTSTEP. An installer keeps one to know which files it put where, and the compiled asset catalogue inside every app bundle is the same format again: Assets.car is a bill of materials whose blocks happen to be images.
Compiled Interface Builder file04E 49 42 41 72 63 68 69 76 65 01 00 00 00 09 00 00 00NIBArchive........application/x-nib.nibThe layout of a screen, frozen. Two little-endian words follow the name and are constant, so the magic is eighteen bytes rather than ten. Everything after them is a table of offsets, because the file is read by seeking rather than by parsing from the front.
NeXT/Apple typedstream273 74 72 65 61 6D 74 79 70 65 64streamtypedapplication/x-apple-typedstream.nibThe name is at 2 because a version byte comes first and then a length byte: the string is stored with its own length, so the format identifies itself using its own encoding. This is what NSArchiver wrote, and it is still what an iMessage database holds for the styled text of a message.
macOS alias / bookmark062 6F 6F 6B 00 00 00 00 6D 61 72 6B 00 00 00 00book....mark....application/x-apple-aliasnoneA pointer to a file that survives the file being moved or renamed, because it records the inode and the volume as well as the path. Two four-character tags each padded to eight bytes, which is the whole reason the magic is sixteen bytes of mostly nothing.
Swift module0E2 9C A8 0E....application/x-swift-module.swiftmoduleThe first three bytes are the UTF-8 encoding of the sparkles character, so the magic is an emoji. What follows is the compiler's serialised description of a module's public interface. Nothing executes it, which is why it is filed as data and not as a program.
Windows minidump04D 44 4D 50 93 A7MDMP..application/x-ms-dmp.dmp .mdmpWhat Windows writes when a program crashes: the stacks, the loaded modules and a slice of memory. The magic is six bytes because only half of the version field is fixed. Its low word must be 42899 and its high word is whatever the writer felt like.
Windows kernel crash dump (32-bit)050 41 47 45 44 55 4D 50PAGEDUMPapplication/x-ms-dmp.dmpThe blue-screen dump, MEMORY.DMP, which is a whole different thing from a minidump: this is the kernel's own copy of physical memory. Two four-character fields, a signature and a validity mark, and the second one is where the word size is declared.
Windows kernel crash dump (64-bit)050 41 47 45 44 55 36 34PAGEDU64application/x-ms-dmp.dmpThe same signature with the validity mark changed, because a 64-bit dump's every pointer and page number is twice as wide. A reader that ignored the difference would walk the memory map at half stride and find nothing.
Extensible Storage Engine database4EF CD AB 89....application/x-ms-ese.edb .datMicrosoft's other database, behind Active Directory, Exchange, Windows Search and the WebCacheV01.dat that holds a browser's history. The name sits at 4 because the first four bytes are the header page's own checksum: the page is verified before any of it is believed, exactly as Btrfs does at 65600.
Windows thumbnail cache043 4D 4D 4DCMMMapplication/x-ms-thumbcache.dbWindows keeps a copy of every picture it has ever drawn a thumbnail of, one file per size. The copies outlive the originals, which is why these turn up in investigations of files that were deleted long ago.
Windows prefetch (compressed)04D 41 4D 04MAM.application/x-ms-prefetch.pfFrom Windows 10 the prefetch file is compressed whole, so the SCCA tag the older row finds at offset 4 is not there at all. The fourth byte names the compression, and 4 is the Xpress Huffman variant every one of these uses.
Portable program database042 53 4A 42 01 00 01 00 00 00 00 00 0C 00 00 00 50 44 42 20 76 31 2E 30BSJB............PDB v1.0application/x-ms-pdb.pdb'BSJB' opens the metadata root that a .NET assembly also carries, and inside an assembly it sits wherever a data directory points, so it cannot be a row. A portable debug file is that same structure with nothing wrapped around it, which puts it at offset 0 and makes the version string a fixed twelve bytes further in.
Group Policy registry policy050 52 65 67 01 00 00 00PReg....application/x-ms-policy.polRegistry.pol is how a domain pushes settings to a machine, and it is not a registry hive: it is a list of key, value, type and data records that the client applies. The four characters are stored as a little-endian number, so they read forwards only by accident.
Inno Setup uninstall log049 6E 6E 6F 20 53 65 74 75 70 20 55 6E 69 6E 73 74 61 6C 6C 20 4C 6F 67 20 28 62 29Inno Setup Uninstall Log (b)application/x-innosetup.datThe unins000.dat sitting beside a great many Windows programs. It records every file, registry key and shortcut the installer created, which is exactly what an uninstaller needs and exactly what an inventory of a machine wants.
Windows event log (legacy)030 00 00 00 4C 66 4C 650...LfLeapplication/x-ms-evt.evtThe format .evtx replaced. The header announces its own size, 48 bytes, before it says what it is, and writes that size again at the end of itself so a reader can walk the structure from either direction. A circular log, so it overwrites its own oldest records.
Windows application compatibility database873 64 62 66sdbfapplication/x-ms-sdb.sdbThe shim database: a list of programs Windows knows are broken and the lies it tells them so they keep working. The tag is at 8 because a major and a minor version come first, and the major number really does change, so the honest pattern starts after it.
Berkeley DB (btree, little-endian)1262 31 05 00b1..application/x-berkeley-db.db .datThe magic sits at 12 because the metadata page opens with an eight-byte log sequence number and its own page number: the page says where it belongs before it says what it is. 0x053162 is the btree access method, and it is written in the byte order of the machine that made the file, so the magic doubles as the instruction for reading every field after it. A Bitcoin wallet.dat is one of these.
Berkeley DB (btree, big-endian)1200 05 31 62..1bapplication/x-berkeley-db.db .datThe same number the other way round, written by a big-endian machine. Berkeley DB reads both and swaps as it goes, which is the whole reason the value is checked rather than the byte order being assumed.
Berkeley DB (hash, little-endian)1261 15 06 00a...application/x-berkeley-db.db .dat0x061561 is the hash access method rather than the btree one, in the same slot 12 bytes in. One file format, two shapes of index, and the number at 12 is the only thing on disk that separates them. RPM kept its package database in one of these for twenty years.
Berkeley DB (hash, big-endian)1200 06 15 61...aapplication/x-berkeley-db.db .datThe hash magic as a big-endian machine writes it. Four rows for one format looks extravagant until you notice that a reader which guessed wrong would read the page size as sixteen million rather than sixteen thousand.
BoltDB / bbolt database16ED DA 0C ED....application/x-boltdb.db .boltThe key-value store inside etcd, and so inside most Kubernetes clusters. Its page header is four fixed-width fields, a page id, flags, a count and an overflow count, so the meta page's 0xED0CDAED lands at exactly 16 on every machine. Compare LMDB, which has the same idea and puts a pointer-sized field first, so its offset depends on the build rather than on the format.
DuckDB database844 55 43 4BDUCKapplication/x-duckdb.duckdb .ddbThe analytics database people run in a notebook the way they run SQLite in an app. The name is at 8 because every block begins with its own eight-byte checksum, so the file is verified before it is identified. Byte for byte the reasoning behind Btrfs at 65600.
Redis database dump052 45 44 49 53REDISapplication/x-redis-rdb.rdbA point-in-time snapshot of a Redis server's memory. Four ASCII digits follow the name and give the format version, so a dump written by a newer server announces itself to an older one instead of being half-read. Five printable bytes, so treat a lone match with care.
PostgreSQL custom-format dump050 47 44 4D 50PGDMPapplication/x-postgresql-dump.dump .pgdump .backupWhat pg_dump writes with its custom format, and the only one of its three output shapes that has a signature at all: the plain form is SQL text and the directory form is a folder. Three version bytes follow the name, which is how pg_restore refuses a dump from a future release rather than misreading it.
MySQL binary log0FE 62 69 6E.binapplication/x-mysql-binlognoneThe replication log every MySQL and MariaDB server writes, and the thing point-in-time recovery replays. The first byte has its high bit set so the file cannot be mistaken for text, and the three that follow spell 'bin'. These files are numbered rather than extended, so the name they wear carries no format claim to check.
GNU dbm database (64-bit)0CF 9A 57 13..W.application/x-gdbm.gdbm .db .dbm0x13579acf, stored in the machine's own byte order, which on anything you are likely to hold means it reads backwards. The last digit of the magic is the point: 0x…cf is the build whose file offsets are 64 bits wide and 0x…cd is the 32-bit one, so the signature says how big the database is allowed to get.
GNU dbm database (32-bit)0CD 9A 57 13..W.application/x-gdbm.gdbm .db .dbmThe same store built where a file offset is 32 bits, so the database stops at 2 GB. One byte apart from its sibling and unreadable by a library expecting the other, which is why the two are separate rows rather than one fuzzy pattern.
Samba trivial database054 44 42 20 66 69 6C 65 0A 00TDB file..application/x-tdb.tdbSamba's little hash store, and where a domain member keeps its machine account and its share definitions. The magic is a sentence with a newline and a terminator on the end, sitting in a 32-byte field, so a printout of the header reads as a line of text.
SQLite rollback journal0D9 D5 05 F9 20 A1 63 D7.... .c.application/x-sqlite3-journal.db-journal .sqlite-journalThe file SQLite leaves beside a database while a transaction is open, holding the original pages so a crash can be undone. Eight bytes of deliberate nonsense with no readable text in them, because this header must never be mistaken for anything else. Its name is the database's whole name with '-journal' appended, so the part after the last dot is not a format at all.
SQLite write-ahead log037 7F 06 827...application/x-sqlite3-wal.db-wal .sqlite-walThe other way SQLite survives a crash: instead of copying the old pages aside, it appends the new ones here and folds them in later. This is the '-wal' file beside every browser profile and phone app database. The last byte of the magic is a flag, and 0x82 means the checksums in the file are computed little-endian.
SQLite write-ahead log (big-endian checksums)037 7F 06 837...application/x-sqlite3-wal.db-wal .sqlite-walThe identical header with the last byte one higher, which says the frame checksums were computed big-endian. The magic itself is stored big-endian either way, so the file states the arithmetic convention rather than leaving a reader to guess and reject good frames.
OGC GeoPackage6847 50 4B 47GPKGapplication/geopackage+sqlite3.gpkgA GeoPackage is a SQLite database with rules about which tables it holds, and the standard requires it to write these four characters into the application id field 68 bytes into SQLite's own header. A format that identifies itself inside another format's spare field, which is a tidier trick than inventing a new container.
OGC GeoPackage 1.06847 50 31 30GP10application/geopackage+sqlite3.gpkgWhat version 1.0 and 1.1 of the standard put in that same field before it settled on 'GPKG'. Same file extension, same container, four different bytes 68 in, and a reader that only knew the newer spelling would call an older map an ordinary database.
MBTiles tileset684D 50 42 58MPBXapplication/x-mbtiles.mbtilesMap tiles packed into a SQLite database, one row per tile. The specification asks for this application id and a great many writers skip it, so finding these bytes proves a tileset and not finding them proves nothing at all.
Audacity project6841 55 44 59AUDYapplication/x-audacity-project.aup3Audacity's newer project format is one SQLite database holding the samples, the labels and the edit history together, instead of the old .aup file with a folder of fragments beside it. It stakes its claim in the same application id field, 68 bytes in.
Apache Arrow file041 52 52 4F 57 31 00 00ARROW1..application/vnd.apache.arrow.file.arrow .featherThe on-disk form of the columnar layout data-science tools pass between processes without re-encoding. The magic is padded with two zero bytes to an eight-byte boundary because everything after it is meant to be read by pointing at it rather than by copying it, and alignment is what makes that safe.
Java serialized object0AC ED 00 05....application/x-java-serialized-object.serAn object graph written by ObjectOutputStream: 0xACED then the stream version, which has been 5 since Java 1.2. It is filed as data because nothing here executes on its own, but handing these bytes to readObject on a classpath you do not control is one of the best-known ways to lose a server.
systemd journal file04C 50 4B 53 48 48 52 48LPKSHHRHapplication/x-systemd-journal.journalThe binary log every systemd machine keeps, which is why journalctl exists and tail does not work on it. Eight letters chosen to be meaningless, so no text file can start this way by accident. The sealing key file beside it uses the same eight letters rotated.
Git index044 49 52 43DIRCapplication/x-git-indexnoneThe staging area: .git/index, a sorted list of every tracked path with the hash and the stat data Git compares against the working tree. 'DIRC' is short for directory cache, the name the file had first, and a four-byte version follows it.
Git pack index0FF 74 4F 63.tOcapplication/x-git-pack-index.idxThe .idx beside every .pack, mapping an object's hash to its offset so Git can seek instead of scanning. Set beside the 'PACK' row, this is the whole argument about magic numbers: the first byte here has its high bit set precisely so the header can never be confused with text, and the pack file's own four printable characters can.
GnuPG trust database001 67 70 67.gpgapplication/x-gnupg-trustdb.gpgtrustdb.gpg, which holds no key material at all: it records how far you have decided to trust each key, keyed by fingerprint. The leading byte is a record type and the version record is always first, so the readable part starts one byte in. Filed as data rather than as key material for exactly that reason.
Fossil repository680F 05 51 11..Q.application/x-fossil-repository.fossilThe version control system SQLite's own authors wrote, keeping the whole repository in one SQLite database rather than a directory of objects. It stakes the same application id field 68 bytes in that a GeoPackage does, and its source says plainly that the value is there so the file command can name it.
ELF core dump (x86-64)1604 00 3E 00..>.application/x-coredump.coreWhat a program leaves behind when it crashes: its memory, its registers and the list of libraries it had open. A core dump is an ELF file like any other, and the only thing that says so is the type field at 16, where an ordinary program says 2 or 3 and this says 4. The two bytes after it name the processor whose registers are inside.
ELF core dump (arm64)1604 00 B7 00....application/x-coredump.coreThe identical field on a 64-bit ARM machine, with 183 instead of 62 in the slot beside it. Two rows for one idea, because the machine number is part of what makes a dump readable: a debugger handed the wrong architecture cannot make sense of a single register.
GNU message catalog (little-endian)0DE 12 04 95....application/x-gettext-translation.mo .gmoEvery translated message a Linux program prints comes out of one of these. The magic is 0x950412de written in the byte order of the machine that compiled it, so a reader that finds it backwards knows to swap every field in the file rather than refusing to open it.
GNU message catalog (big-endian)095 04 12 DE....application/x-gettext-translation.mo .gmoThe same number the right way round, from a big-endian machine. Catalogues are built once and copied everywhere, so the format made byte order a property of the file instead of a property of the reader.
glibc locale archive009 01 02 DE....application/x-locale-archivenoneOne file holding every locale a system knows, so that starting a program does not mean opening a directory of small files per language. It is usually the largest thing in the C library's directory and almost nobody knows it is there.
Linux perf recording050 45 52 46 49 4C 45 32PERFILE2application/x-perf-data.dataWhat perf record writes: a stream of samples saying which instruction the processor was executing each time the clock ticked. The eight letters are stored as one 64-bit number rather than as text, so on a machine of the other byte order the same field reads '2ELIFREP' and the reader learns the layout from its own name. Version 1 spelt itself PERFFILE, with two Fs and no digit.
plocate database000 70 6C 6F 63 61 74 65.plocateapplication/x-plocate.dbThe index behind the locate command on a current Linux desktop, holding a compressed list of every path on the machine. The leading zero byte keeps the header out of the printable range, so the file cannot be mistaken for the list of names it contains.
mlocate database000 6D 6C 6F 63 61 74 65.mlocateapplication/x-mlocate.dbThe predecessor, which changed one letter of the magic and nothing else about the idea. Both files record who may see which path, because an index of every filename on a shared machine is a disclosure risk if it is read by the wrong person.
GCC coverage note file06F 6E 63 67oncgapplication/x-gcov-note.gcnoWritten when a program is compiled for coverage, describing every branch the code could take. The four letters read backwards because the compiler writes them as one 32-bit number in its own byte order, so a reader that finds 'gcno' the right way round knows to swap every field after it. The source says the magic must not be a palindrome, for exactly that reason.
GCC coverage data file061 64 63 67adcgapplication/x-gcov-data.gcdaThe counts collected when that program actually ran, written beside the note file it belongs to. Same reversal, and the pair only means anything together: one says what could have happened and the other says what did.
kdump compressed crash dump04B 44 55 4D 50 20 20 20KDUMP application/x-kdumpnoneWhat a Linux machine leaves behind after a kernel panic, once the memory has been squeezed down to the pages that were actually in use. The name is padded to eight characters with spaces because the field is eight wide and two other dump formats share it, so the padding is part of the signature. Its usual name is simply 'vmcore', with no extension at all, so the bytes are the only evidence there is. The Linux answer to a Windows MEMORY.DMP, and filed as data for the same reason: nothing runs a copy of memory.
SELinux binary policy08C FF 7C F9 08 00 00 00 53 45 20 4C 69 6E 75 78..|.....SE Linuxapplication/x-selinux-policynoneThe compiled rules a system enforces about which program may touch what, loaded into the kernel at boot. The header is a number, then the length of a string, then the string: the file says how long its own name is before it says the name, which is why sixteen bytes can be pinned instead of four. A loadable policy module writes a longer name in that same slot, so these sixteen bytes mean a whole policy and not a piece of one. The file is called policy followed by a version number, so it claims no extension either.
Text11 signatures
Text file signatures (11)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
XML declaration03C 3F 78 6D 6C<?xmlapplication/xml.xml .svg .xhtml .xsl .rss .atom .plist .gpx .kmlNot a binary signature at all, just the text a well-formed XML document usually opens with. An XML file without it is still valid, so absence proves nothing.
PEM-encoded block02D 2D 2D 2D 2D 42 45 47 49 4E 20-----BEGIN application/x-pem-file.pem .crt .cer .csr .key .ascBase64 between dashed labels. The label after 'BEGIN' is what decides whether you are looking at a public certificate or somebody's private key. OpenPGP and age borrowed the same frame for their armoured forms, so this row matches those too: the frame really does contain them, which is why they are listed here rather than treated as a coincidence.
UTF-8 byte-order mark0EF BB BF...text/plain.txt .csv .mdA UTF-8 BOM. It marks the *encoding*, not the format; whatever follows it decides that, and many parsers choke on it precisely because it is invisible.
M3U playlist023 45 58 54 4D 33 55#EXTM3Uaudio/x-mpegurl.m3u .m3u8A list of file names or web addresses, one per line, invented for Winamp and never standardised, then reused unchanged as the playlist that drives HTTP Live Streaming, so nearly every video watched on a phone begins with these seven characters.
PLS playlist05B 70 6C 61 79 6C 69 73 74 5D[playlist]audio/x-scpls.plsThe other playlist: a Windows INI file with numbered File, Title and Length keys. It can carry a station's name where an M3U carries only a path, which is why internet radio directories hand out these.
WebVTT subtitles057 45 42 56 54 54WEBVTTtext/vtt.vttThe captions a browser lays over a video: six characters, then timings in hours, minutes, seconds and thousandths with an arrow between them. It is plain text, so the words in it stay searchable and translatable without any tool at all.
Xcode project file02F 2F 20 21 24 2A 55 54 46 38 2A 24 21// !$*UTF8*$!text/x-pbxproj.pbxprojA comment used as an encoding declaration. The file is an old NeXTSTEP-style property list, which has no way to state its own character set, so Xcode writes the fact in a comment on the first line and refuses the file if a byte-order mark appears in front of it.
Windows registry export (REGEDIT4)052 45 47 45 44 49 54 34REGEDIT4text/x-ms-regedit.regA .reg file is a text script that regedit merges into the registry when double-clicked. This is the Windows 95 spelling, still accepted today, and its whole payload is stored in the machine's own code page, which is why the newer form exists.
Windows registry export (5.00, ANSI)057 69 6E 64 6F 77 73 20 52 65 67 69 73 74 72 79 20 45 64 69 74 6F 72 20 56 65 72 73 69 6F 6E 20 35 2E 30 30Windows Registry Editor Version 5.00text/x-ms-regedit.regThe Windows 2000 header written as plain bytes, which is what a text editor produces and what most .reg files found on the web are. It works, and it cannot carry a key name outside the current code page.
Windows registry export (5.00, UTF-16)257 00 69 00 6E 00 64 00 6F 00 77 00 73 00 20 00 52 00 65 00 67 00 69 00 73 00 74 00 72 00 79 00 20 00 45 00 64 00 69 00 74 00 6F 00 72 00 20 00W.i.n.d.o.w.s. .R.e.g.i.s.t.r.y. .E.d.i.t.o.r. .text/x-ms-regedit.regWhat regedit itself exports, and the offset is the lesson: the two bytes in front are a byte-order mark, so the text starts at 2 and every character after it is two bytes wide. Read it as ASCII and it looks like a word with a hole between every letter.
Remote Desktop connection073 63 72 65 65 6E 20 6D 6F 64 65 20 69 64 3A 69 3Ascreen mode id:i:text/x-ms-rdp.rdpA saved connection is a plain list of name, type and value lines, and Remote Desktop's own client always writes the screen mode first. That is the client's habit and not a rule of the format, which is the same kind of claim the DOS stub message makes.
Key material46 signatures
Key material file signatures (46)
FormatOffsetPattern (hex)PrintableMedia typeExtensionsWhy it looks like that
OpenSSH private key02D 2D 2D 2D 2D 42 45 47 49 4E 20 4F 50 45 4E 53 53 48 20 50 52 49 56 41 54 45 20 4B 45 59-----BEGIN OPENSSH PRIVATE KEYapplication/x-pem-file.key .pemThis is a private key. If you did not intend to be looking at one, stop and close it, and note that it also matches the generic PEM prefix, which is why specificity matters.
PGP armoured block02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50-----BEGIN PGPapplication/pgp.asc .pgp .gpg .sigAn ASCII-armoured OpenPGP message, key or signature: the rest of the label line says which of the three you have.
KeePass 2 database003 D9 A2 9A....application/x-keepass2.kdbxA KeePass password vault: the 0x9AA2D903 signature little-endian. Everything after the header is encrypted, so identifying it is as far as a byte reader can honestly go.
macOS keychain06B 79 63 68kychapplication/x-apple-keychain.keychainThe database behind every saved password, certificate and secure note on a Mac. Four bytes is thin evidence for most things and enough here, because what follows is encrypted and naming the file is as far as reading its bytes can honestly go.
macOS detached code signature0FA DE 0C C1....application/x-apple-code-signaturenone0xFADE0CC1, one of a family of magics beginning 0xFADE0C that Apple gave the parts of a code signature. The embedded form lives inside a Mach-O at an offset a load command points to, so it can never be a row here; only the detached form starts a file.
PEM certificate02D 2D 2D 2D 2D 42 45 47 49 4E 20 43 45 52 54 49 46 49 43 41 54 45 2D 2D 2D 2D 2D-----BEGIN CERTIFICATE-----application/x-pem-file.crt .cer .pemA public X.509 certificate: a name, a public key and somebody's signature over both. Public by design, so this is the one PEM label you can pass around freely. The closing dashes are part of the pattern, because without them this also matches a certificate signing request.
PEM certificate request02D 2D 2D 2D 2D 42 45 47 49 4E 20 43 45 52 54 49 46 49 43 41 54 45 20 52 45 51 55 45 53 54 2D 2D 2D 2D 2D-----BEGIN CERTIFICATE REQUEST-----application/x-pem-file.csr .req .pemWhat you send a certificate authority: the same name and public key, signed by the key itself rather than by anyone else. It proves you hold the private half without ever showing it, which is the whole design.
PEM private key (PKCS#8)02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 52 49 56 41 54 45 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN PRIVATE KEY-----application/x-pem-file.key .pem .p8This is a private key and it is not encrypted. The label says only 'PRIVATE KEY' because PKCS#8 wraps the algorithm name inside the base64 rather than in the label, so one spelling covers RSA, elliptic curve and everything since. If you did not mean to be looking at one, close it.
PEM private key (encrypted)02D 2D 2D 2D 2D 42 45 47 49 4E 20 45 4E 43 52 59 50 54 45 44 20 50 52 49 56 41 54 45 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN ENCRYPTED PRIVATE KEY-----application/x-pem-file.key .pem .p8The same structure with a passphrase over it, so the base64 is ciphertext and the header inside names the derivation the passphrase feeds. Reading the label is as far as anything here goes: identifying the file tells you nothing about the key and does not weaken it.
PEM RSA private key (PKCS#1)02D 2D 2D 2D 2D 42 45 47 49 4E 20 52 53 41 20 50 52 49 56 41 54 45 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN RSA PRIVATE KEY-----application/x-pem-file.key .pemThe older shape, where the algorithm is in the label and the numbers are written bare. Another private key, and one you still meet constantly because a decade of tutorials opened with the command that makes it.
PEM EC private key (SEC1)02D 2D 2D 2D 2D 42 45 47 49 4E 20 45 43 20 50 52 49 56 41 54 45 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN EC PRIVATE KEY-----application/x-pem-file.key .pemAn elliptic-curve private key in its own format rather than in PKCS#8's wrapper. Worth knowing that a PEM file may hold several blocks one after another, and openssl's own curve generator writes a parameters block first, which puts this label further down the file instead of at offset 0.
PEM public key02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 55 42 4C 49 43 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN PUBLIC KEY-----application/x-pem-file.pub .pemThe public half in the standard wrapper that carries its own algorithm name, so the same label serves RSA and elliptic curve alike. One word shorter than the private label and the opposite in every way that matters: this one is meant to be published.
PEM PKCS#7 bundle02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 4B 43 53 37 2D 2D 2D 2D 2D-----BEGIN PKCS7-----application/x-pem-file.p7b .p7c .p7s .pemA bundle of certificates or a detached signature, and the answer to an omission: the same structure in its binary form opens with an ASN.1 sequence tag and a length, which is not a signature and cannot be a row. Wrapped in a dashed label it becomes findable, which is a neat argument for text framing.
SSH2 public key (RFC 4716)02D 2D 2D 2D 20 42 45 47 49 4E 20 53 53 48 32 20 50 55 42 4C 49 43 20 4B 45 59 20 2D 2D 2D 2D---- BEGIN SSH2 PUBLIC KEY ----text/x-ssh-public-key.pubThe standardised text form of an SSH public key, and it is deliberately not PEM: four dashes with a space inside them rather than five with none, so a parser can tell the two framings apart on the first line. OpenSSH reads and writes it on request but stores the one-line form instead.
PGP public key block02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 50 55 42 4C 49 43 20 4B 45 59 20 42 4C 4F 43 4B 2D 2D 2D 2D 2D-----BEGIN PGP PUBLIC KEY BLOCK-----application/pgp.asc .gpg .pgpSomebody's public key, armoured as text so it survives being pasted into mail. OpenPGP borrowed the dashed label frame from PEM, which is why the generic PEM row matches this too and why the longer, specific label has to lead.
PGP private key block02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 50 52 49 56 41 54 45 20 4B 45 59 20 42 4C 4F 43 4B 2D 2D 2D 2D 2D-----BEGIN PGP PRIVATE KEY BLOCK-----application/pgp.asc .gpg .pgp .keyOne word different from the public block and the opposite meaning: this is an exported secret key. Usually passphrase-protected and sometimes not, and nothing in the header says which. Naming the file is all a byte reader can honestly do with it.
PGP message02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 4D 45 53 53 41 47 45 2D 2D 2D 2D 2D-----BEGIN PGP MESSAGE-----application/pgp.asc .gpg .pgpEncrypted or signed content in armoured form. The label is deliberately vague because the packet stream inside decides which, and the first packet usually names the key id it was encrypted to, so the envelope leaks the recipient even though the contents stay shut.
PGP detached signature02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 53 49 47 4E 41 54 55 52 45 2D 2D 2D 2D 2D-----BEGIN PGP SIGNATURE-----application/pgp.asc .sig .signA signature with no message in it, the .asc that sits beside a release tarball. It is useless on its own and that is the point: the thing it vouches for stays exactly as it was, byte for byte, instead of being wrapped in anything.
PGP signed message (clearsigned)02D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 53 49 47 4E 45 44 20 4D 45 53 53 41 47 45 2D 2D 2D 2D 2D-----BEGIN PGP SIGNED MESSAGE-----application/pgp.asc .txtThe compromise form: the text stays readable and the signature is appended in its own block underneath. A hash name follows on the next line, because a verifier has to be told which digest to recompute before it can check anything.
OpenSSH public key (Ed25519)073 73 68 2D 65 64 32 35 35 31 39 20ssh-ed25519 text/x-ssh-public-key.pubOne line of text: the algorithm name, a space, the key in base64, and a comment. The trailing space is load-bearing, because without it this pattern also matches an OpenSSH certificate, whose type name begins with these same eleven characters and then keeps going. A line in authorized_keys may start with options instead, and then nothing here matches.
OpenSSH public key (RSA)073 73 68 2D 72 73 61 20ssh-rsa text/x-ssh-public-key.pubThe same one-line shape with the older algorithm. The name is repeated inside the base64 as the first length-prefixed field, so the readable prefix and the encoded blob have to agree, and a line edited by hand usually stops working for exactly that reason.
OpenSSH public key (ECDSA P-256)065 63 64 73 61 2D 73 68 61 32 2D 6E 69 73 74 70 32 35 36 20ecdsa-sha2-nistp256 text/x-ssh-public-key.pubThe curve is in the type name rather than in a field, so P-256, P-384 and P-521 are three different algorithm strings for what is otherwise one scheme. This row covers the 256-bit curve, which is the one nearly every ECDSA key uses.
OpenSSH certificate (Ed25519)073 73 68 2D 65 64 32 35 35 31 39 2D 63 65 72 74 2D 76 30 31 40 6F 70 65 6E 73 73 68 2E 63 6F 6D 20ssh-ed25519-cert-v01@openssh.com text/x-ssh-public-key.pubNot a key but a key signed by a certificate authority, with a validity window and a list of principals inside it. This is how a fleet avoids copying authorized_keys everywhere. Its type name starts with the plain Ed25519 one, which is why that row's pattern ends with a space.
PuTTY private key050 75 54 54 59 2D 55 73 65 72 2D 4B 65 79 2D 46 69 6C 65 2DPuTTY-User-Key-File-application/x-putty-private-key.ppkPuTTY's own private key file, and the reason ssh-keygen grew an import option. A version digit follows the dashes and then the algorithm name, so the first line says both what made the file and what is in it. Private key material, whether or not a passphrase is set.
GnuPG keybox84B 42 58 66KBXfapplication/x-gnupg-keybox.kbxThe pubring.kbx in every modern GnuPG home. The name is at 8 because the file is a chain of length-prefixed blobs and the first one is a header blob: four bytes of length, a blob type, a version and two flag bytes come first, so the format identifies itself only after saying how far the next record is.
Java keystore (JKS)0FE ED FE ED....application/x-java-keystore.jks .keystoreSun's original keystore, holding certificates and password-protected private keys for a Java program. A four-byte version follows, and it has been 2 since Java 1.2. Worth knowing that this is a store of keys and not a key: filing it under key material rather than under databases is what puts it beside the things it holds.
Java keystore (JCEKS)0CE CE CE CE....application/x-java-jce-keystore.jceks .keystoreThe variant that can also hold plain secret keys, such as the symmetric key an application encrypts its own configuration with. Same tool makes both, same extension is often used for both, and only these four bytes say which one you have.
Password Safe database050 57 53 33PWS3application/x-passwordsafe.psafe3A Password Safe vault. Everything after the tag is a salt, an iteration count and then ciphertext, so identifying the file is the end of what reading bytes can tell you, the same honest limit the KeePass row runs into.
age encrypted file061 67 65 2D 65 6E 63 72 79 70 74 69 6F 6E 2E 6F 72 67 2F 76 31 0Aage-encryption.org/v1.application/x-age-encrypted.ageThe magic is a web address, which is unusual and deliberate: the format has no version negotiation, so the first line names the exact specification and a file written to a later one simply will not match. The recipient lines that follow say which keys can open it, not who holds them.
age encrypted file (armoured)02D 2D 2D 2D 2D 42 45 47 49 4E 20 41 47 45 20 45 4E 43 52 59 50 54 45 44 20 46 49 4C 45 2D 2D 2D 2D 2D-----BEGIN AGE ENCRYPTED FILE-----application/x-age-encrypted.ageThe same ciphertext wrapped in PEM's dashed frame so it can be pasted into a message. Third format in this table to borrow that frame, after PEM itself and OpenPGP, which is why the generic row matches all three and the label is what tells them apart.
OpenSSL encrypted data053 61 6C 74 65 64 5F 5FSalted__application/x-openssl-enc.encWhat openssl enc writes: the word, then eight random bytes of salt, then ciphertext. Nothing in the header names the cipher or the digest, so a file encrypted with one set of options and decrypted with another produces rubbish rather than an error. The salt is public by design and gives nothing away.
OpenSSL encrypted data (base64)055 32 46 73 64 47 56 6B 58 31U2FsdGVkX1application/x-openssl-enc.enc .b64 .txtThe identical file after openssl's base64 option, and the first ten characters are fixed for a lovely reason: ten base64 characters encode sixty bits, which is seven and a half bytes, so they cover the whole of 'Salted__' bar half a byte and the random salt only starts affecting the eleventh character.
AES Crypt encrypted file041 45 53 02AES.application/x-aes-encrypted.aesThe file the AES Crypt tools produce. Three letters and a version byte, and version 2 is what every current writer makes; it is the version that added the plain-text tags after the header naming the software that wrote the file. The payload itself stays shut.
minisign / signify signature075 6E 74 72 75 73 74 65 64 20 63 6F 6D 6D 65 6E 74 3A 20untrusted comment: application/x-minisign.minisig .sig .pub .keyOpenBSD's signify and its portable cousin minisign both open a signature, a public key and a secret key file with this same line, and the wording is a warning rather than a label: the comment on the first line is not covered by the signature, so anything it claims can be edited by anyone. The trusted comment inside a minisign signature is the one that is signed.
PEM certificate revocation list02D 2D 2D 2D 2D 42 45 47 49 4E 20 58 35 30 39 20 43 52 4C 2D 2D 2D 2D 2D-----BEGIN X509 CRL-----application/x-pem-file.crl .pemThe list of certificates an authority has withdrawn before their expiry date, signed so it cannot be edited on the way to you. Most are published in binary form, and this is what openssl writes when asked for text, so meeting one usually means somebody runs their own authority.
PEM trusted certificate02D 2D 2D 2D 2D 42 45 47 49 4E 20 54 52 55 53 54 45 44 20 43 45 52 54 49 46 49 43 41 54 45 2D 2D 2D 2D 2D-----BEGIN TRUSTED CERTIFICATE-----application/x-pem-file.pem .crtAn ordinary certificate with a block appended saying what this machine is willing to trust it for, plus the nickname it was filed under. The extra block is OpenSSL's own idea rather than part of X.509, and a plain certificate reader silently ignores it, so the same file means more to one program than to another.
PEM certificate request (Windows spelling)02D 2D 2D 2D 2D 42 45 47 49 4E 20 4E 45 57 20 43 45 52 54 49 46 49 43 41 54 45 20 52 45 51 55 45 53 54 2D 2D 2D 2D 2D-----BEGIN NEW CERTIFICATE REQUEST-----application/x-pem-file.csr .req .pemThe same signing request the shorter label carries, written the way Windows writes it: the certificate services interface encodes a request with this header, so every certreq output wears it. One structure, two spellings, and a tool that only knows the newer one reports a perfectly good request as unidentified text.
PEM DSA private key02D 2D 2D 2D 2D 42 45 47 49 4E 20 44 53 41 20 50 52 49 56 41 54 45 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN DSA PRIVATE KEY-----application/x-pem-file.key .pemA private key for the signature algorithm that lost. OpenSSH removed DSA outright in version 10, so a key like this can no longer be used for the job it was made for, and the file is still a secret worth handling as one. Finding a live one is usually a sign of something that has not been touched in a decade.
PEM RSA public key (PKCS#1)02D 2D 2D 2D 2D 42 45 47 49 4E 20 52 53 41 20 50 55 42 4C 49 43 20 4B 45 59 2D 2D 2D 2D 2D-----BEGIN RSA PUBLIC KEY-----application/x-pem-file.pub .pemThe bare modulus and exponent with no algorithm name around them, which is why the label has to carry the word RSA. The plain 'PUBLIC KEY' label names its own algorithm inside the base64 instead, and that is the one nearly everything writes now.
PEM Diffie-Hellman parameters02D 2D 2D 2D 2D 42 45 47 49 4E 20 44 48 20 50 41 52 41 4D 45 54 45 52 53 2D 2D 2D 2D 2D-----BEGIN DH PARAMETERS-----application/x-pem-file.pem .dhNot a key and not a secret: a large prime and a generator that two parties agree to use while working out a shared secret they never send. Web servers were configured with a file like this for years because the built-in parameters were too small to trust. Publishing it is fine, which is what makes it worth naming rather than guarding.
PEM elliptic-curve parameters02D 2D 2D 2D 2D 42 45 47 49 4E 20 45 43 20 50 41 52 41 4D 45 54 45 52 53 2D 2D 2D 2D 2D-----BEGIN EC PARAMETERS-----application/x-pem-file.pemUsually not a file at all but the first of two blocks: openssl's curve generator writes these parameters and then the private key underneath, in that order, and only when the output is text. That is why an EC key file often has its real label some way down the page rather than at offset 0.
OpenSSH public key (ECDSA P-384)065 63 64 73 61 2D 73 68 61 32 2D 6E 69 73 74 70 33 38 34 20ecdsa-sha2-nistp384 text/x-ssh-public-key.pubThe curve is part of the algorithm name rather than a field inside the key, so moving from the 256-bit curve to this one changes the first twenty characters of the file. Three curves, three separate names, one scheme.
OpenSSH public key (ECDSA P-521)065 63 64 73 61 2D 73 68 61 32 2D 6E 69 73 74 70 35 32 31 20ecdsa-sha2-nistp521 text/x-ssh-public-key.pubThe largest of the three curves, and the odd number is not a typo: this one is 521 bits rather than 512, because the prime it is built on is two to the 521 minus one. The name in the file is the only place that number appears.
OpenSSH public key (Ed25519, security key)073 6B 2D 73 73 68 2D 65 64 32 35 35 31 39 40 6F 70 65 6E 73 73 68 2E 63 6F 6D 20sk-ssh-ed25519@openssh.com text/x-ssh-public-key.pubA key held inside a hardware authenticator, the sort you tap. The 'sk' prefix marks it, and the blob carries an application string beside the public key so the same device can hold separate keys for separate services. The half that signs never leaves the device, so this file is only ever the public part and a handle to it.
OpenSSH public key (ECDSA P-256, security key)073 6B 2D 65 63 64 73 61 2D 73 68 61 32 2D 6E 69 73 74 70 32 35 36 40 6F 70 65 6E 73 73 68 2E 63 6F 6D 20sk-ecdsa-sha2-nistp256@openssh.com text/x-ssh-public-key.pubThe same hardware-backed idea on the older curve, which is what a security key made before Ed25519 support offers. At thirty-five characters this is the longest algorithm name in the table, and it is still just the first field of a single line of text.
Ansible Vault encrypted file024 41 4E 53 49 42 4C 45 5F 56 41 55 4C 54 3B$ANSIBLE_VAULT;application/x-ansible-vault.yml .yaml .vaultHow secrets ride along inside a configuration repository: the file is ordinary text, the first line names the format and the cipher, and everything under it is hex. It usually still ends in .yml, so the name says nothing and the header says everything.
4 severities

A verdict that shouts at every mismatch is ignored, so the grading distinguishes the alarming from the untidy. The severity is always stated in words, never carried by colour alone. These four lines are the analyzer's real output for four synthetic files.

Extension-mismatch severities
SituationFile nameSeverityThe verdict it prints
The bytes match the namephoto.pngMATCHThe bytes agree with the .png name: PNG image.
No signature, and none expectednotes.txtNOTEA .txt file has no magic bytes to check.
Two harmless formats disagreelogo.pngMISMATCHNamed .png, but the bytes are GIF image (89a).
An executable wearing a document's namedocument.pdfCRITICALNamed .pdf, but the bytes are a DOS/Windows executable (MZ).

This is generated in browser and is not sent to pah.moi servers.

About this tool3 paragraphs

Every other tool here needs you to already know the format: the JWT decoder wants a JWT, the cert analyzer wants a certificate. This is the one that answers what am I even looking at. A file called document.pdf whose first two bytes are 4D 5A is a Windows executable wearing a document's name: an extension is a claim, not a fact.

A signature is a claim too, and a weaker one than it looks. It says the first few bytes match a pattern, which is what a real file of that type would have and also what anything can be given: prepending a valid header to arbitrary data is trivial, and several formats deliberately nest inside others. So a match is a good reason to read the header fields underneath it, which is why they are read out field by field rather than summarised, and a mismatch is the finding worth acting on.

The file is read with the File API. Offline, file-forensics-cli <path> prints the same report.

Use it locally This tool has a native command line twin. Build file-forensics-cli from the site's source with:
cargo build --release --bin file-forensics-cli
Source and licence terms