Skip to content

Encoding Detector and Fixer

Repair text mangled by a wrong decoder, in as many rounds as it took to break it, and see the exact position where the damage starts.

Everything on this page runs in your browser. Nothing you paste is uploaded, logged, or written into the URL — only the settings are, so a configured tool can still be linked to.

Mojibake sequences remaining
0

Down from 5 after 1 round of decoding. Check the result below against what you expected before trusting it.

Best result
café — naïve “quoted”
Characters in
29
Characters out
21
UTF-8 bytes in
46
UTF-8 bytes out
29
Mojibake sequences before
5
Mojibake sequences after
0
Decode rounds applied
1
  • warnline 1, column 4mojibake starts here: "é" is the two-byte UTF-8 sequence for one character, shown as two separate Windows-1252 characters

    Expected: the single character those bytes encode. This happens when UTF-8 output is read by something that assumes Windows-1252 or Latin-1 — a database column with the wrong charset, a CSV opened in a spreadsheet, a Content-Type header with no charset on it

    café — naïve “quoted”
What this checked: this repairs exactly one failure mode, which happens to be the one behind almost every report of this kind: text encoded as UTF-8 and decoded as Windows-1252 or Latin-1, possibly more than once. It re-encodes each character back to the byte it came from, decodes the result as strict UTF-8 — rejecting overlong forms, encoded surrogates and truncated sequences with the byte offset that failed — and keeps the round with the fewest remaining signatures. It also flags a byte order mark, CRLF line endings, and replacement characters, which mark damage that has already become permanent. It does not detect the encoding of a file: text arriving on this page is already a decoded string, and the bytes are no longer available to guess from. It does not handle Shift-JIS, KOI8 or the other single-byte encodings, and it cannot repair anything that has been through a lossy step.
What this assumes: that the wrong decoder was Windows-1252, and that unassigned bytes in that encoding (0x81, 0x8D, 0x8F, 0x90, 0x9D) passed through as the C1 control of the same value, which is what browsers and most libraries do. A repair is only ever a guess about history: it is reported with the signature count before and after so you can judge it, and a round that does not reduce the count is not applied. Always read the result — a confident repair of text that was never damaged will corrupt genuine Latin-1 content, which is the one way this tool can make things worse.

Why é becomes é, precisely

U+00E9 encoded as UTF-8 is the two bytes C3 A9. A decoder that believes it is reading Windows-1252 sees two separate characters: C3 is Ã, A9 is ©. Nothing is lost — both bytes are still there, wearing the wrong names — which is why the damage is reversible as long as nothing downstream has replaced anything. Three-byte characters give the familiar â€" and “, because 0xE2 is â and 0x80 is the euro sign in Windows-1252. Once you know the mapping, you can read the encoding of the original off the mojibake itself.

Fix the pipeline, not the strings

A repair here is a rescue, not a solution. The damage is done in one of four places, and it is worth finding out which: a database column or connection with a non-UTF-8 charset, an HTTP response with no charset on its Content-Type, a file read without an explicit encoding, or a spreadsheet that opened a CSV with the locale default. Repairing the data without fixing the step that broke it means doing it again next week, on data that has by then been through the loop twice — which is why the round counter above goes past one. And a replacement character means you were too late: something already decided those bytes were unreadable and dropped them, and no tool on any site can bring them back.

Encoding Detector and Fixer · Multigrid