Как компьютер хранит текст: ASCII и UTF-8
В памяти компьютера нет букв. Есть только байты — числа от 0 до 255, как мы выяснили в статьях про двоичную запись и дополнительный код. Весь текст, который вы сейчас читаете, — это последовательность чисел, плюс соглашение о том, какое число какая буква. Разберём это соглашение по шагам — от ASCII 1963 года до UTF-8, на котором работает интернет.
Буквы — это числа
Компьютер умеет хранить и пересылать только биты. Чтобы хранить текст, нужно договориться о таблице соответствия: какое число означает какую букву. Такое соглашение называется кодировкой. Кодировка — не устройство и не программа, а просто договорённость, как азбука Морзе: «•−» означает A, потому что так договорились.
Если два компьютера договорились об одной кодировке — текст доходит без потерь. Если о разных — на экране «кракозябры»: числа те же, буквы другие.
ASCII: таблица на 128 символов
В 1963 году в США утвердили ASCII — американский стандартный код для обмена информацией. Семь бит дают 128 позиций, и каждую заняли: латинские буквы, цифры, знаки препинания и управляющие коды (перевод строки, звонок). Фрагмент таблицы:
| Код | Двоичный | Символ |
|---|---|---|
| 48 | 00110000 | 0 |
| 65 | 01000001 | A |
| 66 | 01000010 | B |
| 90 | 01011010 | Z |
| 97 | 01100001 | a |
| 122 | 01111010 | z |
В таблице спрятана занятная арифметика: код цифры «0» — 48, поэтому «символ минус 48» даёт значение цифры. Большие и маленькие буквы отличаются ровно одним битом: A = 65, a = 97, разница — 32, один бит в пятом разряде. Перевод регистра в любом языке программирования — это операция ИЛИ/И над одним битом, что роднит текстовые обработки со схемотехникой из статьи о масках.
256 символов мало: UNICODE
Один байт — 256 значений: латиница помещается, а вот алфавиты кириллицы, греческого, иврита, арабского и иероглифы — уже нет. В эпоху до интернета каждую кодовую страницу изобретали отдельно, и один и тот же байт 0xD0 в одной кодировке означал «Ð», в другой — «Р». Обмениваться текстами стало невозможно.
Решение — UNICODE: единая таблица на все символы мира (более 150 000: все алфавиты, иероглифы, математические знаки, эмодзи). Каждый символ получил постоянный номер — кодовую точку. Буква «Ж» — это номер 1046, где бы она ни встретилась.
UTF-8: умная упаковка
Хранить номера UNICODE «в лоб» расточительно: латинская «A» (номер 65) поместилась бы в один байт, а если тратить четыре байта на каждый символ, английский текст распух бы вчетверо. UTF-8 решает это переменной длиной:
— Символы с номерами 0–127 (весь ASCII) — 1 байт, байты неотличимы от старого ASCII.
— Кириллица и большинство алфавитов — 2 байта.
— Иероглифы — 3 байта, редкие символы и эмодзи — 4 байта.
Длина зашита в сам первый байт: если старший бит 0 — это однобайтовый ASCII; если байт начинается с 110 — символ длиной 2 байта; 1110 — из 3. Продолжающие байты всегда начинаются с 10. Благодаря этому UTF-8 не имеет проблемы «середины символа»: случайно отрезав строку, вы всегда определите границу. Слово «Ж» в UTF-8 — это два байта: 0xD0 0x96 (номер 1046 = 0x416 упакован по схеме 110xxxxx 10xxxxxx).
Именно поэтому UTF-8 стал языком интернета: английский текст остаётся однобайтовым, всё остальное — честно закодировано, и одна кодировка покрывает всю планету.
Проверь себя
Что такое кодировка?
Соглашение о соответствии между числами и символами. Сам компьютер хранит только числа; буквы появляются лишь при выводе по договорённой таблице.
Какой бит отличает заглавную латинскую букву от строчной в ASCII?
Один бит: A = 65 (01000001), a = 97 (01100001). Разница — ровно 32, бит в пятом разряде.
Почему UTF-8 победил, хотя есть «ровные» четырёхбайтовые форматы?
Из-за переменной длины: ASCII остаётся одним байтом, граница символа восстанавливается по старшим битам, и вся таблица UNICODE покрывается без исключений.