Skip to content

Encoding Converter & Mojibake Fixer

Paste garbled text and get the original back. Every plausible encoding chain — UTF-8, GBK, Big5, Shift_JIS, EUC-KR, Windows-1252 — is tried and ranked, with the exact chain shown. Free, private, runs in your browser.

No Tracking Runs in Browser Free
Everything is decoded locally in your browser — the text you paste never leaves this device.

Recover garbled text

Paste the garbled text. Every plausible encoding chain is tried and the results are ranked — you do not need to know which encoding broke it.

Try these

Most likely originals

4 candidates
  1. 测试

    Exact

    UTF-8 → GBK

  2. 娴嬭瘯

    Exact

    Windows-1252 / Latin-1 → UTF-8

  3. 测试

    Exact

    Windows-1252 / Latin-1 → GBK

  4. 测试

    Exact

    Windows-1251 → GBK

Convert and inspect encodings

See the same text as bytes in every common encoding at once — useful when you need to know exactly what your database or protocol will store.

Encoding Bytes Hex
UTF-8 6 E4 B8 AD E6 96 87
GBK 4 D6 D0 CE C4
GB18030 4 D6 D0 CE C4
Big5 4 A4 A4 A4 E5
Shift_JIS 4 92 86 95 B6
EUC-KR 4 F1 E9 D9 FE

Every encoding chain shown on this page is produced by the same engine the page runs, and the round-trip check behind the Exact badge is asserted in the unit test suite against known byte sequences. — Go Tools Team · Sep 8, 2026

Built and verified by the Go Tools engineering team.

Quick answers

What encoding turns 测试 into 娴嬭瘯?

UTF-8 → GBK UTF-8 bytes read as GBK. The six UTF-8 bytes (E6 B5 8B E8 AF 95) get regrouped into three GBK characters.

What turns 测试 into 测试?

UTF-8 → Windows-1252 The same UTF-8 bytes read as Windows-1252. Because that encoding is single-byte, each of the six bytes becomes its own character.

Can text containing � be recovered?

Not recoverable No. Those bytes were discarded at decode time. Recover what you can from the surrounding text and go back to the source for the rest.

How many bytes is a Chinese character?

3 vs 2 bytes Three in UTF-8, two in GBK and Big5. That difference is a common source of truncation when a column is sized in bytes rather than characters.

What is mojibake?

Mojibake is what you get when text is written with one character encoding and read with another. The bytes are intact; only the interpretation is wrong. That distinction is the whole reason recovery is possible: if you can work out which encoding wrote the bytes and which one misread them, you can run the mistake backwards and get the original text.

The word is Japanese — 文字化け, roughly "character transformation" — and it became the standard term in English because the problem was endemic in Japanese computing long before Unicode. Chinese, Japanese and Korean text suffers from it far more than Latin-script text, for a structural reason: those languages need multi-byte encodings, and multi-byte encodings disagree with each other about how to group bytes. A Latin-script string is usually plain ASCII, and every encoding agrees about ASCII.

Recovery fails in exactly one situation. When a decoder meets bytes that have no meaning in its encoding, it does not keep them — it substitutes U+FFFD and throws them away. Those characters are lost permanently. Everything else is reversible.

// The mistake, in three lines of JavaScript
const bytes = new TextEncoder().encode('测试');   // UTF-8: E6 B5 8B E8 AF 95
new TextDecoder('gbk').decode(bytes);            // '娴嬭瘯'  ← mojibake
new TextDecoder('windows-1252').decode(bytes);   // '测试'  ← same bytes, other mistake

What this tool does

No need to know the encoding

Paste the garbled text and the tool enumerates the chains for you. Every combination of written-as and read-as across UTF-8, GBK, GB18030, Big5, Shift_JIS, EUC-KR, Windows-1252 and Windows-1251 is tried.

Exact results are verified, not guessed

A candidate is marked Exact only when running it back through the same chain reproduces your input character for character. That is a deterministic check — a ranked guess would not tell you which results you can trust.

The chain is shown, not hidden

Each candidate names the encoding that wrote the bytes and the one that misread them. That is what you need in order to fix the source, rather than repairing the same strings again next week.

Honest about unrecoverable text

If the input already contains replacement characters, the tool says so plainly and marks every candidate as partial. Information destroyed at decode time does not come back, and pretending otherwise wastes your afternoon.

Byte view in every encoding at once

See any text as hex bytes across all supported encodings side by side, and decode raw hex in the other direction. Useful for sizing columns, reading packet captures and checking BLOB contents.

Nothing leaves your browser

Decoding uses the browser's own TextDecoder. There is no upload, no storage and no URL rewriting — which matters because garbled text usually comes straight out of production.

Worked examples

UTF-8 read as GBK — the classic case

娴嬭瘯
测试

The two Chinese characters were stored correctly as UTF-8 (bytes E6 B5 8B E8 AF 95), then a program read those six bytes as GBK. GBK pairs bytes two at a time, so it produced three characters instead of two. This is what you get when a UTF-8 file is opened by a legacy Windows application, or when a database connection charset is set to gbk while the data is UTF-8.

UTF-8 read as Windows-1252 — the Western variant

测试
测试

Same bytes, different mistake. Windows-1252 is single-byte, so each of the six UTF-8 bytes became its own character. Latin-script languages hit this version constantly: café becomes café, naïve becomes naïve. The tell-tale signs are Ã, Â, â and stray punctuation marks appearing in pairs.

Bytes you already have in hex

B2 E2 CA D4
测试

Sometimes you are not looking at garbled text, you are looking at a hex dump from a packet capture or a BLOB column. Paste the hex into the second section and pick the encoding. B2 E2 CA D4 is 测试 in GBK — the same two characters take six bytes in UTF-8 (E6 B5 8B E8 AF 95) and cannot be represented in Windows-1252 at all.

Text that cannot be recovered

鏁版嵁搴�
(partial only)

数据库 was written as UTF-8 and read as GBK, but the last byte pair had no meaning in GBK, so the decoder replaced it with U+FFFD. That byte is gone. The tool flags this instead of quietly guessing — you can still recover 数据 from the front of the string, but the last character is unrecoverable and you need to go back to the source data.

How to use this tool

  1. 1

    Paste the garbled text

    Drop it straight in — no need to identify the encoding first. A short fragment is enough; a dozen characters usually pins the chain down.

  2. 2

    Read the top candidate and its badge

    Exact means the chain round-trips back to your input exactly. Partial means it does not, so treat the result as a lead.

  3. 3

    Check the encoding chain

    Each candidate shows which encoding the text was really written in and which one misread it. That tells you what to fix upstream, not just what the text said.

  4. 4

    Inspect the bytes if you need to

    The second section shows any text as bytes in every common encoding, and decodes raw hex the other way. Use it to size columns or check protocol frames.

Mistakes that make it worse

Converting text that was never really broken

If a string displays correctly but you convert it anyway, you create the mojibake you were trying to avoid. Check the display first, and note that a missing font renders as boxes (□□□) while an encoding problem renders as wrong characters.

✗ Wrong
iconv -f UTF-8 -t GBK correct.txt > broken.txt
✓ Correct
# Confirm the current encoding first
file -I correct.txt   # charset=utf-8 → nothing to convert

Declaring a charset the data does not have

Changing a MySQL column's declared charset does not re-encode the bytes it holds. Declaring latin1 data as utf8 makes the server hand back bytes that are not valid UTF-8, and the driver replaces them with U+FFFD — which destroys them.

✗ Wrong
ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4;
✓ Correct
-- Go via a binary type so the bytes are preserved, not reinterpreted
ALTER TABLE t MODIFY c VARBINARY(255);
ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4;

Trusting a partial recovery

A candidate marked Partial did not round-trip. It is a lead worth following, not an answer to paste back into your database. If nothing comes back Exact, the input probably lost information already — go back to the source bytes.

✗ Wrong
// Take the first candidate whatever the badge says
db.update(row.id, candidates[0].text);
✓ Correct
// Only write back what round-trips
if (candidates[0].lossless) db.update(row.id, candidates[0].text);

Assuming Python 2 habits still apply

Calling encode on something that is already bytes, or decode on something already a string, raises in Python 3 rather than silently doing a round trip through ASCII. Decode bytes once, at the boundary, and keep text as text after that.

✗ Wrong
text = raw.decode('utf-8').encode('gbk').decode('utf-8')
✓ Correct
# Decode once at the boundary, with the encoding the file actually uses
with open(path, encoding='gbk') as f:
    text = f.read()

When you need this

A database migration produced garbage
Legacy MySQL tables declared latin1 while actually holding UTF-8 bytes are the single most common source. Paste a garbled row here to confirm the real chain before you write the ALTER TABLE — running the conversion in the wrong direction turns a recoverable problem into a permanent one.
A CSV opened in Excel shows nonsense
Excel on Windows still assumes the system code page for CSV files without a BOM, so UTF-8 exports come out as mojibake. Confirm the chain here, then re-export with a BOM or import through the text wizard with the encoding set explicitly.
Log files from a legacy service
Applications built against GBK or Shift_JIS write logs in those encodings, and modern log aggregators read everything as UTF-8. Paste a line to recover it — and because nothing is uploaded, you can do this with production logs.
Filenames broken by a ZIP archive
The ZIP format has no encoding field, so archives created on Chinese or Japanese Windows carry filenames in GBK or Shift_JIS that Unix tools read as UTF-8. Recover the real names here before you rename anything.
Sizing a database column
The byte view shows the same text across every encoding at once. A Chinese character is 3 bytes in UTF-8 but 2 in GBK, which is exactly the sort of difference that turns a VARCHAR(50) into a truncation bug.

How mojibake happens

Bytes survive, meaning does not
Encoding maps characters to bytes; decoding maps bytes back. Mojibake is a decode with the wrong map. The bytes were never damaged, which is why running the wrong decode backwards recovers the original exactly — provided the wrong decode did not discard anything.
Why CJK text suffers most
ASCII occupies 0x00–0x7F and every common encoding agrees on it, so English text passes through unharmed. Chinese, Japanese and Korean need multi-byte sequences, and the encodings disagree about how to group them. UTF-8 uses three bytes per Chinese character; GBK uses two. Feed UTF-8 bytes to a GBK decoder and the grouping shifts, producing a different number of different characters.
The round-trip test
For each candidate chain the tool re-encodes the recovered text with the first encoding and re-decodes with the second. If that reproduces the input exactly, the chain explains every character and the candidate is marked Exact. Candidates that fail this test are still shown, because a partial recovery often identifies the text even when it cannot reproduce it.
Where the encoding tables come from
The browser's TextDecoder supplies the tables. Encoding in the other direction is trickier, because TextEncoder only supports UTF-8 — so the tool builds a reverse map by walking the byte space and asking the decoder what each sequence means. The mapping is therefore always consistent with the browser's own behaviour, and no lookup tables are shipped to your device.
The ranking heuristic, and its limits
Beyond the round-trip test, candidates are scored by how much of the text is common Chinese characters (those whose GBK lead byte falls in 0xB0–0xF7), minus penalties for replacement characters, half-width katakana and control characters. Half-width katakana is a strong Shift_JIS signal because normal Japanese text hardly ever uses it. This is a heuristic; it breaks ties, it does not establish truth.

Stopping it from happening again

Fix the source, not just the string
The encoding chain shown under each candidate tells you which component is misconfigured. Repairing the text without fixing the connection charset, file reader or export setting means doing it again tomorrow with fresh data.
Confirm the direction before converting a whole file
Run a representative line through this page first. Converting in the wrong direction can produce replacement characters, and unlike the original mistake, that step is not reversible.
Set the encoding explicitly everywhere
Database connection charset, HTTP Content-Type, file open calls, CSV exports. Every place that defaults to "the system encoding" is a place where the same bug returns when the code moves to a different machine.
Prefer utf8mb4 over utf8 in MySQL
MySQL's utf8 stores at most three bytes per character, so emoji and some rarer Chinese characters are silently truncated. utf8mb4 is real UTF-8. This is a different failure from mojibake and the recovery tool cannot help with it, because the bytes are genuinely gone.
Keep the original bytes until the fix is verified
Take a copy before converting anything. As long as the original bytes exist, every wrong decode is reversible — once they are overwritten with replacement characters, no tool on this page or anywhere else can bring them back.

Frequently asked questions

How do I fix Chinese characters that show up as garbage?
Paste the garbled text into the box at the top of this page. The tool tries every plausible encoding chain and ranks the results, so you do not need to identify the encoding yourself. In the overwhelming majority of cases the answer is UTF-8 text read as GBK (you will see characters like 娴嬭瘯) or UTF-8 text read as Windows-1252 (you will see 测试). Both are recovered exactly.
What does the Exact badge actually verify?
It runs the recovery backwards. The recovered text is encoded again with the chain's first encoding, and those bytes are decoded again with the chain's second encoding. If the result reproduces your input character for character, the chain fully explains what you pasted and the badge says Exact. This is a deterministic round-trip check rather than a similarity score, which is why an Exact result is reliable in a way that a ranked guess is not.
Why can some garbled text never be recovered?
Because the damage happened before you saw it. When a decoder meets a byte sequence that has no meaning in its encoding, it does not preserve the bytes — it substitutes U+FFFD (shown as �) and discards them. That is lossy and irreversible. If your text contains �, those specific characters are gone no matter what tool you use. This page tells you so instead of producing a confident-looking guess.
What is the difference between GBK, GB2312 and GB18030?
They are three generations of the same family, each a superset of the last. GB2312 (1980) covers 6,763 simplified Chinese characters — enough for everyday text. GBK (1995) extends it to roughly 21,000 characters including traditional forms. GB18030 (2000, mandatory in China) covers all of Unicode. For recovering mojibake, GBK is almost always the right choice, because the software that caused the problem was usually written against GBK.
Is ISO-8859-1 the same as Windows-1252?
Not in the standards, but yes in every browser. The WHATWG Encoding Standard — which is what browsers implement — treats iso-8859-1 and latin1 as labels for windows-1252. The two differ only in the range 0x80–0x9F, where true ISO-8859-1 has control characters and Windows-1252 has printable punctuation such as the em dash and curly quotes. Since those printable characters are exactly what shows up in mojibake, Windows-1252 is the more useful of the two and this tool lists it once under both names.
Does my text get uploaded anywhere?
No. All decoding happens in your browser using its built-in TextDecoder, and nothing is sent over the network, written to storage, or added to the URL. This matters more than usual for this particular tool: garbled text almost always comes from a production log, a customer record, or a database dump, and those are exactly the things you should not be pasting into a server-side tool.
Can I convert a whole file, not just a snippet?
This page handles text you paste in. For whole files, use the command line: iconv -f GBK -t UTF-8 input.txt > output.txt on macOS or Linux, or Get-Content -Encoding Default in.txt | Set-Content -Encoding UTF8 out.txt in PowerShell. Paste a representative line here first to work out which encodings to name in the command — getting the direction wrong on a whole file is how one-line problems become thousand-line problems.
Why does the tool show several candidates instead of one answer?
Because more than one chain can produce readable text, and the tool does not hide that from you. Candidates are sorted with self-consistent (Exact) chains first, then by a readability heuristic that rewards common Chinese characters and penalises replacement characters, half-width katakana and control characters. The heuristic is a tie-breaker, not an oracle. When two candidates both look plausible, the encoding chain shown under each one tells you which is consistent with where your data actually came from.

Related Tools

View all tools →