Как компьютер хранит и выводит текст
Компьютер принципиально не умеет хранить буквы, знаки препинания или смайлики. Процессор и память оперируют исключительно числами в двоичной системе. Чтобы записать фразу на экране, инженеры договорились сопоставлять каждому печатному знаку свой уникальный порядковый номер. Этот общий свод правил называют таблицей кодировки.
Сам процесс вывода текста на экран разбит на два последовательных шага. Сначала текстовый редактор или браузер берет байты из файла и переводит их по таблице кодировки в абстрактные номера символов. Затем графическая подсистема операционной системы передает эти номера установленному шрифту. Шрифт находит внутри себя векторный рисунок, называемый глифом, и отрисовывает контуры на матрице монитора. Сбой на любом из этих двух этапов приводит к искажению текста.
История кодировок от семи бит до глобального стандарта
В 1963 году в США утвердили стандарт ASCII, ставший фундаментом компьютерной типографики. Создатели выделили под кодирование одного символа 7 бит, что давало 128 уникальных комбинаций. Этого объема с запасом хватило на латинский алфавит двух регистров, арабские цифры, базовую пунктуацию и служебные команды управления печатью вроде перевода каретки.
Компьютеры быстро распространились по миру, и семи бит стало критически мало для других языков. Архитектура памяти при этом уже стандартизировалась вокруг байта размером в 8 бит. Лишний восьмой бит удвоил доступное адресное пространство до 256 позиций. Первую половину таблицы от 0 до 127 оставили неизменной для совместимости со старыми программами на ASCII. Вторую половину, с номерами от 128 до 255, разные страны и производители операционных систем начали заполнять собственными национальными буквами.
Так возник хаос однобайтовых кодовых страниц. В русскоязычном сегменте вычислительной техники одновременно закрепились несколько несовместимых стандартов. Операционная система MS-DOS использовала CP866, среда Microsoft Windows перешла на Windows-1251, компьютеры Apple работали на MacCyrillic, а серверы под управлением Unix отправляли почту в KOI8-R.
Откуда берутся кракозябры
Проблема так называемого моджибейка, или кракозябр, возникает при несовпадении кодовой страницы сохранения и кодовой страницы чтения. Если автор сохранил документ в кодировке Windows-1251, русская буква «Р» записалась в файл числом 240. Когда этот же документ открывают в программе, настроенной по умолчанию на DOS-таблицу CP866, байт 240 интерпретируется по тамошним правилам. В CP866 номеру 240 соответствует буква «р». Текст превращается в кашу из случайных символов, ломаных рамок псевдографики и латинских вставок.
Появление Юникода и триумф формата UTF-8
В конце восьмидесятых годов консорциум разработчиков приступил к созданию единого стандарта Unicode. Цель заключалась в присвоении индивидуального номера абсолютно каждому существующему знаку письменности, древним иероглифам, математическим формулам и пиктограммам. В современных версиях Юникода зарезервировано свыше миллиона кодовых позиций, из которых занято около ста пятидесяти тысяч.
Юникод решает задачу каталогизации, но для сохранения этих гигантских номеров в память потребовались специальные форматы кодирования. Наиболее удачным решением стал UTF-8, разработанный Кеном Томпсоном и Робом Пайком в 1992 году. Его главное достоинство заключается в переменной длине символа.
- Символы стандартной латиницы записываются ровно одним байтом и полностью совпадают со старым стандартом ASCII 1963 года.
- Кириллица, греческий алфавит, арабская вязь и знаки европейских языков с диакритикой кодируются двумя байтами.
- Китайские, японские и корейские иероглифы требуют трех байтов на каждый символ.
- Редкие исторические письмена, нотные знаки и современные эмодзи занимают четыре байта.
Почему символы превращаются в пустые квадраты
Если кодировка определена верно, но на экране вместо знака виден пустой белый прямоугольник, прямоугольник с вопросом или перечеркнутый крестом блок, причина кроется в шрифте. Такой глиф-заглушку в среде программистов часто называют тофу за сходство с кусочком соевого сыра.
Шрифт представляет собой отдельный файл с векторными иллюстрациями. Создание каждого начертания требует кропотливой ручной работы цифрового художника и шрифтового дизайнера. Практически ни один общедоступный коммерческий шрифт не содержит всех ста пятидесяти тысяч символов Юникода. Базовые шрифты в операционных системах обычно содержат от пятисот до двух тысяч наиболее употребительных глифов для целевого региона продаж.
Когда программа запрашивает у операционной системы отрисовку редкого японского кандзи или математического интеграла шрифтом Arial, система понимает номер символа, но не находит подходящего рисунка внутри файла шрифта. В этот момент срабатывает механизм отката, когда система пытается подставить глиф из запасного системного шрифта. Если ни в одном установленном в операционной системе шрифте изображения для этого кода нет, система вынужденно рисует стандартный пустой контур.
Частые вопросы
Что делать, если скачанный текстовый файл открылся нечитаемыми знаками?
Нужно открыть файл в продвинутом текстовом редакторе вроде Notepad++ или VS Code и принудительно переключить кодировку отображения на Windows-1251, CP866 или UTF-8 без изменения самого содержимого документа.
Чем кодировка UTF-8 отличается от UTF-16?
В UTF-8 минимальный размер символа составляет один байт, а длина записи варьируется от одного до четырех байт. В UTF-16 под любой базовый знак сразу отводится минимум два байта, из-за чего обычные тексты на латинице начинают весить ровно в два раза больше.
Можно ли установить один универсальный шрифт, где есть абсолютно все символы?
Технический формат шрифтов TrueType и OpenType имеет аппаратное ограничение на максимальное число глифов внутри одного файла, равное 65535 штукам. Создать единый шрифт под весь Юникод физически невозможно, поэтому крупные компании вроде Google создают целые семейства составных шрифтов, например Noto.
Почему браузеры сейчас почти никогда не показывают кракозябры?
Современные сайты указывают кодировку прямо в служебных заголовках страницы через метатег charset со значением UTF-8, а сами браузеры научились автоматически угадывать кодовую страницу по частоте встречаемости байтов в тексте.