DEV Community

David
David

Posted on

Hex to ASCII and Back: A Practical Guide to Hex Encoding for Developers

If you've ever stared at a string like 48 65 6C 6C 6F and thought "that's probably text but I'm not decoding it in my head" — this one's for you.

Hex encoding is everywhere in development. Network packets, color codes, binary file inspection, memory addresses, character encoding debugging. Yet most developers treat it as a black box until they actually need to convert something.

Let's fix that.

What is Hexadecimal?

Hexadecimal (base-16) uses 16 symbols: 0-9 and A-F. Each hex digit represents 4 bits, which means two hex digits represent one byte (8 bits).

Decimal:     0  1  2  ... 9  10 11 12 13 14 15
Hex:         0  1  2  ... 9  A  B  C  D  E  F
Binary:      0000 0001 0010 ... 1001 1010 1011 1100 1101 1110 1111
Enter fullscreen mode Exit fullscreen mode

Why base-16 instead of base-10? Because computers think in binary, and hex maps perfectly to binary — every 4 bits = 1 hex digit. It's the most human-readable way to represent binary data.

How Hex to ASCII Conversion Works

ASCII assigns a number (0-127) to each character. When we convert hex to ASCII, we're translating those numbers back to their character representations.

Let's decode 48 65 6C 6C 6F:

Hex Decimal ASCII
48 72 H
65 101 e
6C 108 l
6C 108 l
6F 111 o

Result: Hello 👋

ASCII to Hex: The Reverse

Going the other direction is just as straightforward. Take each character, get its ASCII code, convert to hex:

"Dev" → D(44) e(65) v(76) → 44 65 76
Enter fullscreen mode Exit fullscreen mode

Code Examples

JavaScript

// Hex to ASCII
function hexToAscii(hex) {
  return hex.match(/.{1,2}/g)
    .map(byte => String.fromCharCode(parseInt(byte, 16)))
    .join('');
}

// ASCII to Hex
function asciiToHex(str) {
  return Array.from(str)
    .map(char => char.charCodeAt(0).toString(16).padStart(2, '0'))
    .join(' ');
}

console.log(hexToAscii('48656C6C6F')); // "Hello"
console.log(asciiToHex('Hello'));        // "48 65 6c 6c 6f"
Enter fullscreen mode Exit fullscreen mode

Python

# Hex to ASCII
def hex_to_ascii(hex_string):
    return bytes.fromhex(hex_string).decode('ascii')

# ASCII to Hex
def ascii_to_hex(text):
    return ' '.join(f'{ord(c):02x}' for c in text)

print(hex_to_ascii('48656C6C6F'))  # "Hello"
print(ascii_to_hex('Hello'))        # "48 65 6c 6c 6f"
Enter fullscreen mode Exit fullscreen mode

Command Line

# Hex to ASCII
echo '48656C6C6F' | xxd -r -p
# Output: Hello

# ASCII to Hex
echo -n 'Hello' | xxd -p
# Output: 48656c6c6f

# Pretty print with spaces
echo -n 'Hello' | od -A n -t x1
# Output: 48 65 6c 6c 6f
Enter fullscreen mode Exit fullscreen mode

Where You'll Actually Use This

1. Network Debugging

Packet captures (Wireshark, tcpdump) show payloads in hex. Being able to spot ASCII text in a hex dump is a fundamental debugging skill:

0000   47 45 54 20 2f 61 70 69  GET /api
0008   2f 75 73 65 72 73 20 48  /users H
0010   54 54 50 2f 31 2e 31     TTP/1.1
Enter fullscreen mode Exit fullscreen mode

2. CSS/HTML Colors

Every web developer works with hex colors daily:

color: #FF5733;  /* R:255 G:87 B:51 */
background: #2D2D2D;  /* Dark gray */
Enter fullscreen mode Exit fullscreen mode

3. Unicode and Character Encoding

Debugging encoding issues often means reading hex:

UTF-8 for 'é': C3 A9
UTF-8 for '€': E2 82 AC
UTF-8 for '🔥': F0 9F 94 A5
Enter fullscreen mode Exit fullscreen mode

4. Binary File Inspection

File signatures (magic numbers) are in hex:

PNG:  89 50 4E 47 0D 0A 1A 0A
JPEG: FF D8 FF
PDF:  25 50 44 46 (that's "%PDF" in ASCII!)
GIF:  47 49 46 38 ("GIF8")
Enter fullscreen mode Exit fullscreen mode

5. Memory Addresses and Pointers

Segfault at address 0x7FFE4B2A1000
Stack pointer: 0x00007FFEEFBFF5A0
Enter fullscreen mode Exit fullscreen mode

Beyond ASCII: Extended Character Sets

ASCII only covers 0-127 (7 bits). For the full byte range (0-255), you're in "extended ASCII" territory, which varies by encoding. For Unicode, hex encoding uses more bytes:

ASCII 'A':       41 (1 byte)
UTF-8 'ñ':       C3 B1 (2 bytes)
UTF-8 '漢':      E6 BC A2 (3 bytes)
UTF-8 '🚀':      F0 9F 9A 80 (4 bytes)
Enter fullscreen mode Exit fullscreen mode

Common Hex Formats You'll See

Format Example Context
Space-separated 48 65 6C 6C 6F Hex dumps, debuggers
No separator 48656C6C6F URLs, hashes
0x prefix 0x48, 0x65 C/C++, memory
\x prefix \x48\x65 Python, escape sequences
% prefix %48%65 URL encoding

Quick Reference: Printable ASCII

20 = SPACE    30 = 0    41 = A    61 = a
21 = !        31 = 1    42 = B    62 = b
22 = "        ...       ...       ...
2F = /        39 = 9    5A = Z    7A = z
Enter fullscreen mode Exit fullscreen mode

Pro tip: Lowercase letters start at 0x61, uppercase at 0x41. The difference is always 0x20 (32) — that's why toggling case is just flipping one bit.

Try It Yourself

If you're working with hex conversions regularly, having a tool that handles the conversion instantly saves time — especially when dealing with large blocks of hex data or non-ASCII characters.

hextoascii.co does exactly that: paste hex, get ASCII (and vice versa). No signup, no tracking, works entirely in your browser.


Hex encoding is one of those fundamentals that keeps showing up. Network debugging, binary analysis, color codes, encoding issues — once you internalize the conversion, you'll spot patterns in hex dumps without even thinking about it.

What's the weirdest hex debugging situation you've run into? Drop it in the comments 👇

Top comments (0)