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

Published: (February 5, 2026 at 12:13 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

Hexadecimal Basics

Hexadecimal (base‑16) uses the symbols 0‑9 and A‑F.
Each hex digit represents 4 bits, so two hex digits represent one byte (8 bits).

DecimalHexBinary
000000
110001
991001
10A1010
11B1011
12C1100
13D1101
14E1110
15F1111

Why base‑16? 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.

ASCII assigns a number (0‑127) to each character. Converting hex to ASCII means translating those numbers back to their character representations.

Converting Hex to ASCII and Back

Example conversion

HexDecimalASCII
4872H
65101e
6C108l
6C108l
6F111o

Result: Hello 👋

Going the other direction is just as straightforward:

"Dev" → D(44) e(65) v(76) → 44 65 76

JavaScript

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

// ASCII → 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"

Python

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

# ASCII → 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"

Bash (using xxd and od)

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

# ASCII → Hex (continuous)
echo -n 'Hello' | xxd -p
# Output: 48656c6c6f

# ASCII → Hex (pretty, space‑separated)
echo -n 'Hello' | od -A n -t x1
# Output: 48 65 6c 6c 6f

Practical Applications

  • Packet captures (Wireshark, tcpdump) show payloads in hex. Spotting ASCII text in a 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
  • Web colors are hex values:

    color: #FF5733;   /* R:255 G:87 B:51 */
    background: #2D2D2D; /* Dark gray */
  • UTF‑8 encoding examples:

    CharacterUTF‑8 hex
    éC3 A9
    E2 82 AC
    🔥F0 9F 94 A5
  • File signatures (magic numbers):

    FormatHex signature
    PNG89 50 4E 47 0D 0A 1A 0A
    JPEGFF D8 FF
    PDF25 50 44 46 (%PDF)
    GIF47 49 46 38 (GIF8)
  • Memory addresses (e.g., from a crash dump):

    Segfault at address 0x7FFE4B2A1000
    Stack pointer: 0x00007FFEEFBFF5A0

Common Hex Formats

FormatExampleTypical Use
Space‑separated48 65 6C 6C 6FHex dumps, debuggers
No separator48656C6C6FURLs, hashes
0x prefix0x48, 0x65C/C++, memory literals
\x escape\x48\x65Python, string literals
% prefix%48%65URL encoding

ASCII vs. Extended/Unicode

EncodingCharacterHex bytes
ASCIIA41
UTF‑8ñC3 B1
UTF‑8E6 BC A2
UTF‑8🚀F0 9F 9A 80

ASCII covers only 0‑127 (7 bits). Values 128‑255 belong to “extended ASCII” (varies by code page). Modern text uses Unicode, which is encoded in UTF‑8 as shown above.

Pro Tip

Lowercase letters start at 0x61, uppercase at 0x41. The difference is always 0x20 (32). Toggling case is therefore just flipping one bit.

Handy Tool

For quick, in‑browser conversion without sign‑ups or tracking, try hextoascii.co – paste hex, get ASCII (and vice versa).

Conclusion

Hex encoding is a fundamental skill that resurfaces in network debugging, binary analysis, color codes, and encoding issues. Once you internalize the conversion process, you’ll recognize patterns in hex dumps without thinking about it.

What’s the weirdest hex‑debugging situation you’ve encountered? Share it in the comments!

Back to Blog

Related posts

Read more »