Bytes → characters
Hex to ASCII Converter
Decode hexadecimal byte pairs into ASCII text, with control characters made visible instead of invisible.
—
—
How hex becomes text
Every ASCII character has a code number from 0 to 127, and every one of those numbers fits in a single byte — two hex digits. Decoding is therefore mechanical: split the hex string into pairs, turn each pair into a number, look the number up in the ASCII table.
- Split the hex string into pairs, working left to right.
48656C6C6Fbecomes 48, 65, 6C, 6C, 6F. - Convert each pair to its decimal value: 72, 101, 108, 108, 111.
- Look each value up in the ASCII table: H, e, l, l, o.
- Join the characters. The order never changes — unlike number conversion, nothing is reversed.
Worked example
48 65 6C 6C 6F 48 → 72 → H 65 → 101 → e 6C → 108 → l 6C → 108 → l 6F → 111 → o result → Hello
Landmarks in the ASCII range
You do not need the whole table memorised. Four anchor points let you estimate any byte, and the full ASCII hex table has all 128 codes when you do.
| Hex | Decimal | Character | Range starts |
|---|---|---|---|
| 20 | 32 | space | Printable characters begin |
| 30 | 48 | 0 | Digits 0–9 run to 39 |
| 41 | 65 | A | Capitals A–Z run to 5A |
| 61 | 97 | a | Lower case a–z runs to 7A |
| 7F | 127 | DEL | End of ASCII |
Upper and lower case differ by exactly 0x20 — one bit. 41 is A and 61 is a; 5A is Z and 7A is z. Flipping bit 5 changes case, which is why case conversion in C was historically a single bitwise operation.
Control characters
Bytes below 20 are control codes, not printable characters. They were designed for
teleprinters and most are now historical, but a handful still matter constantly. This converter
shows them as visible escapes rather than dropping them, so a decoded string never lies about its
own length.
| Hex | Name | Shown as | Still used for |
|---|---|---|---|
| 00 | NUL | \\0 | End of a C string |
| 09 | HT | \\t | Tab |
| 0A | LF | \\n | Newline on Unix, macOS, HTTP bodies |
| 0D | CR | \\r | Paired with LF on Windows and in HTTP headers |
| 1B | ESC | \\x1B | Start of a terminal escape sequence |
Seeing 0D 0A at the end of every line tells you the file came from Windows or a
network protocol. Seeing 0A alone tells you it did not. That distinction is invisible
in the decoded text and obvious in the hex.
Bytes above 0x7F
ASCII proper stops at 7F. Anything higher is not ASCII, whatever the surrounding
tool calls it — it belongs to some extension, and which one changes the meaning entirely.
The byte E9 is é in Latin-1, a completely different character in Windows-1252's
higher range, and the start of a three-byte sequence in UTF-8. Guessing wrongly is how mojibake
happens. If your input contains bytes above 7F, the
hex to text converter decodes them as UTF-8, which is almost certainly
what you want for anything modern.
Where you meet hex-encoded text
- Memory and file dumps — the classic hexdump layout puts hex bytes on the left and their ASCII rendering on the right, so you can spot strings inside binary data.
- Network captures — packet payloads are shown as hex, and protocol keywords are readable once decoded.
- Debug logs — binary buffers get logged as hex because it is safe to print and unambiguous.
- Firmware and ROM images — version strings and error messages sit in plain ASCII inside otherwise opaque data.
Frequently asked questions
How do I convert hex to ASCII?
Split the hex into pairs of digits, convert each pair to its decimal value, then look that value up as an ASCII character code.
What is 48 65 6C 6C 6F in ASCII?
Hello. Each pair is one character code.
What is 41 in ASCII?
Capital A. Lower case a is 61, exactly 0x20 higher, because case differs by a single bit.
Why do I get strange characters above 7F?
ASCII only defines codes 0 to 127. Higher bytes belong to an extension such as Latin-1 or UTF-8, and you have to know which one to decode them correctly.
What happens to an odd number of hex digits?
A zero is added on the left so the digits pair up. The converter tells you when it has done this, because an odd count usually means a character was lost.
Why are control characters shown as backslash escapes?
So the output never silently changes length. A tab or newline that just disappeared would make the decoded string misleading.