Во что превращается «Привет», если UTF-8 прочитать как Windows-1251?
UTF-8 → Windows-1251 В «РџСЂРёРІРµС‚». Двенадцать байтов UTF-8 распадаются на двенадцать отдельных однобайтовых символов Windows-1251.
Вставьте кракозябры — и получите исходный текст. Перебираются все правдоподобные цепочки кодировок: UTF-8, Windows-1251, GBK, Big5, Shift_JIS, EUC-KR. Бесплатно, локально в браузере.
Вставьте испорченный текст. Все правдоподобные цепочки кодировок будут перебраны, а результаты отранжированы — знать, какая кодировка всё сломала, не нужно.
测试
UTF-8 → GBK
娴å¬ç˜¯
Windows-1252 / Latin-1 → UTF-8
测试
Windows-1252 / Latin-1 → GBK
测试
Windows-1251 → GBK
Посмотрите один и тот же текст в байтах сразу во всех распространённых кодировках — полезно, когда нужно точно знать, что сохранит база данных или протокол.
| Кодировка | Байты | 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 |
Собрано и проверено инженерной командой Go Tools.
UTF-8 → Windows-1251 В «РџСЂРёРІРµС‚». Двенадцать байтов UTF-8 распадаются на двенадцать отдельных однобайтовых символов Windows-1251.
UTF-8 → Windows-1252 Получится «ÐŸÑ€Ð¸Ð²ÐµÑ‚»: тот же механизм, другая однобайтовая таблица. Отсюда узнаваемые Ð, Ñ и случайные знаки препинания в латинских текстах.
Не восстановить Нет. Эти байты были выброшены при декодировании. Возьмите что получится из окружающего текста, а остальное — из источника.
2 против 1 байта Два в UTF-8 и один в Windows-1251; китайский иероглиф — три в UTF-8 и два в GBK. Из-за этой разницы колонки, размеренные в байтах, режут текст.
Кракозябры — это то, что получается, когда текст записали одной кодировкой символов, а прочитали другой. Байты целы, неверно только их истолкование. На этом различии и держится возможность восстановления: если понять, какая кодировка записала байты и какая прочитала их неверно, ошибку можно прогнать назад и получить исходный текст.
У явления в каждом языке своё имя. По-английски прижилось японское 文字化け — mojibake, примерно «превращение символов», потому что в японских вычислениях проблема была повсеместной задолго до Unicode. В русском закрепилось слово «кракозябры», пришедшее из эпохи, когда Windows-1251, KOI8-R и CP866 сосуществовали и почта регулярно приходила нечитаемой. Кириллица и восточноазиатские письменности страдают сильнее латиницы по структурной причине: всё, что выше 0x7F, кодировки трактуют по-своему, а латинская строка обычно укладывается в чистый ASCII, о котором договорились все.
Восстановление проваливается ровно в одном случае. Встретив байты, не имеющие смысла в своей кодировке, декодер их не сохраняет — он подставляет U+FFFD и выбрасывает их. Эти символы потеряны навсегда. Всё остальное обратимо.
// 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 Вставьте испорченный текст, и инструмент сам переберёт цепочки. Проверяется каждое сочетание «записано в» и «прочитано как» среди UTF-8, GBK, Big5, Shift_JIS, EUC-KR, Windows-1252 и Windows-1251, а GB18030 доступна в разделе с байтами.
Кандидат получает метку «Точно», только если прогон обратно по той же цепочке воспроизводит ваш ввод символ в символ. Это детерминированная проверка: ранжированная догадка не сказала бы, каким результатам можно верить.
У каждого кандидата названы кодировка, которой байты были записаны, и кодировка, которая прочитала их неверно. Это то, что нужно, чтобы починить источник, а не чинить те же строки снова через неделю.
Если во вводе уже есть символы замены, инструмент прямо об этом говорит и помечает всех кандидатов как частичных. Информация, уничтоженная при декодировании, не возвращается, и вид, будто это не так, стоит впустую потраченного вечера.
Посмотрите любой текст в шестнадцатеричных байтах по всем поддерживаемым кодировкам бок о бок и декодируйте сырой hex в обратную сторону. Полезно, чтобы подобрать длину колонки, читать перехват пакетов и проверять содержимое BLOB.
Декодирование использует встроенный в браузер TextDecoder. Ни отправки на сервер, ни записи в хранилище, ни изменения адресной строки — а это важно, потому что испорченный текст обычно приезжает прямо с продакшена.
娴嬭瘯
测试
Два китайских иероглифа были корректно сохранены в UTF-8 (байты E6 B5 8B E8 AF 95), а затем программа прочитала эти шесть байтов как GBK. GBK группирует байты по два, поэтому вместо двух символов получилось три. Ровно это происходит, когда файл в UTF-8 открывают устаревшим приложением для Windows или когда кодировка соединения с базой данных выставлена в gbk, а данные лежат в UTF-8.
测试
测试
Те же байты, другая ошибка. Windows-1252 однобайтовая, поэтому каждый из шести байтов UTF-8 стал отдельным символом. Языки на латинице попадают в эту версию постоянно: café превращается в café, naïve — в naïve. Опознавательные признаки — Ã, Â, â и знаки препинания, вылезающие парами. С русским текстом происходит то же самое: «Привет» в UTF-8, прочитанный как Windows-1252, даёт «ÐŸÑ€Ð¸Ð²ÐµÑ‚», а прочитанный как Windows-1251 — «РџСЂРёРІРµС‚».
B2 E2 CA D4
测试
Иногда перед вами не испорченный текст, а шестнадцатеричный дамп из перехвата пакетов или из BLOB-колонки. Вставьте его во второй раздел и выберите кодировку. B2 E2 CA D4 — это 测试 в GBK; те же два иероглифа занимают в UTF-8 шесть байтов (E6 B5 8B E8 AF 95) против четырёх в GBK, а в Windows-1252 их вообще нельзя представить.
鏁版嵁搴�
(только частично)
数据库 записали в UTF-8 и прочитали как GBK, но последняя пара байтов не имела смысла в GBK, и декодер заменил её на U+FFFD. Этот байт потерян. Инструмент прямо помечает такой случай, а не подбирает догадку втихую: 数据 из начала строки восстановить всё ещё можно, а последний иероглиф невосстановим, и за ним придётся идти к исходным данным.
Просто вставьте его — определять кодировку заранее не нужно. Хватит короткого фрагмента: десятка символов обычно достаточно, чтобы цепочка определилась однозначно.
«Точно» означает, что цепочка при обратном проходе воспроизводит ваш ввод символ в символ. «Частично» означает, что не воспроизводит, — такой результат стоит считать зацепкой.
У каждого кандидата показано, в какой кодировке текст был записан на самом деле и какая прочитала его неверно. Это говорит, что чинить в источнике, а не только что было написано в тексте.
Второй раздел показывает любой текст в байтах во всех распространённых кодировках и декодирует сырой hex в обратную сторону. Пригодится, чтобы подобрать длину колонки или разобрать кадр протокола.
Если строка отображается правильно, а вы всё равно её конвертируете, то сами и создаёте кракозябры, которых пытались избежать. Сначала проверьте, как текст отображается, и учтите: отсутствующий шрифт даёт квадратики (□□□), а проблема кодировки — другие символы.
iconv -f UTF-8 -t GBK correct.txt > broken.txt
# Сначала подтвердите текущую кодировку file -I correct.txt # charset=utf-8 → конвертировать нечего
Смена объявленной кодировки колонки MySQL не перекодирует уже лежащие в ней байты. Если данные latin1 объявить как utf8, сервер начнёт отдавать байты, не являющиеся корректным UTF-8, а драйвер заменит их на U+FFFD — то есть уничтожит.
ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4;
-- Пройдите через двоичный тип, чтобы байты сохранились, а не были истолкованы заново ALTER TABLE t MODIFY c VARBINARY(255); ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4;
Кандидат с меткой «Частично» не прошёл обратный проход. Это зацепка, за которой стоит пойти, а не ответ, который можно записать обратно в базу. Если ничего не вернулось с меткой «Точно», ввод, скорее всего, уже потерял информацию — возвращайтесь к исходным байтам.
// Берём первого кандидата, что бы ни говорила метка db.update(row.id, candidates[0].text);
// Записываем обратно только то, что проходит обратный проход if (candidates[0].lossless) db.update(row.id, candidates[0].text);
Вызов encode у того, что уже является bytes, или decode у того, что уже является строкой, в Python 3 приводит к исключению, а не к молчаливому проходу через ASCII. Декодируйте байты один раз, на границе, и дальше работайте с текстом как с текстом.
text = raw.decode('utf-8').encode('gbk').decode('utf-8') # Декодируем один раз на границе — той кодировкой, которая в файле на самом деле
with open(path, encoding='gbk') as f:
text = f.read() iconv -f KOI8-R -t UTF-8 in.txt > out.txt. iconv -f CP1251 -t UTF-8 input.txt > output.txt в macOS и Linux или Get-Content -Encoding Default in.txt | Set-Content -Encoding UTF8 out.txt в PowerShell. Сначала прогоните здесь одну показательную строку, чтобы понять, какие кодировки называть в команде: ошибка в направлении на целом файле — это способ превратить проблему в одну строку в проблему в тысячу строк. Кодирование и форматирование
Полная таблица ASCII: 128 символов в десятичном, шестнадцатеричном, восьмеричном и двоичном виде плюс конвертер текста и кодов. Управляющие символы — с escape-последовательностями, caret-записью и тем, где их встретить.
Кодирование и форматирование
Декодирование и кодирование Base64 онлайн бесплатно. Преобразование в реальном времени с полной поддержкой UTF-8 и эмодзи. Полная приватность — работает в браузере. Без регистрации.
Кодирование и форматирование
Декодируйте строку Base64 или data URI обратно в изображение прямо в браузере. Предпросмотр, размеры и MIME, затем скачивание как PNG, JPG, GIF, SVG. Без загрузки.
Кодирование и форматирование
Конвертируйте CSV в JSON в браузере. RFC 4180, определение типов, заголовок, безопасность больших целых. 100% приватно, без загрузки.
Кодирование и форматирование
Вставьте файл .env — получите JSON мгновенно. Пароли БД, API-ключи и токены не покидают браузер: 100% приватно, без загрузки, парсер dotenv.
Кодирование и форматирование
Декодируйте HTML-сущности и снимайте экранирование HTML онлайн — бесплатно, без регистрации, 100% в браузере. Преобразует именованные, десятичные и hex-ссылки обратно в символы; данные не загружаются.