🔍 КАК ЭТО УСТРОЕНО

Как компьютер хранит букву «ё» и эмодзи: история кодировок

Внутри компьютера нет ни букв, ни смайликов — только числа. Прослеживаем путь от ASCII на 128 символов до Unicode, который вмещает все языки мира и каждый эмодзи, и разбираемся, почему текст иногда превращается в «кракозябры».

Компьютер не знает букв — он знает только числа, и вся история письменности внутри машины свелась к одному вопросу: какое число какой букве дать.
Кодировка — это просто договор: какому символу соответствует какое число. Все «кракозябры» возникают, когда два собеседника подписали разные договоры.

На самом дне всё, что вы читаете на экране, — это числа. Буква, пробел, запятая, смайлик — каждому символу сопоставлено число, а число хранится в виде нулей и единиц. Вопрос лишь в том, по какому правилу мы это число назначаем. Это правило и называется кодировкой.

ASCII: тесная комната на 128 мест

В 1960-х договорились о таблице ASCII. В ней 128 символов: латинские буквы в двух регистрах, цифры, знаки препинания и служебные коды. Например, у заглавной «A» число 65, у пробела — 32. Семи бит хватало на все 128 значений, и для английского языка это работало прекрасно.

Но мир говорит не только по-английски. Куда девать кириллицу, греческий, арабский? Свободных номеров в ASCII не осталось.

Эпоха кодовых страниц и первых «кракозябр»

Решение нашли костыльное: использовать восьмой бит и втиснуть в освободившиеся 128 мест буквы своего языка. Так появились десятки несовместимых кодовых страниц: одна для русского, другая для греческого, третья для турецкого. Беда в том, что число, скажем, 200 в русской странице означало одну букву, а в греческой — совсем другую.

Стоило открыть русский текст в программе, настроенной на другую страницу, — и вместо слов появлялась знаменитая абракадабра вроде «Ð¿Ñивеѻ. Текст не испортился: просто числа читали по неправильному договору. Именно поэтому старые письма иногда приходили нечитаемыми.

Unicode: один номер для каждого символа на Земле

Чтобы покончить с хаосом, придумали Unicode — единую таблицу, где номер есть у каждого символа всех письменностей сразу. У латинской «A» — номер 65 (совместимость с ASCII сохранили), у кириллической «ё» — 1105, у эмодзи с улыбкой — 128512. Места хватает на миллион с лишним символов, и заняты пока не все. Номер символа в Unicode называют кодовой точкой.

Но Unicode — это только таблица соответствий «символ → номер». Остаётся вопрос: как записать эти номера в файл байтами?

UTF-8: гениальная экономия

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

  • обычные латинские символы (номера до 127) занимают 1 байт — и полностью совпадают с ASCII;
  • кириллица и большинство европейских букв — 2 байта;
  • иероглифы — 3 байта;
  • эмодзи и редкие знаки — 4 байта.

Красота в обратной совместимости: старый английский текст в ASCII оказывается валидным UTF-8 без единого изменения. А за иностранные буквы и смайлики мы платим лишними байтами только там, где они реально есть.

for s in ["A", "ё", "中", "😀"]:
    b = s.encode("utf-8")
    print(f"{s}: код {ord(s):>6}, байт в UTF-8: {len(b)}")

Почему эмодзи иногда «разваливается»

Многие эмодзи — это вообще не один символ, а склейка нескольких кодовых точек через невидимый «соединитель». Семья из четырёх человечков — это четыре эмодзи людей, сшитые вместе. Если программа не понимает соединитель, склейка распадается на отдельные фигурки. А цвет кожи добавляется отдельным символом-модификатором поверх базового. Так что за одним смайликом нередко прячется небольшая последовательность чисел — и весь этот зоопарк держится на одном простом принципе: договорились, какое число что значит, и аккуратно записали его в байты.

#Unicode#UTF-8#кодировки#текст#эмодзи