rea-reverse

File type identifier and hex viewer

Drop any file, even one without an extension or several gigabytes large, to see what it is from its magic bytes, which signatures are embedded inside it, how its entropy changes from block to block and which strings it contains, with a hex view to check every byte yourself.

Your file never leaves your browser. The file is read in slices by a Web Worker that has no network access. Nothing is uploaded. How to verify this yourself

Drop any file here

or

Unknown extensions, CTF files, firmware dumps, archives, executables, images. Any size: the file is read in slices.

What this tool does not do

  • It reads signatures and headers; it does not unpack, decompress, decrypt or run anything. A match says what the bytes claim to be, so a damaged file can still match.
  • Formats without a signature, such as Protocol Buffers, raw C structs, Brotli streams or encrypted blobs, cannot be named from their bytes. High entropy only tells you the data is compressed or encrypted.

A file with no extension, a CTF attachment called chall, a firmware dump from a flash chip, a .bin from a vendor’s support site: the name tells you nothing, and double-clicking it is the wrong first step. What you want is what file and xxd would tell you, plus a quick look at what else is buried inside, before you choose the tool that actually opens it.

This page does that in the browser. It reads the file in slices, so a 2 GB disk image works the same way as a 2 KB .pyc, and nothing is uploaded.

What it shows

What the file is. The signature at offset 0, or at the fixed offset some formats use (tar at 257, ISO 9660 at 0x8001, ext2/3/4 at 0x438, the GPT header at 512, the DMG koly trailer 512 bytes from the end). Each result shows the matched bytes and their offset, a confidence level, and what the header says:

  • High: the signature matches and a structural check agrees, for example the ELF class and version bytes, a tar header checksum, a U-Boot header CRC32, a SquashFS block size that matches its log, or a Java class version in range.
  • Medium: the signature matches but cannot be checked further, or a check failed (the U-Boot CRC does not match, a declared size is larger than the file, a PNG does not end with its IEND chunk, a gzip stream stops before its end).
  • Low: a short or common pattern such as an MP3 frame sync, a zlib header or 55 AA at byte 510. Treat it as a hint.

Formats covered include:

  • Executables: ELF (architecture, 32/64-bit, byte order, type, OS/ABI), PE (PE32 or PE32+, machine, EXE or DLL, subsystem; a CLI header marks a .NET assembly), Mach-O (CPU, file type) and universal Mach-O with every slice’s architecture. CA FE BA BE is split into universal Mach-O and Java class by the next four bytes, the same rule file(1) uses.
  • Bytecode: Java class (with the Java version), DEX/ODEX/VDEX/ART, WebAssembly modules and components, .pyc with the Python version read from the magic number (2.x up to 3.15 development builds; pre-release magic numbers are flagged), Lua 5.1–5.5 and LuaJIT, Hermes (React Native) with its bytecode version, V8 code caches (bytenode .jsc), Erlang BEAM, Dart kernel.
  • Archives and compression: ZIP, gzip (original name and OS), xz, Zstandard, bzip2, 7z, RAR 4 and 5, LZ4, lzip, LZMA, Unix compress, CAB, ar and .deb, RPM, XAR (.pkg), CRX, tar (POSIX and GNU), cpio (newc, CRC, odc, binary), Electron ASAR.
  • ZIP-based formats, told apart by the names in the central directory: APK, AAB, APKS, XAPK, AAR, IPA, JAR, WAR, DOCX, XLSX, PPTX, EPUB, ODT/ODS/ODP, MSIX, VSIX, NuGet, Python wheel and egg, 3MF, KMZ, Fiddler SAZ, Firefox XPI and other WebExtension packages.
  • Firmware and file systems: SquashFS (version, compression, block size, image size; also the byte-swapped vendor magics), U-Boot uImage (name, OS, architecture, image type, compression, header CRC), Broadcom TRX, UBI and UBIFS, JFFS2 in either byte order, cramfs, romfs, device trees, Android boot.img and vendor_boot.img, Android sparse images (with the expanded size), OTA payload.bin, DTBO, ext2/3/4, FAT, NTFS, exFAT, GPT and MBR, ISO 9660, DMG, qcow, VMDK, VHDX, VDI, WIM, LUKS, Intel HEX and S-record.
  • Images, audio and video: PNG, JPEG, GIF, BMP, WebP, TIFF and raw formats built on it, ICO/CUR, PSD, QOI, ICNS, JPEG XL, JPEG 2000, HEIF/AVIF, MP4/MOV/M4A/3GP by their ftyp brand, WAV (codec, channels, rate), AVI, Ogg with the codec inside, FLAC, MP3, AAC, Matroska and WebM, FLV, MIDI, AIFF, MPEG-TS and PS, ASF.
  • Data, keys and text: PDF, OLE2 compound files, RTF, PostScript, binary and XML property lists, SQLite and its WAL, pcap and pcapng, Windows shortcuts, registry hives, event logs and minidumps, fonts, Git packs, Android binary XML and resources.arsc, X.509 certificates in DER, CMS / PKCS#7 SignedData in DER or BER (an iOS provisioning profile when the signed content is a plist with profile keys), PEM blocks by label, OpenSSH keys, Java keystores, and text formats recognized from their content: HAR, source maps, JSON, HTML, SVG, XML, scripts with a shebang, EVM bytecode as hex text.

Protocol Buffers cannot be identified. A serialized protobuf message, like a FlatBuffer, a raw C struct, a Brotli stream or anything encrypted, has no magic number: its first byte is just the first field’s tag. The tool says so instead of guessing, and the entropy graph and strings below are what you have to go on.

Open with. When the format has a tool on this site, the result links to it: the APK & AAB analyzer, the native binary overview for ELF, PE and Mach-O, the .NET metadata viewer, WASM to WAT, the ASAR unpacker, the HAR / SAZ summarizer, the source map restorer, the EVM selector extractor and, for provisioning profiles and IPAs, the iOS provisioning profile and IPA viewer. Pages do not pass files to each other, so you choose the same file again there.

Hex view. Offset, hex and ASCII columns for the whole file. Only the visible rows are read, so scrolling a multi-gigabyte image costs the same as a small one. The bytes that identified the file are highlighted. Jump to any offset in hex (0x8001) or decimal, click a byte, and drag or Shift+click to select a range: the panel underneath reads the first bytes as 8-, 16-, 32- and 64-bit integers (signed and unsigned, both byte orders), 32- and 64-bit floats and a Unix timestamp, and the selection as ASCII, UTF-8 and UTF-16LE text.

Embedded signatures. A binwalk-style pass over every byte of the file that reports each offset where a known header starts and passes its check: a gzip stream inside a firmware image, a SquashFS root file system after a uImage kernel, a PNG inside a PDF. Hits that fall inside a container with a declared length (SquashFS, uImage, TRX, device tree, cramfs, DEX, SQLite) are marked as nested. Repeating structures (JFFS2 nodes, UBI erase blocks, cpio and ZIP members) are reported once per run. Up to 1,000 hits are kept.

Entropy graph. Shannon entropy per block, about 1,024 blocks across the file (at least 1 KiB each). Flat zero is padding or erased flash, 4.5 to 6.5 is typical for code and text, and a plateau near 8 is compressed or encrypted data. Click the graph to jump to that block in the hex view.

Strings. Printable ASCII and UTF-16LE runs of at least 6 characters (adjustable from 2 to 64), each with its offset; click an offset to see it in the hex view. The first 20,000 are kept and can be filtered. On a large file the scan stops once it has that many, and says how far it got.

How it works

The page hands the file to a Web Worker, which reads the first 64 KiB with Blob.slice and runs it through the signature table. Each entry has the magic bytes, the offset they sit at and, where the format allows one, a check on the surrounding header fields; matching entries then read their details. For a ZIP the worker reads the central directory from the end of the file and names the format from the entries it lists. If nothing binary matches, the first 8 KiB are tested as text.

The worker then reads the whole file once more in 4 MiB slices for the embedded scan, the entropy blocks and the strings, posting progress as it goes. A two-byte index over the signatures keeps the scan to a table lookup per byte. The entropy and strings code is the same as the native binary overview uses. Peak memory stays around one slice no matter how large the file is.

We checked it against file 5.41 (macOS) and binwalk 3.1.0 on 98 sample files made for this purpose: archives from zip, tar, gzip, xz, zstd, 7zz, bzip2, lz4, cpio and mksquashfs (gzip, xz, lz4 and zstd), .pyc files from CPython 3.11, 3.12, 3.13 and 3.14, a SQLite database, images converted with sips, audio and video from ffmpeg, certificates from openssl, DMG, ISO and .pkg images from hdiutil and pkgbuild, ZIP-based packages laid out the way their packagers do, and this site’s own ELF, PE, Mach-O, APK, AAB, WASM, ASAR and HAR test files. For every sample the top result matched the format we built. file named the same format for 90 of them. The other eight are cases file 5.41 does not cover: it reports the four .pyc files (Python 3.11 to 3.14), an ASAR archive and an MPEG transport stream as data, a PEM private key as ASCII text, and a UDZO DMG as zlib compressed data (it does not look for the koly trailer). Across the corpus binwalk reported 53 offsets, and 51 of them are found here, at offset 0 by the identification or further in by the embedded scan. The other two are a “Copyright text” string binwalk flags in the color profile of the TIFF and JPEG 2000 images; it shows up here in the strings list. On a sample with a gzip file, a SquashFS image and a PNG appended at known offsets, both tools reported the same three offsets; this one also lists the xz-compressed blocks inside the SquashFS image, marked as nested.

For large files we tested a 2.5 GB sparse image with a gzip header at 0, a SquashFS image at 1 GiB and a PNG at 2 GiB: in Node.js 22 the whole scan took 10.4 seconds with a peak resident memory of 133 MiB, and all three were found at the right offsets.

How your files stay private

Your file is not uploaded:

  • Identification, the embedded scan, entropy and strings run in a Web Worker on your device; the hex view reads slices of the file in the page itself.
  • Everything taken from the file (names, labels, strings, bytes) is shown as plain text and never interpreted as HTML or run.
  • The only analytics event, filetype_identify, carries the outcome, the coarse kind and confidence of the top result (for example archive and high), a size bucket and a duration bucket. It never contains the file name, the format name, bytes, strings or offsets. The full list is on the privacy page.
  • The tool page shows no ads.

How to verify this yourself

  1. Open your browser’s developer tools and switch to the Network tab before you choose a file. Identify a file, scroll the hex view and change the strings length. The only requests are page assets and the worker script /_astro/filetype-worker-*.js; none carries your file.
  2. Or load the page, go offline (turn off Wi-Fi, or tick Offline in the Network tab) and identify a file. It still works.
  3. The worker runs under the Content Security Policy default-src 'none'; script-src 'self'; connect-src 'none', so the browser does not let it make any network request.

Limitations

  • A signature is a claim. A truncated or corrupted file still starts with the right bytes, and some formats are only recognizable by a short pattern. Only PNG (the IEND chunk at the end) and gzip files up to 8 MiB (test-inflated to the end of the stream) are checked for a missing end; a cut-off ZIP shows up because its central directory is gone. Other formats are not. The confidence level and the notes under each result say how much was checked.
  • No unpacking. Nothing is extracted, decrypted or executed, and nothing is decompressed except that end check on gzip files up to 8 MiB, whose output is thrown away. The embedded scan finds where things start; to carve them out, use binwalk -e, unblob or dd. The Binwalk 3 guide walks through it.
  • ZIP refinement needs the central directory: ZIP64 archives and ZIP files over 1 GiB are reported as plain ZIP with a note.
  • Text formats are recognized from the first 8 KiB, so a JSON file that only becomes a HAR further down is reported as JSON.
  • Embedded hits can be coincidences, especially inside compressed data, where any byte pattern can appear. Every scan signature needs four or more bytes or a header check, which keeps these rare but not impossible.
  • V8 startup snapshots (snapshot_blob.bin) have no stable signature and are not detected; only V8 code caches are.
  • Strings are printable ASCII (0x20–0x7e) in single bytes or UTF-16LE code units, as strings and strings -e l find them.

FAQ

Why is my .pyc reported with a “pre-release” note?

The magic number in the first two bytes changes during each CPython release cycle. The tool maps the whole range to the version and adds the note unless the number is that version’s final value, which means the file was written by an alpha, beta or release candidate.

The file is an APK but the result says ZIP.

The APK is told apart from other ZIP files by AndroidManifest.xml with classes.dex or resources.arsc in the central directory. If the directory cannot be read (a ZIP64 archive, a damaged file, or one over 1 GiB), the result stays at ZIP with a note.

What does an entropy of 8 tell me?

Only that the bytes look random. Compressed data, encrypted data and random keys all reach it. A firmware image is usually a mix: low entropy for the bootloader and padding, then a plateau near 8 where the compressed kernel and root file system start, which is also where the embedded scan tends to find their headers.

How is this different from file and binwalk?

file names the format from the start of the file, and binwalk scans for embedded signatures and extracts them. This page does the first two without installing anything and adds the hex view, entropy and strings, but it extracts nothing. Our signature table is our own, so its coverage differs from both. The comparison above lists where the results differ.

Compliance

Identify files you made yourself, open-source software, CTF challenges or files you are authorized to assess. Respect the licenses of the software you inspect, including any terms that restrict reverse engineering, and the laws that apply to you. See the disclaimer.