Кодирование информации — это перевод данных из одной формы представления в другую по заранее известным правилам, чтобы их было удобно хранить, передавать и обрабатывать. Обратная операция называется декодированием. Ниже разберем, зачем компьютеру двоичный код, какие есть виды и способы кодирования и как на практике кодируются текст, цвет, звук и видео — с примерами на Python, которые можно запустить самому.
Содержание
Что такое кодирование информации
Любое кодирование опирается на две вещи: набор символов (алфавит) и правило соответствия. Пример из жизни — азбука Морзе, где буквы заменяются точками и тире. Компьютер делает то же самое, только его «алфавит» — всего два состояния.
Важно не путать кодирование и шифрование. При кодировании правило открыто, цель — удобство обработки; при шифровании правило (ключ) скрыто, цель — защита от посторонних. В старых статьях кодирование часто называют «шифрованием» — это неточность.
Код — это набор знаков и правило, по которому одни символы сопоставляются другим. Декодирование — восстановление исходных данных из кода по тому же правилу.
Почему компьютер использует двоичный код
На физическом уровне 0 и 1 кодируются двумя различимыми состояниями схемы. Конкретная реализация зависит от устройства: например, в ячейке динамической памяти DRAM заряд хранит конденсатор, а транзистор управляет доступом к ячейке; в SSD бит — это захваченный заряд в ячейке флеш-памяти; на жестком диске — направление намагниченности участка. Общая идея одна: два состояния надежно отличить друг от друга проще, чем десять, поэтому вся цифровая электроника работает с двумя уровнями сигнала.
Двоичный код — это способ представления информации всего двумя символами, 0 и 1. Любые данные (текст, картинка, звук, видео) в итоге превращаются в последовательность нулей и единиц.
Бит — минимальная единица информации, один разряд двоичного кода со значением 0 или 1. Один бит различает 2 варианта, два бита — 4, три — 8. Общая формула: N бит кодируют 2^N вариантов.
for n in range(1, 5):
print(n, "бит ->", 2 ** n, "вариантов")
Вывод:
1 бит -> 2 вариантов
2 бит -> 4 вариантов
3 бит -> 8 вариантов
4 бит -> 16 вариантов
Восемь бит образуют байт — 256 вариантов (от 0 до 255). Байт — основная единица, которой оперирует память и файлы.
Виды и способы кодирования: карта уровней
Чтобы не путать «что кодируем» с «как это записано», удобно смотреть на кодирование как на несколько уровней. Любой объект проходит один и тот же путь: от исходной сущности к номеру, затем к байтам и, наконец, к физической записи на носителе.
- Объект — исходная сущность (буква, точка изображения, мгновенный уровень звука).
- Абстрактный код — номер объекта по выбранному правилу (кодовая точка, тройка RGB, целое значение уровня). Пока это только число, без привязки к байтам.
- Байтовое представление — как этот номер укладывается в байты (кодировка текста, число байт на канал цвета, формат аудиоотсчета).
- Физический носитель — как байты хранит устройство (заряд, намагниченность, ячейка флеш-памяти).
Проведем по этой карте три сквозных объекта — букву, пиксель и аудиоотсчет:
| Уровень | Буква «Я» | Пиксель цвета | Аудиоотсчет |
|---|---|---|---|
| Объект | символ «Я» | одна точка изображения | мгновенный уровень сигнала |
| Абстрактный код | кодовая точка U+042F | RGB (40, 120, 200) | целое число уровня, напр. 15230 |
| Байтовое представление | D0 AF (UTF-8) |
28 78 C8 (по байту на канал) |
7E 3B (16 бит, little-endian) |
| Физический носитель | заряд / намагниченность / ячейка флеш | то же | то же |
Дальше «виды» — это верхняя строка (буква, пиксель, звук), а «способы» — как заполняются средние строки для каждого вида. Разберем их по очереди.
Как кодируется текст: ASCII, Unicode, UTF-8
Здесь важно развести два понятия, которые легко путаются.
Набор символов (character set) отвечает на вопрос «какой номер у символа». Unicode — это именно набор символов: он назначает каждому абстрактному символу кодовую точку (code point), например «Я» получает кодовую точку U+042F. Сам по себе номер не говорит, сколькими байтами его записать.
Кодировка (encoding) отвечает на вопрос «как записать этот номер байтами». UTF-8, UTF-16 — это кодировки: они задают правило перевода кодовой точки в конкретные байты. В UTF-8 кодовая точка U+042F превращается в два байта D0 AF.
Мини-цепочка целиком: символ «Я» -> кодовая точка U+042F (набор символов) -> байты D0 AF (кодировка UTF-8).
Историческая база — ASCII: 7 бит на символ, 128 позиций (латиница, цифры, знаки препинания, управляющие символы). Для кириллицы и других алфавитов места не хватило, поэтому появились 8-битные кодировки на 256 символов: первые 128 совпадают с ASCII, вторые 128 отданы под национальный алфавит (для русского — Windows-1251, KOI8-R, ISO 8859-5).
Проблема 8-битных кодировок: в один текст нельзя одновременно вписать, например, кириллицу и греческий, а при неверной кодировке появляются «кракозябры». Решение — Unicode: единая таблица, где своя кодовая точка есть у символа любого языка, а также у emoji. Unicode — это не размер в байтах, а нумерация: кодовые точки идут до U+10FFFF, всего чуть больше 1,1 млн возможных позиций, из них в версии 17.0 назначено 159 801 символ.
Как записать кодовую точку в байты — решает кодировка представления. Самая распространенная в вебе — UTF-8: одна кодовая точка занимает от 1 до 4 байт. Латиница остается 1 байтом (совместимость с ASCII), кириллица — 2 байта, многие emoji — 4 байта.
| Кодировка | Размер | Сколько символов | Что покрывает |
|---|---|---|---|
| ASCII | 7 бит | 128 | латиница, цифры, базовые знаки |
| Windows-1251 | 8 бит | 256 | ASCII + кириллица |
| Unicode (набор символов) | кодовые точки до U+10FFFF | 159 801 назначено (v17.0) | все письменности + emoji |
| UTF-8 | 1-4 байта на кодовую точку | весь Unicode | ASCII-совместима, стандарт веба |
| UTF-16 | 2 или 4 байта | весь Unicode | строки внутри Windows, Java, JS |
Важная оговорка про «символы». Одна кодовая точка — это не всегда один видимый символ. Видимый пользователю символ называют графемой, и он может состоять из нескольких кодовых точек: например, emoji с модификатором тона кожи или семейный emoji склеиваются из нескольких кодовых точек и занимают в UTF-8 больше 4 байт. Функция len(s) в Python считает именно кодовые точки, а не всегда графемы.
| Символ | Кодовая точка | UTF-8 байты | len() в Python |
|---|---|---|---|
| A | U+0041 | 41 |
1 |
| Я | U+042F | D0 AF |
1 |
| € | U+20AC | E2 82 AC |
1 |
| 😀 | U+1F600 | F0 9F 98 80 |
1 |
| 👍🏽 | U+1F44D U+1F3FD | F0 9F 91 8D F0 9F 8F BD |
2 |
Последняя строка — тот самый случай: один видимый значок (палец с тоном кожи) — это две кодовые точки, восемь байт и len() равный 2.
Посмотрим на кодирование текста в Python. Функция ord дает номер (кодовую точку) символа, chr — обратно символ по номеру:
print(ord('A')) # 65
print(chr(65)) # A
print(ord('Я')) # 1071, это U+042F
Вывод:
65
A
1071
Теперь превратим строку в байты через UTF-8 и посмотрим, сколько места она занимает:
s = 'Привет'
print(len(s)) # 6 кодовых точек
print(len(s.encode('utf-8'))) # 12 байт (кириллица по 2 байта)
print(s.encode('utf-8'))
Вывод:
6
12
b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82'
Типичная ошибка: чужая кодировка при декодировании
Байты без указания кодировки — просто числа. Если декодировать их не той таблицей, получится ошибка или мусор. Разберем тройкой.
Неверный код — пытаемся прочитать UTF-8 байты как ASCII:
b = 'Привет'.encode('utf-8')
print(b.decode('ascii'))
Фактический результат — программа падает:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
ASCII знает только позиции 0-127, а первый байт кириллицы равен 0xd0 (208) — выходит за диапазон. Исправление — декодировать той же кодировкой, которой кодировали:
b = 'Привет'.encode('utf-8')
print(b.decode('utf-8')) # Привет
Правило простое: кодируй и декодируй одной кодировкой, а при работе с файлами и сетью явно указывай encoding='utf-8'.
Как кодируются числа
Целые числа переводятся в двоичную систему счисления напрямую. Функция bin в Python показывает двоичную запись:
print(bin(5)) # 0b101
print(bin(255)) # 0b11111111
print(0b101) # 5
Вывод:
0b101
0b11111111
5
Отрицательные числа — отдельная тема. В регистрах процессора и типах фиксированной ширины (например, int32 в C или Java) их обычно хранят в дополнительном коде (two’s complement). В Python тип int — произвольной точности: он не занимает фиксированное число бит, а битовые операции определены так, будто число записано в дополнительном коде с бесконечным числом знаковых разрядов. Поэтому bin(-5) показывает не «настоящие биты в памяти», а знак и модуль. Увидеть дополнительный код в конкретной ширине можно маской:
print(bin(-5)) # -0b101 (знак и модуль)
print(bin(-5 & 0xFF)) # 0b11111011 - дополнительный код в 8 битах
Вывод:
-0b101
0b11111011
Дробные числа хранят в формате с плавающей точкой (IEEE 754). Из-за конечного числа битов дроби хранятся приближенно — отсюда классический 0.1 + 0.2, дающий не ровно 0.3. Это не ошибка Python, а свойство двоичного представления дробей.
Как кодируются цвет и графика
Растровое изображение делится на пиксели — мелкие точки. Цвет каждого пикселя задают моделью RGB: три числа — доли красного, зеленого и синего. Обычно на каждый канал отводится 8 бит (0-255), значит на пиксель — 24 бита, а всего оттенков 256^3, это около 16,7 млн.
Глубина цвета — это число бит на пиксель: чем больше, тем больше оттенков. Разрешение (число пикселей) влияет на детализацию: камера на 12 мегапикселей раскладывает кадр примерно на 12 млн точек.
Векторная графика устроена иначе: вместо сетки пикселей хранятся описания фигур — линий, кривых, окружностей с их параметрами (координаты, толщина, цвет заливки). Такую картинку можно масштабировать без потери качества. Для фотографий обычно эффективнее растр (JPEG, PNG): в них множество несистемных оттенков, которые формулами не описать. Вектор удобнее для геометрических объектов — логотипов, иконок, шрифтов, схем (SVG).
Как кодируются звук и видео
Звук — это колебания воздуха. Микрофон превращает их в электрический сигнал, а звуковая карта измеряет его уровень много раз в секунду — это дискретизация. Частота дискретизации 44100 Гц означает 44100 замеров в секунду; каждый замер (отсчет) округляется до ближайшего уровня из доступных — это квантование. Чем выше частота и разрядность отсчета, тем точнее восстановится звук, но тем больше размер файла.
Видео — это графика плюс звук. Кадры кодируются как растровые изображения, звуковая дорожка — как аудио. Чтобы файл не был огромным, применяют сжатие. Упрощенно это работает так: кодек хранит несколько внутрикодированных (опорных) кадров целиком, а остальные предсказывает по одному или нескольким опорным кадрам, записывая лишь отличия. Это именно упрощенная модель: в реальных кодеках есть разные типы кадров, а предсказание может опираться и на предыдущие, и на будущие кадры.
На этом принципе работают кодеки, например H.264, H.265 и AV1. Стандарты продолжают выходить: Alliance for Open Media опубликовал следующий за AV1 стандарт AV2 (актуальность и уровень поддержки стоит сверять на дату публикации). Поэтому лучше держаться конкретных названий, а не ярлыка «самый новый».
Выводы
- Кодирование — это перевод данных в другую форму по открытому правилу; декодирование — обратный перевод. Шифрование — другая задача (защита ключом), путать их не нужно.
- Компьютер работает в двоичном коде, потому что два различимых состояния схемы надежнее десяти; N бит кодируют 2^N вариантов, 8 бит — это байт и 256 значений.
- Удобно думать уровнями: объект -> абстрактный код (номер) -> байты -> физический носитель. «Виды» — это разные объекты (буква, пиксель, звук), «способы» — как заполняются средние уровни.
- В тексте различают набор символов (Unicode назначает кодовые точки) и кодировку (UTF-8/UTF-16 пишут кодовые точки байтами); главная причина «кракозябр» — декодирование не той кодировкой.
- Один видимый символ (графема) может состоять из нескольких кодовых точек, поэтому число символов, кодовых точек и байт в строке часто не совпадает.
Где применяется / связь с практикой
Понимание кодировок нужно каждый день: прочитать CSV без «кракозябр», не сломать текст при выгрузке из базы, корректно принять JSON от чужого API, разобраться, почему длина строки в символах и в байтах разная. Как только вы начинаете писать код, работать с файлами и сетью, кодировки перестают быть теорией.
Освойте тему на практике
Разобраться с этим удобно на Python: в нем строки и байты — разные типы, а методы encode и decode наглядно показывают, что происходит с данными. Собрать базу с нуля помогает курс Python Basic — там же на практике разбирают работу с текстом и файлами. Если хочется сначала присмотреться к формату и направлению, посмотрите ближайшие бесплатные вебинары и вживую задайте вопросы преподавателям.
Смежные темы: Кодирование символов и UTF, Введение в кодирование информации, Кодирование и декодирование: что должен знать программист.
FAQ
Чем кодирование отличается от системы счисления? Система счисления (двоичная, десятичная) — это способ записать число. Кодирование шире: оно сопоставляет по правилу любые данные, в том числе не-числовые, а уже их номера записываются в какой-то системе счисления.
Почему один и тот же файл открывается «кракозябрами» в одной программе и нормально в другой? Программы по умолчанию предполагают разные кодировки. Если текст сохранен в UTF-8, а редактор читает его как Windows-1251 (или наоборот), символы декодируются не теми таблицами. Нужно явно выбрать правильную кодировку при открытии.
Почему len() строки с emoji бывает больше, чем видно символов? Потому что len() считает кодовые точки, а один видимый значок (графема) — например, emoji с тоном кожи или семейный emoji — собран из нескольких кодовых точек. В UTF-8 такой символ занимает и больше 4 байт.



