UTF-8 Decode
Paste UTF-8 bytes in hex, decimal, binary, %XX or \x form and get the text back. The format is detected for you, bad bytes are pointed out one by one, and garbled text like Café is repaired to Café.
C3 A9 → é · %E2%82%AC → € · \xF0\x9F\x98\x80 → 😀 · Café → Café
Hello 🌍
Read as hex · 10 bytes → 7 characters
Everything runs in your browser; nothing is uploaded.
How to decode UTF-8
Decoding UTF-8 means turning a list of bytes back into the characters they stand for. You might have the bytes from a hex dump, a log file, a URL, a debugger or a program that printed a byte array.
- Paste the bytes into the box. Spaces, commas, colons and brackets between them are fine.
- The tool works out the format and shows it on the Auto chip. If it guessed wrong (65 66 67 could be hex or decimal), click the right format.
- Read or copy the text. If some bytes aren't valid UTF-8, the tool says which ones and why, and can show the rest with � in their place.
Which byte formats can I paste?
| Format | é looks like | Where you see it |
|---|---|---|
| Hex | C3 A9 · C3A9 · 0xC3, 0xA9 | Hex editors, packet captures, xxd, most dumps |
| Decimal | 195 169 | Python lists, byte arrays printed by programs |
| Signed decimal | -61 -87 | Java and C# sbyte arrays, which print bytes over 127 as negatives |
| Binary | 11000011 10101001 | Homework and bit-level debugging |
| URL % | %C3%A9 · caf%C3%A9 | Links, query strings, server logs |
| \x escapes | \xC3\xA9 · b'caf\xc3\xa9' | Python bytes, C strings, error messages |
| Octal escapes | \303\251 | git file names, C strings (read under \x escapes) |
| Garbled text | é | Emails, CSV files and web pages opened with the wrong encoding |
A code point such as U+00E9 is not a byte dump; it is the character’s Unicode number. To see its bytes, use the UTF-8 Converter and type the character. For Base64, first turn it into hex with the Base64 to Hex converter, then paste the hex here.
Worked example: decoding E2 82 AC by hand
Step 1: Write each byte in binary
Step 2: Read the first byte’s marker
Step 3: Drop the markers and join the rest
Answer
So the three bytes are one euro sign, not three characters. A byte under 80 (hex) is always a whole ASCII character on its own, so 45 75 72 6F is simply Euro.
Fixing garbled text like é and ’
Garbled text (sometimes called mojibake) happens when UTF-8 bytes are read as Windows-1252 or Latin-1, which use one byte per character. The two bytes of é, C3 A9, show up as the two characters à and ©. Paste the garbled text and the tool reverses the mix-up; it also handles text garbled twice, like ’.
| You see | It should be | UTF-8 bytes |
|---|---|---|
| é | é | C3 A9 |
| è | è | C3 A8 |
| ü | ü | C3 BC |
| ñ | ñ | C3 B1 |
| ’ | ’ (apostrophe) | E2 80 99 |
| “ | “ (opening quote) | E2 80 9C |
| †followed by nothing visible | ” (closing quote) | E2 80 9D |
| — | — (em dash) | E2 80 94 |
| € | € | E2 82 AC |
| £ | £ | C2 A3 |
| Â before a space | no-break space | C2 A0 |
| 😀 | 😀 | F0 9F 98 80 |
Fixing the copy you have is a stopgap. The lasting fix is to make the program that shows it read the file as UTF-8, for example by adding <meta charset="utf-8"> to a web page or choosing UTF-8 when importing a CSV.
Why UTF-8 decoding fails
| Bytes | What is wrong | What to do |
|---|---|---|
| … C3 | A 2-byte character with only its first byte: the data was cut off | Copy the whole dump; check for a length limit |
| 43 61 66 E9 | E9 is é in Windows-1252 or Latin-1, not UTF-8 | The tool shows the Windows-1252 reading for you |
| FF FE 41 00 | FF FE at the start marks UTF-16, not UTF-8 | Decode it as UTF-16, or re-save the file as UTF-8 |
| A9 | A follow-on byte with no first byte | The dump starts mid-character; include the byte before |
| C0 AF · ED A0 80 | Byte patterns UTF-8 never allows | Usually corrupted or deliberately crafted data |
The � symbol (U+FFFD, the replacement character) is what browsers and most programs put where bytes couldn't be decoded. Once text has been saved with � in it, the original bytes are gone, so go back to the source rather than trying to repair the � characters.
Decoding UTF-8 in JavaScript, Python, PHP, C# and Java
// JavaScript
const bytes = Uint8Array.from('43 61 66 C3 A9'.split(' '), (h) => parseInt(h, 16));
new TextDecoder().decode(bytes); // "Café"
# Python
bytes.fromhex('43 61 66 C3 A9').decode('utf-8') # 'Café'
'Café'.encode('cp1252').decode('utf-8') # 'Café' (fixes garbled text)
// PHP
hex2bin(str_replace(' ', '', '43 61 66 C3 A9')); // "Café"
// C#
Encoding.UTF8.GetString(Convert.FromHexString("436166C3A9")); // "Café"
// Java 17+
new String(HexFormat.ofDelimiter(" ").parseHex("43 61 66 c3 a9"), StandardCharsets.UTF_8);They treat bad bytes differently. Python stops with a UnicodeDecodeError. JavaScript, C# and Java quietly put � in their place; use new TextDecoder('utf-8', { fatal: true }) in JavaScript or new UTF8Encoding(false, true) in C# to get an error instead. PHP’s hex2bin doesn’t check at all, so test the result with mb_check_encoding($text, 'UTF-8').
Frequently asked questions
Why does my decoded text show boxes or question marks?
An empty box usually means the bytes decoded fine but your font has no picture for that character. A � means the bytes were not valid UTF-8. A plain ? often means another program already replaced the character before you copied it.
Is UTF-8 decoding the same as URL decoding?
URL decoding turns each %XX back into a byte and then reads the bytes as UTF-8, so %C3%A9 becomes é. This tool does that for the URL % format, but keeps + as a plus sign; in form data a + means a space.
Can it decode Base64?
Not directly. Base64 is a different way of writing bytes as text. Convert it to hex with the Base64 to Hex converter first, then paste the hex here.
Is my data uploaded?
No. Decoding happens in your browser, so the bytes and the text never leave your device.
Sources
- The Unicode Standard, chapter 3: well-formed UTF-8 byte sequences
- WHATWG Encoding Standard: UTF-8 decoder: where browsers insert U+FFFD
- MDN: TextDecoder: decoding bytes in JavaScript, and the fatal option
- Python docs: bytes.decode: decoding and error handling in Python
- Microsoft Learn: UTF8Encoding: throwing on invalid bytes in .NET
Related Tools
Build and preview Valorant crosshair settings.
Search common Vim commands.
Turn JSON rows into bar, line, or pie charts.
Convert WebP files and Base64 data in both directions.
Convert GIF files and Base64 data in both directions.
Save any GIF frame, or all frames, as JPG.