RunToolz iconRunToolz
Welcome to RunToolz!
КодировкаUnicodeИнструменты разработчика

Кодировка символов: от ASCII до UTF-8

Почему текст иногда превращается в вопросительные знаки и странные символы. Практическое руководство по кодировкам.

RunToolz Team16 января 2026 г.3 min read

Открываешь файл и видишь ü вместо u. Или база данных возвращает ???? там, где должно быть имя. Или приходит письмо с =?UTF-8?B? разбросанным по теме.

Добро пожаловать в мир проблем с кодировкой символов.

Краткая история

Компьютеры хранят числа, а не буквы. Поэтому кто-то должен был решить, какое число означает какую букву. В 1960-х ASCII присвоил номера 0-127 английским буквам, цифрам и основным символам. Буква "A" — это 65. Пробел — 32. Просто.

Но ASCII покрывает только 128 символов. Для английского хватает. Для немецких умляутов, японских кандзи, арабской письменности или тысяч других символов, которые люди реально используют, — нет.

Хаос до Unicode

Разные регионы изобретали свои кодировки. Западная Европа получила ISO-8859-1. Япония — Shift-JIS. Россия — KOI8-R. Китай — GB2312. Каждая работала нормально внутри своей экосистемы. Как только их смешивали — всё ломалось.

Файл, сохранённый в одной кодировке и открытый в другой, даёт кракозябры — ту самую кашу из неправильных символов, которую ты наверняка видел. cafe превращается в café, когда файл UTF-8 читается как ISO-8859-1.

Unicode решил проблему сопоставления

Unicode дал каждому символу уникальный номер (называемый «кодовой точкой»). Латинская A — это U+0041. Снеговик — U+2603. Каждый эмодзи, каждая письменность, каждый математический символ получает свою кодовую точку. Более 150 000 символов и число растёт.

Но Unicode — это только сопоставление. Он не говорит, как хранить эти числа в виде байтов. Это задача кодировки.

Хотите попробовать сами?Подсчитать символы и байты

UTF-8: кодировка-победитель

UTF-8 — это способ, которым большая часть интернета хранит текст Unicode. Ключевой приём: используется переменное количество байтов на символ.

  • Символы ASCII (английские буквы, цифры): по 1 байту
  • Европейские символы с диакритиками: по 2 байта
  • Азиатские символы (CJK): по 3 байта
  • Эмодзи и редкие символы: по 4 байта

Это значит, что английский текст в UTF-8 идентичен ASCII. Старые системы не ломаются. Но при этом можно представить любой символ в мире.

Сейчас более 98% сайтов используют UTF-8. Война кодировок окончена, и UTF-8 победил.

UTF-8 vs UTF-16 vs UTF-32

UTF-8: Переменная ширина (1-4 байта). Эффективен для текста на английском. Веб-стандарт.

UTF-16: Переменная ширина (2 или 4 байта). Используется внутри JavaScript, Java и Windows. Каждый символ — минимум 2 байта, поэтому менее эффективен для ASCII-текста.

UTF-32: Фиксированная ширина (4 байта на символ). Просто, но расточительно. Редко используется для хранения или передачи.

string.length в JavaScript считает кодовые единицы UTF-16, а не символы. Поэтому "😀".length возвращает 2, а не 1.

Когда кодировка ломается

Чтение файла в неправильной кодировке. Байты в порядке, но интерпретируются неправильно. Решение: указать правильную кодировку при открытии.

Несоответствие кодировки базы данных. Приложение отправляет UTF-8, а столбец базы данных настроен на latin1. Символы за пределами ASCII портятся. Решение: настройте базу на utf8mb4 (не просто utf8 в MySQL, который обрабатывает только 3-байтовые символы).

Отсутствие заголовка charset в HTTP. Если сервер не отправляет Content-Type: text/html; charset=utf-8, браузерам приходится угадывать. Иногда они угадывают неправильно.

Хотите попробовать сами?Кодировать/декодировать URL

Практические советы

Всегда используй UTF-8. Если нет очень конкретной причины поступить иначе, UTF-8 — правильный выбор для всего.

Объявляй кодировку явно. В HTML: <meta charset="utf-8">. В HTTP: Content-Type: text/html; charset=utf-8. Не заставляй системы гадать.

Будь осторожен с длиной строк. В JavaScript подсчёт символов усложняется с эмодзи и комбинирующими символами. Используй Array.from(str).length или API Intl.Segmenter для точного подсчёта.

Следи за BOM. Метка порядка байтов (U+FEFF) иногда появляется в начале файлов UTF-8. Она невидима, но может сломать парсеры. Некоторые редакторы добавляют её тихо.


Кодировка символов — не самая захватывающая тема, но понимание сэкономит часы отладки. Используй UTF-8 везде, объявляй явно, и когда увидишь кракозябры, будешь точно знать, где искать.