What is a hex to ASCII converter?
A hex to ASCII converter takes a string of hexadecimal digits — pairs of characters like 48 65 6C 6C 6F — and translates each pair back into the character it represents, producing readable text. Every pair of hex digits is one byte, and each byte maps to a character according to an encoding table. 48 65 6C 6C 6F becomes Hello because 0x48 is decimal 72, which is H, 0x65 is 101, which is e, and so on.
This is the reverse of encoding text into hex — the two operations together are what developers use to inspect raw bytes from sources that emit numeric data instead of text: network packet captures, memory dumps, database BLOB columns, file headers, cryptographic digests, and protocol logs. A packet capture tool does not print GET /, it prints 47 45 54 20 2F, and you need to decode it back to know what the packet contains.
This converter is built around that workflow. It accepts the six formats that hex actually arrives in — space-separated, comma-separated, 0x-prefixed, \x-prefixed, newline-separated, and continuous with no separator — auto-detects which one you pasted, and decodes it with the correct character encoding. It also shows every stage of the decode: the per-byte breakdown table with UTF-8 sequence grouping, the classic xxd-style hex dump, and a statistics summary so you can see at a glance whether the data is mostly text or mostly binary.
💡 Quick example. 47 45 54 20 2F 20 48 54 54 50 decodes to GET / HTTP. If you saw that hex in a network log, this converter tells you in one paste that it is the start of an HTTP request — no IDE or wireshark session required.
How hex to ASCII conversion works
The conversion is three steps, and every one of them is deterministic. Knowing them is what lets you verify the tool's output by hand.
- Split the hex string into two-digit pairs. Each pair is one byte.
48 65 6C 6C 6Fbecomes48,65,6C,6C,6F. - Convert each pair from hex to decimal.
0x48= 4×16 + 8 = 72.0x65= 6×16 + 5 = 101.0x6C= 6×16 + 12 = 108.0x6F= 6×16 + 15 = 111. - Map each decimal value to its character. 72 =
H, 101 =e, 108 =l, 108 =l, 111 =o.
Step 2 is just base-16 → base-10 arithmetic: the first digit is worth its value times 16, the second is worth its value. Step 3 depends entirely on the character encoding, which is why the encoding selector above matters.
ASCII, Latin-1 and UTF-8 — which encoding?
Hex bytes do not carry their own encoding. The same bytes C3 A9 mean one thing in UTF-8 (é) and something completely different in Latin-1 (two separate characters). The tool lets you pick which encoding to decode with, and the correct choice depends on where the hex came from.
| Encoding | Bytes per character | Range covered | Use it when… |
|---|---|---|---|
| ASCII | 1 | 0x00 – 0x7F (128 chars) | You know the data is strictly 7-bit — HTTP headers, JSON tokens, hex from a hex editor set to ASCII view. |
| Latin-1 (ISO-8859-1) | 1 | 0x00 – 0xFF (256 chars) | Data predates UTF-8 (legacy HTML, older databases, POSIX locale output) and you see bytes above 0x7F that are single characters. |
| UTF-8 | 1–4 | All Unicode | Any modern text — the default. Accented letters, emoji, non-Latin scripts all live here. |
The key insight: UTF-8 is a strict superset of ASCII. Every valid ASCII byte sequence is also a valid UTF-8 byte sequence and decodes to the same characters. That is why UTF-8 is the safe default — if your data is ASCII, UTF-8 gives the same answer; if your data has anything richer, UTF-8 handles it correctly where ASCII would have errored or shown garbage.
⚠ Mojibake is not corruption. When you decode a UTF-8 byte sequence as Latin-1, each 2-byte or 3-byte character becomes multiple single-byte characters. C3 A9 (UTF-8 for é) shows as é under Latin-1 — that classic garbled look is called mojibake. It is not a bug in the data, just the wrong decoder. Switch the encoding selector to UTF-8 and the correct character appears.
Spotting multi-byte UTF-8 sequences in hex
UTF-8 uses the high bits of the first byte of each character to encode the length of that character's byte sequence. This is why UTF-8 can represent every Unicode character while staying ASCII-compatible — and it is easy to spot once you know the patterns.
| First byte pattern | Range | Bytes in sequence | Typical content |
|---|---|---|---|
| 0xxxxxxx | 0x00–0x7F | 1 | English ASCII characters |
| 110xxxxx | 0xC0–0xDF | 2 | Latin accents, Greek, Cyrillic, Hebrew, Arabic |
| 1110xxxx | 0xE0–0xEF | 3 | Most CJK (Chinese, Japanese, Korean), Devanagari |
| 11110xxx | 0xF0–0xF7 | 4 | Emoji, historic scripts, less-common CJK |
| 10xxxxxx | 0x80–0xBF | — (continuation) | Every non-first byte of a multi-byte character |
Example: F0 9F 98 80. The first byte 0xF0 starts with 11110, so this is a 4-byte sequence. The three continuation bytes 0x9F, 0x98, 0x80 all start with 10. Together the four bytes represent U+1F600 GRINNING FACE. The per-byte table in this tool labels each byte with its role — "▶ Start · 4-byte seq" or "↳ Cont." — so you can see the boundaries without decoding by hand.
💡 Why this matters. If you are debugging a corrupted UTF-8 stream, the most common cause is a byte that breaks the pattern — a first byte that says "3-byte sequence" but only two continuation bytes follow, or a continuation byte (0x80–0xBF) at the start of a character. These produce the Unicode replacement character � in the decoded output. The per-byte table shows exactly where the pattern breaks.
Hex input formats this converter accepts
Hex arrives from different tools in different shapes. Some emit space-separated byte pairs, some emit a continuous run of digits, some prefix every byte with 0x, and C source code uses the \x escape. This tool handles all of the common forms and auto-detects which one you pasted.
| Format | Example | Where it comes from |
|---|---|---|
| Space-separated | 48 65 6C 6C 6F | xxd, hexdump, Wireshark byte view, most hex editors |
| Comma-separated | 48,65,6C,6C,6F | Language array literals, JSON arrays of bytes |
| 0x prefix | 0x48 0x65 0x6C | Python byte strings, Arduino, C hex literals |
| \x prefix | \x48\x65\x6C | C source code string escapes, Ruby, PHP |
| Newline-separated | 48 65 6C | Column output from scripts, one byte per line |
| Continuous | 48656C6C6F | URLs, hashes, base16 encoded strings, MD5/SHA digests |
Leave the format selector on Auto-detect and the tool reads the shape of your input. If you paste mixed formats in one input the tool will flag the first byte it cannot parse, rather than silently misreading the data.
Non-printable characters — what they are and how they show
Not every byte maps to a visible glyph. ASCII defines two ranges of control characters — 0x00 to 0x1F and 0x7F — that do not render as characters on screen. They exist for historical reasons (controlling teleprinters and terminals) and still appear constantly in real data:
| Byte | Name | Common use |
|---|---|---|
| 0x00 | NUL | String terminator in C; padding |
| 0x09 | HT (Tab) | Tab character in text files |
| 0x0A | LF (Line Feed) | Newline on Unix, macOS, and modern cross-platform text |
| 0x0D | CR (Carriage Return) | Part of CRLF line endings on Windows |
| 0x1B | ESC | ANSI escape sequences for terminal colours |
| 0x7F | DEL | Delete; appears as a result of bit-flip corruption |
The output has two tabs. Decoded shows the real characters — a 0x0A byte is an actual newline in the output, exactly as the source intended. Safe replaces each non-printable byte with a labelled placeholder like [LF] or [NUL] so you can see exactly where each control character occurs in the stream without the layout getting mangled. In the per-byte breakdown table they show up with their mnemonic name and are highlighted in amber; in the hex dump view they render as a middle dot ·, exactly as xxd does.
Reading the hex dump view
The hex dump below the result uses the classic layout that xxd, hexdump -C, and every graphical hex editor share. It is worth learning to read because once you can, you can inspect any binary file or memory dump in any hex tool.
| Column | Shows | Example |
|---|---|---|
| Offset | Byte position in hexadecimal (4 hex digits for up to 64KB, 8 for larger) | 00000000 |
| Hex bytes | 16 bytes per row, in hex, space-separated with a gap after the 8th byte | 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 |
| ASCII | The same 16 bytes rendered as printable characters; non-printable become a middle dot | Hello, World! |
When you see something unexpected in the ASCII column — for example a byte that should be e but reads as à — you have found a byte or byte sequence that is not valid for the encoding you selected, or a genuine endianness or alignment issue in the source data. The dump view makes these problems immediately visible.
Where people actually use this converter
- Network debugging. Packet captures, HTTP/2 binary frames, TCP payload dumps, TLS handshakes, and DNS responses all appear as hex. Decoding the headers into readable text tells you instantly what the protocol is doing —
47 45 54 20 2Fis a GET request,48 54 54 50 2F 31 2E 31isHTTP/1.1. - Reverse engineering and CTF challenges. Malware strings, obfuscated payloads, shellcode, and packet captures in capture-the-flag competitions all start as hex. Decoding to text is the first step of analysis.
- Database inspection. BLOB and BYTEA columns store raw bytes. When you query them, many database clients print the value as hex. This tool decodes it back to the text or binary structure it represents.
- Reading cryptographic output. MD5, SHA-1, SHA-256, and HMAC digests are conventionally printed as lowercase hex. When you want to inspect the underlying byte structure, decode to get the raw bytes.
- Serial port and embedded debugging. UART traffic, I2C and SPI bus captures, and firmware log dumps all arrive as hex byte streams. Decoding the text portions reveals the printable messages the device is emitting.
- Reading escaped strings from source code. C source uses
\xNNescapes for non-printable bytes; Python and Ruby use similar conventions. Pasting the escaped string into this tool reveals what the compiler will actually emit. - Inspecting file headers. Magic bytes at the start of files are conventionally written as hex.
50 4B 03 04is the ZIP/JAR magic;89 50 4E 47starts every PNG image;FF D8 FFstarts every JPEG. - Debugging character-encoding bugs. When text appears garbled in a web page or application, decoding the raw bytes here quickly tells you whether the problem is UTF-8 vs Latin-1 confusion, an invalid byte sequence, or a genuine data corruption.
Common mistakes when decoding hex to ASCII
- Pasting an odd number of hex digits. Each byte needs exactly two digits.
48656C6has 7 digits — which is 3.5 bytes — and the tool will flag it with a clear error telling you how many digits are missing. - Assuming all bytes are text. A byte like
0x00is a null terminator, not a character. In a C string it truncates everything after it; in a text file it means the file has embedded binary content. The breakdown table marks these as non-printable so you can spot them. - Using the wrong encoding. The most common mistake. If the decoded text looks garbled —
éwhere you expecté— you decoded UTF-8 bytes as Latin-1. Switch the encoding to UTF-8. - Mixing separators in one input.
48 65,6Cis three bytes with two different separators. Auto-detect cannot reliably parse mixed formats — the tool picks the most likely separator and flags the rest as invalid hex. - Confusing hex digests with hex text. A 32-byte MD5 digest is 64 hex characters — decoding it produces 32 mostly non-printable bytes, not a readable string. That is the correct behaviour, not a bug; cryptographic output is not text.
- Forgetting about byte order. If you are decoding a multi-byte value (like a 32-bit length field), the bytes may be in little-endian or big-endian order depending on the source. The bytes themselves decode fine either way, but the numeric value they represent depends on byte order.
- Expecting the input to survive exactly. Decoding is not always lossless — a UTF-8 sequence with an invalid byte becomes the Unicode replacement character
�rather than an exact round trip. That is the correct behaviour, but worth knowing if you plan to re-encode.
Privacy and data storage
Everything runs in your browser. The conversion, the byte breakdown, the hex dump rendering, the ASCII reference table filter, and the encoding conversion all happen locally in JavaScript using the native TextEncoder and TextDecoder APIs. Nothing you type is uploaded to a server. There is no account, no login, and no network request after the page has loaded — the tool works offline once the page is cached. Your input is not stored anywhere; refreshing the page clears it.
Limitations
- The converter handles bytes, not bits. Every hex digit pair is treated as one byte. If your data is a bit stream that is not byte-aligned, you need to pad it to a byte boundary first.
- Only three encodings are offered — ASCII, Latin-1 and UTF-8. UTF-16 and UTF-32 hex data needs a dedicated tool, because their byte-order marks and code-unit structure require different parsing.
- The tool assumes the hex is big-endian byte order internally, which is what "byte 0 is the first byte" means. It does not swap byte order for you — for that, use a dedicated byte-swap utility.
- Output is rendered in the browser; extremely large inputs (over 1 MB of hex) may take a moment to lay out in the per-byte table. The conversion itself is fast — the bottleneck is table rendering.
- The ASCII reference table covers the full 0x00–0xFF range but names are the standard Unicode names for the Latin-1 block, not the informal names some tools use.
- Non-printable bytes in the main output produce their real control effects. A 0x0A is a real newline in the decoded text — this is correct, and the "Safe" tab is available if you want to see placeholder markers instead.
- Invalid UTF-8 byte sequences decode to the Unicode replacement character
�. The converter does not attempt to "repair" the sequence or guess the intended encoding — that would hide real bugs.
Frequently asked questions
How do I convert hex to ASCII?
Split the hex string into two-digit pairs — each pair is one byte. Convert each pair from hex to decimal, then look up the ASCII character for that decimal value. For example, 48 65 6C 6C 6F is 72 101 108 108 111 in decimal, which maps to H e l l o.
What is 48 65 6C 6C 6F in ASCII?
48 65 6C 6C 6F decodes to the text "Hello". Each hex pair is one byte: 0x48=72="H", 0x65=101="e", 0x6C=108="l", 0x6C=108="l", 0x6F=111="o".
What formats of hex input does the converter accept?
Space-separated hex pairs (48 65 6C), comma-separated (48,65,6C), 0x-prefixed (0x48 0x65), backslash-x notation (\x48\x65), newline-separated, and continuous hex strings with no separator (48656C6C6F). Auto-detect reads the format from your input.
How does the converter handle non-printable characters?
The output has two tabs — Decoded shows the real characters (so 0x0A produces an actual newline), and Safe shows placeholders like [LF] for 0x0A and [NUL] for 0x00 so you can see every control character. The per-byte breakdown table shows the name and category of every non-printable byte.
Does it support UTF-8?
Yes. The encoding selector lets you choose ASCII (strict 7-bit), Latin-1 (ISO-8859-1, one byte per character), or UTF-8 (variable-width, up to four bytes per character). For text with emoji, accented letters, or non-Latin scripts, choose UTF-8. The per-byte table shows which bytes belong to which UTF-8 sequence.
Why does my accented character look garbled (mojibake)?
Mojibake happens when UTF-8 bytes are decoded as Latin-1 (or vice versa). For example, the two bytes C3 A9 are UTF-8 for é. If you decode them as Latin-1 you get é — two separate characters. Switch the encoding selector to UTF-8 and the correct character appears.
What is a hex dump and why is it useful?
A hex dump is a classic layout — used by tools like xxd and hexdump -C — that shows the byte offset on the left, the hex byte values in the middle, and the printable ASCII translation on the right. It is the standard format for inspecting binary files and network captures. The converter renders this view automatically for any input.
Why does my hex length have to be even?
Each byte needs exactly two hex digits. A hex string with an odd number of digits cannot be split into complete bytes — for example, 48656C6 has 7 hex digits, which is 3.5 bytes. The converter shows a clear validation error telling you how many digits are missing.
Can I convert text back to hex with this tool?
Yes. Switch to the ASCII → Hex direction, type or paste any text, and the tool converts each character into its hex byte representation. Output format is configurable — space-separated, comma-separated, 0x-prefixed, backslash-x, or continuous.
What is the difference between ASCII and UTF-8?
ASCII uses one byte per character and covers only 128 characters (English letters, digits, common punctuation, and control codes). UTF-8 uses one to four bytes per character and covers every character in every script — including accented letters, Greek, Cyrillic, Chinese, and emoji. UTF-8 is a strict superset of ASCII, so any ASCII text is also valid UTF-8.
What is the difference between ASCII and Latin-1?
ASCII covers only 0x00–0x7F (128 characters). Latin-1 (ISO-8859-1) extends this to 0x00–0xFF (256 characters), adding accented Western European letters like é, ñ, ü, and the pound, yen and cent currency symbols in the range 0x80–0xFF. Latin-1 is a strict superset of ASCII for the first 128 characters.
How do I spot multi-byte UTF-8 sequences in hex?
UTF-8 uses leading bits to signal sequence length. A byte starting with 0xxxxxxx (0x00–0x7F) is a standalone ASCII character. A byte starting with 110xxxxx (0xC0–0xDF) starts a 2-byte sequence. 1110xxxx (0xE0–0xEF) starts a 3-byte sequence. 11110xxx (0xF0–0xF7) starts a 4-byte sequence. Continuation bytes always start with 10xxxxxx (0x80–0xBF). The per-byte table labels these automatically.
Can I upload a file instead of pasting hex?
No. This tool is paste-based by design, so nothing is uploaded to a server. For inspecting files, use a local hex editor or a command-line tool such as xxd, and paste the hex output here.
Is anything I paste uploaded?
No. The entire conversion runs in your browser using vanilla JavaScript and the native TextEncoder / TextDecoder APIs. Nothing you type is uploaded, logged, or stored on a server. There is no account, no login, and no network request after the page loads — the tool works offline once cached.
What is the most common use case for a hex to ASCII converter?
Reading raw bytes from network captures, packet analyzers, memory dumps, database BLOBs, and cryptographic digests. When you see a hex string like 47 45 54 20 2F, decoding it to GET / tells you instantly that it is the start of an HTTP request — the kind of one-off question a full hex editor is overkill for.
Related tools on AIToolsPros
Sources & methodology
- ANSI X3.4-1986 (R1986) — American National Standard for Information Systems — Coded Character Sets — 7-Bit American National Standard Code for Information Interchange (7-Bit ASCII). The normative ASCII table for codes 0x00–0x7F.
- ISO/IEC 8859-1:1998 — Information technology — 8-bit single-byte coded graphic character sets — Part 1: Latin alphabet No. 1. The Latin-1 character mapping used by the "Latin-1" encoding option.
- IETF RFC 3629 — UTF-8, a transformation format of ISO 10646. The normative UTF-8 specification including the leading-bit pattern table.
- The Unicode Standard — the character names shown in the reference table.
- ECMAScript Language Specification — the
TextEncoderandTextDecoderAPIs used for encoding conversion. - Wikipedia — Hex dump, ASCII, Mojibake: reference documentation for the classic layout and character encoding concepts.