Skip to content
ZeroServer.tools

UTF-8 Decoder

Decode UTF-8 byte values back into text.

Decoded Text

Reconstructing Text from UTF-8 Bytes

Paste UTF-8 byte values as hexadecimal — with or without a 0xprefix, separated by spaces, commas, or new lines — and this tool reassembles the original text, correctly combining multi-byte sequences for accented characters and emoji. It's the inverse of the UTF-8 Encoder and is handy for debugging data dumps and network payloads, all locally.

Built and maintained by Meet Shah · Last updated

What this tool is used for

  • Turning a hex dump from a packet capture or a database blob column back into readable text.
  • Diagnosing which byte in a payload is malformed when a parser reports an encoding error but not a position.
  • Confirming that a file really is UTF-8 rather than Latin-1 before importing it and finding out the hard way.
  • Recovering the original characters from a log line that was written as escaped bytes.
  • Checking whether an emoji arrived as four bytes or as a pair of broken surrogates.

Frequently Asked Questions

How does UTF-8 encode a character?
In 1 to 4 bytes. ASCII (U+0000-007F) stays a single byte, which is why UTF-8 is backward compatible; beyond that the leading byte announces the length (110xxxxx for 2 bytes, 1110xxxx for 3) and continuation bytes all start 10xxxxxx.
What causes mojibake like ’ or é?
Reading UTF-8 bytes as if they were Latin-1 or Windows-1252. The multi-byte sequence gets shown as several single-byte characters — ’ is the three bytes of a curly apostrophe misread one at a time. The data is intact; only the interpretation is wrong.
What is the replacement character?
U+FFFD (�), inserted where a byte sequence is not valid UTF-8. Unlike mojibake this is lossy — once a decoder substitutes it, the original bytes are gone and the text cannot be recovered.
Is a byte-order mark needed?
No. UTF-8 has no byte order to mark, so the BOM (EF BB BF) is pointless and actively harmful in many contexts — it breaks shebang lines, corrupts CSV headers and appears as before PHP output.
Why is string length ambiguous?
Because three different counts exist: bytes, Unicode code points, and grapheme clusters. An emoji family is one grapheme, several code points, and many bytes. JavaScript's .length counts UTF-16 units, so it charges most emoji 2.
How does a decoder resynchronise after a bad byte?
By scanning forward to the next byte that is not a continuation byte, since continuation bytes are always in the range 0x80-0xBF and lead bytes never are. That self-synchronising property means one corrupt byte damages one character, not the rest of the file.
Why can a UTF-8 file be truncated mid-character?
Because a character can span up to four bytes, and cutting a file at a fixed byte count can land inside one. Truncating by bytes rather than by characters is the standard cause of a stray replacement character at the end.
What is WTF-8?
A superset that permits unpaired surrogates, existing to round-trip strings from systems such as Windows and JavaScript whose text can contain them. It is not valid UTF-8 and should never be emitted where interchange matters.

Common errors and gotchas

  • Feeding in bytes that are actually Latin-1. Every byte above 0x7F is then either an invalid sequence or the wrong character entirely.
  • Splitting the input mid-character. A multi-byte sequence cut in half decodes to a replacement character no matter how correct the rest is.
  • Assuming a leading `EF BB BF` is data. That is the byte-order mark, and it will show up as an invisible first character downstream.
  • Reading the byte count as a character count. One emoji is four bytes and one character, which is why length checks disagree.
  • Treating replacement characters as recoverable. Once a decoder substitutes them the original bytes are gone from the output.

Related Encoders & Decoders tools

Private & free — this tool runs entirely in your browser.

IndieKitShip your Next.js startup in days.affiliate