Вы копируете текст из базы данных или документа, и он выглядит так: «Ã©chéance» или «â€˜типографские кавычки’». Это кракозябры (mojibake) — текст, закодированный в одной кодировке и декодированный в другой. Это руководство точно объясняет, почему это происходит, как определить, с каким расхождением кодировок вы столкнулись, и как исправить это за секунды правильными инструментами.
Что такое кракозябры (mojibake)?
Модзибаке (文字化け) — японский термин, означающий «превращение символов»: он описывает искажённый текст, который появляется, когда строка интерпретируется с неверной кодировкой. Вместо «résumé» вы видите «résumé». Вместо типографского апострофа — «â€™». Символы не повреждены на уровне байтов — байты в порядке. Проблема в том, что читающая их программа использует неверную таблицу правил для перевода байтов в символы.
Проблема перевода байтов в символы
Каждая кодировка — это отображение между числами (байтами) и символами. Буква «e» — это байт 0x65 практически в любой кодировке. Но акцентированное «é» представляется по-разному в зависимости от кодировки: в UTF-8 это двухбайтовая последовательность 0xC3 0xA9, а в Latin-1 — одиночный байт 0xE9. Когда программа читает байты UTF-8 0xC3 0xA9 по правилам Latin-1, она выдаёт два отдельных символа — Ã и © — вместо одного символа é. Эта подмена и есть кракозябры.
- é превращается в é — байты UTF-8, прочитанные как Latin-1 (самый частый паттерн)
- ü превращается в ü — то же расхождение для немецкого умлаута ü
- ’ (правая одиночная кавычка) превращается в ’ — типографская кавычка UTF-8, неверно прочитанная как Latin-1
- – (среднее тире) превращается в – — часто в тексте, вставленном из Word или PDF
- Символ замены Unicode — валидный символ был принудительно помещён в контекст, который не может его представить
Note
Почему возникают ошибки кодировки
Ошибки кодировки — это проблема стыков системы. Они возникают, когда текст пересекает границу — между файлом и приложением, между базой данных и API, между веб-сервером и браузером, — а отправляющая и принимающая стороны расходятся во мнении о кодировке текста. В мире, где UTF-8 — универсальный стандарт, такие ошибки должны быть редкостью. Но они часты, потому что легаси-системы, инструменты Windows и некоторые базы данных по умолчанию всё ещё используют старые кодировки.
Самые частые источники
- CSV-файлы из Excel — Excel по умолчанию сохраняет CSV как Windows-1252 в Windows, а не UTF-8. При открытии в Linux или Python акцентированные символы искажаются.
- Базы MySQL с charset latin1 — старые установки MySQL по умолчанию используют `latin1` для кодировок столбцов. Хранение UTF-8-данных в них вызывает кракозябры при чтении.
- Заголовки и тела писем — почтовые клиенты, не объявляющие charset или неверно трактующие объявление, порождают кракозябры в полях От, Тема и теле.
- Извлечение текста из PDF — PDF встраивает шрифты с пользовательскими отображениями глифов, не всегда соответствующими стандартным кодовым точкам Unicode, что даёт искажённый вывод при копировании.
- HTTP-ответы без charset в Content-Type — сервер, отправляющий `Content-Type: text/html` без `; charset=utf-8`, оставляет браузер гадать, и он часто гадает неверно.
UTF-8 против Windows-1252 — самое частое расхождение
Windows-1252 (также CP1252) — надмножество Latin-1, разработанное Microsoft для западноевропейских языков. Оно использует один байт на символ и покрывает 256 кодовых точек — достаточно для английского, французского, немецкого, испанского и португальского. UTF-8 использует от одного до четырёх байтов на символ и покрывает все 1,1 миллиона кодовых точек Unicode. Когда текст UTF-8 читается как Windows-1252, многобайтовые последовательности дают характерные паттерны кракозябр из двух-трёх символов. Обратный случай — текст Windows-1252, прочитанный как UTF-8, — даёт символы замены (□ или ?), потому что одиночные старшие байты не являются валидными UTF-8-последовательностями.
Текст без метаданных кодировки — не текст: это последовательность байтов, ожидающая неверного истолкования.
Как обнаружить проблемы кодировки
Обнаружить проблему кодировки обычно просто — визуальный облик кракозябр достаточно характерен, чтобы опознать паттерн расхождения. Но для программного обнаружения или для текста, который выглядит правильно, но содержит невидимые проблемы, нужны специальные приёмы.
Визуальное распознавание паттернов
Самый надёжный диагностический признак — сам паттерн кракозябр. Текст UTF-8, прочитанный как Latin-1, даёт характерный префикс «Ã» со вторым символом — например, é для é, à для à, ü для ü. Типографская пунктуация из Word или rich-text-редакторов даёт последовательности, начинающиеся с †— например, ’ для ’ и “ для “. Если вы видите такие последовательности, решение — перекодировать байты из Latin-1 обратно в UTF-8.
Программное обнаружение кодировки
Для файлов и потоков данных, содержимое которых нельзя увидеть глазами, используйте библиотеку `chardet` (Python) или пакет `jschardet` (Node.js) для автоопределения кодировки по байтовым паттернам. Эти библиотеки анализируют частоту и распределение значений байтов, чтобы определить наиболее вероятную кодировку. Они не на 100% точны — короткие строки и строки с малым числом не-ASCII-символов труднее классифицировать уверенно, — но типовые случаи обрабатывают хорошо. Используйте поиск символов Unicode, чтобы инспектировать отдельные кодовые точки и их ожидаемые байтовые представления при отладке конкретных символов.
Tip
Как исправить кракозябры онлайн
Самый быстрый способ починить текст с кракозябрами — инструмент починки Unicode и кодировок. Он работает целиком в вашем браузере — без загрузки на сервер и регистрации — и автоматически обрабатывает самые частые расхождения UTF-8/Latin-1, искажения типографских кавычек и удаление невидимых символов.
Определите паттерн расхождения кодировок
Прежде чем чинить кракозябры, определите, с каким расхождением вы имеете дело. Посмотрите на искажённые символы: если видите последовательности é или ü — это UTF-8, прочитанный как Latin-1. Если видите ’ или “ — в тексте типографские кавычки или пунктуация, искажённые тем же способом. Если видите знаки вопроса или символы □ — кодировка была перепутана наоборот: не-UTF-8-байты были принудительно помещены в контекст UTF-8.
Вставьте повреждённый текст в инструмент починки
Откройте инструмент починки Unicode и кодировок и вставьте свой текст с кракозябрами в поле ввода. Инструмент немедленно анализирует текст и определяет наиболее вероятную починку: перекодирование из Latin-1 в UTF-8, исправление последовательностей типографских кавычек, удаление символов нулевой ширины, нормализацию форм Unicode или удаление маркеров порядка байтов. Определение происходит в вашем браузере — ваш текст не покидает устройство.
Выберите пару кодировок и примените исправление
Если автоопределение верно, нажмите «Починить», чтобы применить исправление. Если автоматический выбор не соответствует вашему случаю, вручную выберите исходную кодировку (в которой текст был неверно прочитан) и целевую (в которой его следовало прочитать). Для большинства веб-контента пара — Latin-1 → UTF-8. Для CSV-файлов Windows — часто Windows-1252 → UTF-8.
Скопируйте починенный текст и проверьте
После починки скопируйте вывод и вставьте обратно в исходный контекст — редактор документов, интерфейс базы данных или файл кода. Убедитесь, что все акцентированные символы, кавычки и спецсимволы отображаются правильно, прежде чем сохранять или коммитить изменения. Для массовой починки данных в базе протестируйте паттерн на выборке строк, прежде чем применять исправление ко всей таблице.
Инструмент починки Unicode и кодировок
Исправляйте кракозябры, чините артефакты кодировок, нормализуйте Unicode и удаляйте невидимые символы — бесплатно, в браузере, без загрузки файлов.
Частые паттерны кракозябр и их исправление
Разные расхождения кодировок дают разные визуальные паттерны. Распознав паттерн, вы узнаете и причину, и правильное исправление — какую пару кодировок применить или какую операцию починки запустить.
| Паттерн кракозябр | Исходный символ | Причина | Исправление |
|---|---|---|---|
| é | é (e с акутом) | UTF-8 прочитан как Latin-1 | Перекодировать Latin-1 → UTF-8 |
| ü | ü (u с умлаутом) | UTF-8 прочитан как Latin-1 | Перекодировать Latin-1 → UTF-8 |
| À | À (a с грависом) | UTF-8 прочитан как Latin-1 | Перекодировать Latin-1 → UTF-8 |
| ’ | ’ (правая кавычка) | UTF-8 прочитан как Latin-1 | Перекодировать Latin-1 → UTF-8 |
| “ | “ (левая кавычка) | UTF-8 прочитан как Latin-1 | Перекодировать Latin-1 → UTF-8 |
| – | – (среднее тире) | UTF-8 прочитан как Latin-1 | Перекодировать Latin-1 → UTF-8 |
| ’ | ’ (правая кавычка) | UTF-8 прочитан как Windows-1252 | Перекодировать Windows-1252 → UTF-8 |
| ? или □ | Любой не-ASCII-символ | Не-UTF-8 в контексте UTF-8 | Определить исходную кодировку через chardet |
Проблема двойного кодирования
Особенно коварная разновидность — двойные кракозябры: текст был дважды закодирован неправильно. Это даёт последовательности вроде © вместо © или Æ¢ вместо ¢. Случается, когда уже испорченный текст сохраняют, а затем ещё раз читают с неверной кодировкой. Починка требует двух проходов перекодирования в обратном порядке. Инструмент починки Unicode и кодировок автоматически обнаруживает и обрабатывает самые частые паттерны двойного кодирования.
Warning
Профилактика ошибок кодировки
Долгосрочное решение проблемы кракозябр — принудительный UTF-8 на каждом стыке системы: файловое хранилище, база данных, API и веб-слой. Вот конкретные места, где объявления кодировки должны быть явными.
Базы данных — объявляйте UTF-8 везде
В MySQL и MariaDB установите кодировку по умолчанию `utf8mb4` (не `utf8` — MySQL-овский `utf8` покрывает лишь 3-байтовые последовательности и исключает эмодзи и редкие символы Unicode). Установите её на трёх уровнях: умолчание сервера в `my.cnf`, кодировка базы и кодировки отдельных столбцов. В PostgreSQL для новых установок по умолчанию уже UTF-8. В SQLite текст всегда UTF-8 по умолчанию.
-- MySQL: set all levels to utf8mb4
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;Файлы — всегда сохраняйте в UTF-8
При сохранении текстовых файлов, CSV-экспортов или файлов конфигурации всегда выбирайте UTF-8. В VS Code кодировка показана в строке состояния — щёлкните, чтобы сменить. В Excel экспортируйте CSV как «CSV UTF-8 (разделители — запятые)», а не как стандартный «CSV (разделители — запятые)». В Python-скриптах, пишущих файлы, всегда явно передавайте `encoding='utf-8'` в вызов `open()`, не полагаясь на системное умолчание. Очищайте текст после вставки из внешних источников с помощью очистителя текста писем, который удаляет невидимые символы и автоматически нормализует пробелы.
API и HTTP — объявляйте charset в Content-Type
Каждый HTTP-ответ с текстом должен содержать объявление charset: `Content-Type: application/json; charset=utf-8` или `Content-Type: text/html; charset=utf-8`. Без него клиент угадывает — а старые HTTP-клиенты по умолчанию используют Latin-1 для ответов `text/html`. Для HTML-страниц добавьте также `<meta charset="UTF-8">` первым элементом внутри `<head>`. Для JSON API `Content-Type: application/json` подразумевает UTF-8 по RFC, но явность устраняет двусмысленность и предотвращает проблемы с нестандартными клиентами.
Чек-лист кодировок по контекстам
- Файлы Python: добавьте заголовок `# -*- coding: utf-8 -*-` для Python 2; в Python 3 он не нужен, но безвреден
- Строки подключения MySQL: включите `charset=utf8mb4` в DSN — например `mysql+pymysql://user:pass@host/db?charset=utf8mb4`
- Чтение файлов в Node.js: передавайте `encoding: "utf8"` в `fs.readFile()` или используйте `Buffer.from(data).toString("utf8")`
- Документы XML и HTML: всегда включайте `<?xml version="1.0" encoding="UTF-8"?>` и `<meta charset="UTF-8">`
- Библиотеки отправки писем: задайте `Content-Type: text/plain; charset=utf-8` и `Content-Transfer-Encoding: 8bit` или `quoted-printable`
Нормализация Unicode и невидимые символы
Помимо классического расхождения UTF-8/Latin-1, ещё две проблемы Unicode порождают тонкие, труднее обнаруживаемые баги: расхождения нормализации и невидимые символы. Оба могут ломать сравнение строк, приводить к промахам поиска в базе и неполным результатам поиска — даже когда текст на экране выглядит одинаково.
Формы нормализации Unicode
Unicode позволяет представлять один и тот же видимый символ несколькими способами. Буква «é» может быть закодирована одной прекомпозированной кодовой точкой (U+00E9) или комбинацией «e» (U+0065) и комбинируемого акута (U+0301). На экране они выглядят одинаково, но это разные байтовые последовательности, которые проваливают проверки равенства строк. Поэтому поиск «résumé» в базе иногда не находит результаты — сохранённый текст использует другую форму нормализации. NFC (каноническая декомпозиция, за которой следует каноническая композиция) — рекомендуемая нормальная форма для большинства приложений. Инструмент починки Unicode и кодировок нормализует текст к NFC в рамках процесса починки.
Невидимые и нулевой ширины символы
Символы нулевой ширины — это кодовые точки Unicode, которые занимают место в строке, но не отображаются. Их часто вставляют текстовые процессоры, чат-приложения и операции копирования-вставки из PDF или веб-страниц. Частые виновники — пробел нулевой ширины (U+200B), неразрывный пробел нулевой ширины (U+FEFF, он же маркер порядка байтов) и различные управляющие символы двунаправленного текста (U+200E, U+200F, U+202A-U+202E). Эти символы ломают regex-паттерны, путают токенизаторы и заставляют выглядящие одинаково строки сравниваться как неравные. Используйте поиск символов Unicode, чтобы выявить подозрительные кодовые точки в строке.
Note
Поиск символов Unicode
Ищите любой символ Unicode по кодовой точке или имени, либо вставьте символ, чтобы выявить невидимые или подозрительные кодовые точки в вашем тексте.
Key takeaways
- Кракозябры возникают из-за чтения байтов текста с неверной кодировкой — чаще всего байты UTF-8 прочитаны как Latin-1 или Windows-1252.
- Паттерн é (вместо é) — диагностическая сигнатура кракозябр «UTF-8 как Latin-1» — распознав паттерн, вы узнаёте точное необходимое исправление.
- Инструмент починки Unicode и кодировок автоматически находит и исправляет частые паттерны кракозябр, невидимые символы и проблемы нормализации Unicode в вашем браузере.
- Никогда не чините кракозябры поиском-заменой по искажённым последовательностям — всегда чините на уровне кодировки, корректно перекодируя байты.
- Предотвращайте ошибки кодировки, явно объявляя UTF-8 на каждом стыке системы: файлы, базы данных, ответы API и HTTP-заголовки.
- Невидимые символы (пробел нулевой ширины, BOM, двунаправленные управляющие) ломают сравнение и поиск даже когда текст выглядит правильно — их нужно удалять программно.
- Расхождения форм нормализации Unicode (NFC против NFD) заставляют выглядящие одинаково строки проваливать проверку равенства — нормализуйте к NFC перед сохранением или сравнением текста.