How to Read and Convert Hex Dumps: A Practical Guide

How to Read and Convert Hex Dumps: A Practical Guide

How to Read and Convert Hex Dumps: A Practical Guide

Try the Hex Converter

Somewhere in every developer's career, they stare at a wall of hex and think: "What am I looking at?"

Hex dumps are the raw truth of computing. Beneath every file, network packet, and memory address is a sequence of bytes — and hex dumps are how you see them. Whether you're debugging a corrupted file, analyzing a network capture, or reverse-engineering a binary protocol, reading hex dumps is a skill that pays off over and over.

This guide teaches you to read hex dumps fluently. You'll learn the format, master the command-line tools, identify files by their magic bytes, and write code that parses hex data programmatically.

What Is a Hex Dump?

A hex dump is a representation of binary data where each byte is shown as a two-digit hexadecimal number. Instead of showing you the raw binary (which would be unreadable streams of 1s and 0s), hex dumps present data in a compact, human-scannable format.

Every byte in a file is a value from 0 to 255 — or in hex, 00 to FF. A hex dump lines these up in rows, usually 16 bytes per line, with the ASCII interpretation shown alongside.

Anatomy of a Hex Dump

Here's a typical hex dump of a simple text file containing "Hello, World!\n":

00000000: 4865 6c6c 6f2c 2057 6f72 6c64 210a       Hello, World!.

Let's break down the three parts:

1. Offset (Address)

00000000: — The byte offset from the start of the file. This tells you where you are. The first byte is at offset 0, the 16th byte at offset 10 (hex for 16), and so on.

Offsets are always in hexadecimal. So 00000010 means byte 16, 00000020 means byte 32, and 000000FF means byte 255.

2. Hex Bytes

4865 6c6c 6f2c 2057 6f72 6c64 210a — The actual byte values in hexadecimal, grouped in pairs or quads depending on the tool. Each pair is one byte:

Hex Decimal ASCII
48 72 H
65 101 e
6c 108 l
6c 108 l
6f 111 o
2c 44 ,
20 32 (space)
57 87 W
6f 111 o
72 114 r
6c 108 l
64 100 d
21 33 !
0a 10 (newline)

You can paste these hex values into hextoascii.co and instantly see the decoded text.

3. ASCII Representation

Hello, World!. — The printable ASCII interpretation of the bytes. Non-printable characters (control codes, bytes above 126) are shown as . (dot). This column is your quick visual reference — it's what makes hex dumps readable at a glance.

Command-Line Tools for Hex Dumps

xxd — The Standard

xxd ships with Vim and is available on virtually every Unix system. It's the go-to tool.

# Basic hex dump
xxd file.bin

# Output:
# 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR

# Limit to first 64 bytes
xxd -l 64 file.bin

# Show in plain hex (no ASCII column)
xxd -p file.bin

# Set columns per line (default 16)
xxd -c 32 file.bin

# Reverse: convert hex dump back to binary
xxd -r hexdump.txt > restored.bin

# Seek to offset (skip first 100 bytes)
xxd -s 100 file.bin

The -r flag is gold. It means you can edit a hex dump in a text editor and convert it back to binary — poor man's hex editor.

hexdump — The Flexible One

hexdump (or hd) offers more formatting control:

# Canonical format (most readable, same as `hd`)
hexdump -C file.bin

# Output:
# 00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|

# First 32 bytes only
hexdump -C -n 32 file.bin

# Skip first 1024 bytes
hexdump -C -s 1024 file.bin

# Custom format: offset + hex bytes
hexdump -e '"%08.8_ax: " 16/1 "%02x " "\n"' file.bin

# Just the hex, no formatting
hexdump -v -e '/1 "%02x "' file.bin

od — The POSIX Classic

od (octal dump) is POSIX standard — available everywhere, even minimal systems:

# Hex output with ASCII
od -A x -t x1z -v file.bin

# Output:
# 000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52  >.PNG........IHDR<

# Two-byte hex words
od -A x -t x2 file.bin

# First 48 bytes
od -A x -t x1z -N 48 file.bin

Quick Comparison

Tool Best For Reverse? Everywhere?
xxd General use, binary editing -r flag Ships with Vim
hexdump Custom formatting Most Unix
od POSIX compliance POSIX standard

Reading a Hex Dump: Step-by-Step Walkthrough

Let's read a real hex dump. Here's the first 96 bytes of a PNG image:

00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 0100 0000 0100 0802 0000 00d3 107e  ...............~
00000020: 8f00 0000 0173 5247 4200 aece 1ce9 0000  .....sRGB.......
00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000  ..gAMA......a...
00000040: 0009 7048 5973 0000 0e74 0000 0e74 01de  ..pHYs...t...t..
00000050: 661f 7800 0020 0049 4441 5478 5ced ddb7  f.x.. .IDATx\...

Line 1 (offset 0x00):

  • 89 50 4E 47 → The PNG signature! (89 followed by PNG in ASCII)
  • 0D 0A 1A 0A → DOS/Unix line ending test bytes (part of the PNG spec)
  • 00 00 00 0D → Chunk length: 13 bytes
  • 49 48 44 52 → Chunk type: IHDR (image header)

Line 2 (offset 0x10):

  • 00 00 01 00 → Image width: 256 pixels
  • 00 00 01 00 → Image height: 256 pixels
  • 08 → Bit depth: 8
  • 02 → Color type: 2 (truecolor RGB)

Line 3 (offset 0x20):

  • 73 52 47 42 → Chunk type: sRGB (color space)

See the pattern? Once you know the file format, hex dumps become a conversation with the binary data. The offset tells you where to look, the hex tells you what's there, and the ASCII column gives you quick landmarks.

Common File Signatures (Magic Bytes)

Every file format starts with specific bytes — called magic bytes or file signatures. These let you identify a file regardless of its extension.

File Type Magic Bytes (Hex) ASCII Offset
PNG 89 50 4E 47 0D 0A 1A 0A .PNG.... 0
JPEG FF D8 FF ÿØÿ 0
GIF87a 47 49 46 38 37 61 GIF87a 0
GIF89a 47 49 46 38 39 61 GIF89a 0
PDF 25 50 44 46 2D %PDF- 0
ZIP 50 4B 03 04 PK.. 0
GZIP 1F 8B .. 0
ELF (Linux binary) 7F 45 4C 46 .ELF 0
Mach-O (macOS) FE ED FA CE þíúÎ 0
PE (Windows .exe) 4D 5A MZ 0
SQLite 53 51 4C 69 74 65 SQLite 0
MP3 (ID3) 49 44 33 ID3 0
MP4 66 74 79 70 ftyp 4
WASM 00 61 73 6D .asm 0

Quick File Identification

# Check the first 8 bytes of a mystery file
xxd -l 8 mystery_file

# Output: 89504e47 0d0a1a0a → It's a PNG!

# The `file` command does this automatically
file mystery_file
# mystery_file: PNG image data, 256 x 256, 8-bit/color RGB

This is incredibly useful when dealing with files that have wrong extensions, corrupted downloads, or data extracted from network captures. Knowing magic bytes lets you identify content without trusting metadata.

Converting Hex Dumps Programmatically

Python

# Read a file as hex dump
def hex_dump(filepath, bytes_per_line=16):
    with open(filepath, 'rb') as f:
        offset = 0
        while chunk := f.read(bytes_per_line):
            hex_part = ' '.join(f'{b:02x}' for b in chunk)
            ascii_part = ''.join(
                chr(b) if 32 <= b < 127 else '.' for b in chunk
            )
            print(f'{offset:08x}: {hex_part:<{bytes_per_line*3}}  {ascii_part}')
            offset += len(chunk)

hex_dump('example.bin')

# Convert hex string to bytes
hex_str = '48656c6c6f20576f726c64'
data = bytes.fromhex(hex_str)
print(data.decode('utf-8'))  # "Hello World"

# Convert bytes to hex string
text = 'Hello World'
hex_output = text.encode('utf-8').hex()
print(hex_output)  # "48656c6c6f20576f726c64"

# Parse a hex dump back to binary
import re

def parse_hex_dump(dump_text):
    """Extract raw bytes from a hex dump string."""
    result = bytearray()
    for line in dump_text.strip().split('\n'):
        # Remove offset and ASCII columns, keep hex bytes
        match = re.match(r'[0-9a-f]+:\s+((?:[0-9a-f]{2}\s*)+)', line, re.I)
        if match:
            hex_bytes = match.group(1).strip()
            result.extend(bytes.fromhex(hex_bytes.replace(' ', '')))
    return bytes(result)

# Identify file type by magic bytes
SIGNATURES = {
    b'\x89PNG': 'PNG image',
    b'\xff\xd8\xff': 'JPEG image',
    b'%PDF': 'PDF document',
    b'PK\x03\x04': 'ZIP archive',
    b'\x7fELF': 'ELF binary',
    b'MZ': 'Windows executable',
    b'SQLite': 'SQLite database',
}

def identify_file(filepath):
    with open(filepath, 'rb') as f:
        header = f.read(8)
    for sig, name in SIGNATURES.items():
        if header.startswith(sig):
            return name
    return 'Unknown'

print(identify_file('photo.png'))  # "PNG image"

JavaScript (Node.js)

const fs = require('fs');

// Generate a hex dump
function hexDump(buffer, bytesPerLine = 16) {
  const lines = [];
  for (let i = 0; i < buffer.length; i += bytesPerLine) {
    const slice = buffer.slice(i, i + bytesPerLine);
    const offset = i.toString(16).padStart(8, '0');
    const hex = [...slice]
      .map(b => b.toString(16).padStart(2, '0'))
      .join(' ');
    const ascii = [...slice]
      .map(b => (b >= 32 && b < 127) ? String.fromCharCode(b) : '.')
      .join('');
    lines.push(`${offset}: ${hex.padEnd(bytesPerLine * 3)}  ${ascii}`);
  }
  return lines.join('\n');
}

const buf = fs.readFileSync('example.bin');
console.log(hexDump(buf));

// Hex string to text
function hexToText(hex) {
  const clean = hex.replace(/\s+/g, '');
  const bytes = clean.match(/.{2}/g).map(b => parseInt(b, 16));
  return Buffer.from(bytes).toString('utf-8');
}

console.log(hexToText('48 65 6c 6c 6f')); // "Hello"

// Text to hex string
function textToHex(text) {
  return Buffer.from(text, 'utf-8')
    .toString('hex')
    .match(/.{2}/g)
    .join(' ');
}

console.log(textToHex('Hello')); // "48 65 6c 6c 6f"

Bash One-Liners

# Hex string to ASCII text
echo "48656c6c6f" | xxd -r -p
# Output: Hello

# ASCII text to hex string
echo -n "Hello" | xxd -p
# Output: 48656c6c6f

# Compare two binary files at hex level
diff <(xxd file1.bin) <(xxd file2.bin)

# Extract bytes at specific offset (bytes 4-7 of a file)
dd if=file.bin bs=1 skip=4 count=4 2>/dev/null | xxd -p

# Find a hex pattern in a file
xxd file.bin | grep "504b 0304"

# Patch a single byte at offset 0x10 to value 0xFF
printf '\xff' | dd of=file.bin bs=1 seek=16 conv=notrunc

Real-World Use Cases

Debugging Network Packets

When a REST API returns garbled data or a WebSocket connection drops, hex-dumping the raw bytes reveals the truth. Tools like Wireshark show hex dumps of every packet. You can identify:

  • Malformed headers
  • Encoding mismatches (UTF-8 vs Latin-1)
  • Unexpected null bytes in payloads
  • Protocol-level framing errors

If you capture raw bytes, paste them into hextoascii.co for quick visual decoding.

Forensics and Incident Response

Digital forensics relies heavily on hex analysis:

  • File carving: Finding files embedded in disk images by scanning for magic bytes
  • Metadata extraction: Reading EXIF data from images, embedded timestamps
  • Malware analysis: Examining PE headers, finding embedded strings
  • Data recovery: Identifying file boundaries in corrupted storage

Reverse Engineering Binary Protocols

When documentation doesn't exist (or lies), hex dumps are the source of truth. Compare hex dumps of different messages to spot patterns:

Request 1:  01 00 00 05 48 65 6c 6c 6f   → length=5, data="Hello"
Request 2:  01 00 00 03 48 69 21         → length=3, data="Hi!"

The pattern emerges: byte 0 is a type flag, bytes 1-3 are a big-endian length prefix, and the rest is the payload.

Validating File Integrity

After downloading or transferring files, a quick hex check of the header confirms the file isn't truncated or corrupted:

# Check that a downloaded ZIP starts with PK signature
xxd -l 4 download.zip
# Should show: 504b 0304 → PK..

Debugging Encoding Issues

When text looks wrong — mojibake, missing characters, invisible BOM markers — hex dumps show you the actual bytes. Is that é encoded as C3 A9 (UTF-8) or E9 (Latin-1)? The hex dump tells you instantly. Check our guide on text encoding formats for more on fixing encoding bugs.

Online Tools for Hex Analysis

Command-line tools are powerful but not always convenient. For quick conversions:

  • hextoascii.co — Convert hex to ASCII text and back. Paste hex bytes and instantly see the decoded output. Supports UTF-8 and multiple formats.
  • base64decode.co — When your data is Base64-encoded (common in APIs and email), decode it first, then hex-dump the result.

These are especially useful when you're reading logs, debugging on a machine without your usual tools, or just need a quick sanity check.

FAQ

What is a hex dump?

A hex dump is a display of binary data where each byte is represented as a two-digit hexadecimal number (00–FF). It typically shows three columns: the byte offset, the hex values, and the ASCII interpretation. It's used for inspecting files, debugging protocols, and analyzing binary data.

How do I create a hex dump on Linux or Mac?

Use xxd filename for a standard hex dump, hexdump -C filename for canonical format, or od -A x -t x1z filename for POSIX-compatible output. All three are pre-installed on most systems. Use -l N or -n N to limit output to the first N bytes.

How do I convert a hex dump back to a binary file?

With xxd, use the reverse flag: xxd -r hexdump.txt > output.bin. For plain hex strings (no offsets), use xxd -r -p hex.txt > output.bin. You can also use hextoascii.co for quick online conversion.

What are magic bytes?

Magic bytes (or file signatures) are specific byte sequences at the beginning of a file that identify its format. For example, PNG files start with 89 50 4E 47, PDFs with 25 50 44 46, and ZIP files with 50 4B 03 04. The file command on Unix uses magic bytes to determine file types.

How do I find a specific byte sequence in a file?

Use xxd file.bin | grep "pattern" for a quick search, or grep -boa -P '\x89\x50\x4e\x47' file.bin for binary pattern matching. Python's bytes.find() method works for programmatic searches.

What's the difference between hexdump, xxd, and od?

xxd is the most user-friendly and supports reverse conversion (hex dump to binary). hexdump offers the most formatting flexibility with custom format strings. od is the POSIX standard, guaranteed to exist on any Unix system. For most tasks, xxd is the best default choice.

Why do hex dumps show dots (.) for some characters?

The dots represent non-printable bytes — control characters (0x00–0x1F), DEL (0x7F), and extended bytes (0x80–0xFF). Only bytes in the range 0x20–0x7E (printable ASCII) are shown as their character representation. This prevents terminal escape sequences and invisible characters from breaking your display.

Can I edit a binary file using hex dumps?

Yes. With xxd: dump the file (xxd file.bin > hex.txt), edit hex.txt in any text editor, then reverse it (xxd -r hex.txt > modified.bin). For single-byte patches, use printf '\xNN' | dd of=file.bin bs=1 seek=OFFSET conv=notrunc. For serious hex editing, tools like hexedit or bless provide a proper GUI.

Convert Hex to ASCII Instantly

Paste hex strings and get readable text. Supports multiple formats, batch conversion, all client-side.

Open Hex Converter