Таблицы кодировки, ASCII, Unicode и UTF-8, вычисление информационного объёма текста
Зачем нужно кодирование текста
Компьютер способен хранить и обрабатывать только числа в двоичном виде, поэтому любой символ текста — буква, цифра, знак препинания, пробел — должен быть представлен последовательностью бит. Кодирование текстовой информации — это установление взаимно однозначного соответствия между символами некоторого алфавита и числовыми кодами. Совокупность таких соответствий называют таблицей кодировки.
Принцип кодирования символов
Каждому символу алфавита ставится в соответствие уникальный числовой код — целое число, которое затем записывается в двоичной системе счисления и хранится в памяти компьютера. Если мощность алфавита равна N символов и все символы кодируются одинаковым числом бит (равномерное кодирование), то по формуле Хартли информационный вес одного символа составляет I=log₂N бит. Именно эта величина определяет, сколько бит памяти отводится на хранение одного символа текста.
Кодировка ASCII
Исторически первой широко распространённой таблицей кодировки стала ASCII (American Standard Code for Information Interchange), разработанная в 1960-х годах. Базовая таблица ASCII использует 7 бит на символ и кодирует N=2⁷=128 символов: латинские буквы, цифры, знаки препинания и служебные (управляющие) символы. Позже таблицу расширили до 8 бит, добавив ещё 128 кодов (128–255) для символов национальных алфавитов, псевдографики и специальных знаков — такую таблицу называют расширенной ASCII или просто однобайтовой кодировкой.
Мощность расширенной таблицы N=2⁸=256, поэтому информационный вес одного символа: I=log₂256=8 бит, то есть ровно 1 байт. Отсюда следует важное практическое правило: при использовании однобайтовой кодировки объём текста в байтах равен количеству символов в тексте.
Пример 1. Объём текста в однобайтовой кодировке
Дано: текстовый файл содержит 3 страницы по 40 строк, в каждой строке в среднем 60 символов. Текст закодирован в однобайтовой кодировке (например, Windows-1251). Найдите информационный объём текста в байтах и килобайтах.
Решение. Общее количество символов: K=3·40·60=7200 символов. Так как кодировка однобайтовая, информационный вес символа I=8 бит=1 байт, поэтому объём текста:
Переведём в килобайты: 7200/1024 ≈ 7,03 Кбайт.
Ответ: 7200 байт, или примерно 7,03 Кбайт.
Ограничения однобайтовых кодировок
Проблема однобайтовых кодировок в том, что 256 кодов недостаточно, чтобы одновременно разместить символы всех языков мира — латиницу, кириллицу, иероглифы, арабское письмо и так далее. Поэтому для разных языков создавались разные таблицы (например, отдельные кодировки для кириллицы: Windows-1251, КОИ8-Р, СР866), несовместимые друг с другом: один и тот же код в разных таблицах соответствует разным символам, из-за чего при неверном выборе кодировки текст превращается в «кракозябры».
Юникод — универсальная система кодирования
Чтобы раз и навсегда решить проблему несовместимости кодировок, был разработан стандарт Unicode (Юникод) — единая таблица, которая ставит в соответствие уникальный номер (кодовую точку) практически каждому символу любого языка мира, а также математическим знакам, эмодзи и символам псевдографики. Всего стандарт предусматривает более миллиона кодовых точек, что требует существенно больше 8 бит на символ при прямом кодировании.
Кодировка UTF-8
Чтобы не расходовать память впустую на символы, коды которых малы, для Юникода придумали кодировки с переменной длиной символа. Самая распространённая из них — UTF-8 (Unicode Transformation Format, 8-bit). В UTF-8 каждый символ кодируется от 1 до 4 байт в зависимости от диапазона его кодовой точки, при этом первые 128 символов (латиница, цифры, базовые знаки препинания — то есть весь набор ASCII) кодируются одним байтом, полностью совпадающим с кодом ASCII. Это обеспечивает обратную совместимость UTF-8 с ASCII-текстами.
| Диапазон кодовых точек Юникода | Длина кода в UTF-8 |
|---|---|
U+0000 – U+007F (латиница, цифры, ASCII) | 1 байт |
U+0080 – U+07FF (кириллица и другие алфавиты) | 2 байта |
U+0800 – U+FFFF (иероглифы, доп. символы) | 3 байта |
U+10000 – U+10FFFF (эмодзи, редкие символы) | 4 байта |
Пример 2. Объём текста в UTF-8
Дано: текст состоит из 50 символов латинского алфавита и знаков препинания (по 1 байту в UTF-8) и 30 символов кириллицы (по 2 байта в UTF-8). Найдите объём текста в UTF-8 в байтах.
Решение. Так как в UTF-8 разные символы могут занимать разное число байт, объём считаем отдельно для каждой группы символов:
Ответ: 110 байт. Обратите внимание: тот же текст из 80 символов в однобайтовой кодировке занял бы ровно 80 байт — в UTF-8 текст с кириллицей занимает больше места именно из-за символов, кодируемых двумя байтами.
Программная иллюстрация: анализ кодирования строки
В языке Python строки по умолчанию хранятся как последовательности символов Юникода, а метод encode() позволяет получить их представление в конкретной кодировке в виде байтовой строки. Рассмотрим программу, которая для заданного текста определяет число символов, размер в UTF-8 и то, укладывается ли текст в диапазон ASCII.
def text_info(text):
"""Возвращает число символов, размер в UTF-8 (байт) и признак ASCII-текста."""
chars = len(text)
utf8_bytes = len(text.encode('utf-8'))
ascii_only = all(ord(ch) < 128 for ch in text)
return chars, utf8_bytes, ascii_only
s = "Привет, Python!"
chars, size, ascii_only = text_info(s)
print(f"Символов: {chars}")
print(f"Размер в UTF-8: {size} байт")
print(f"Только ASCII: {ascii_only}")
for ch in "A€Б":
code = ord(ch)
b = len(ch.encode('utf-8'))
print(f"{ch}: код U+{code:04X}, {b} байт(а) в UTF-8")
Функция ord() возвращает кодовую точку символа в Юникоде, а len(ch.encode('utf-8')) — количество байт, которое займёт этот символ именно в кодировке UTF-8: для латинской буквы «A» это 1 байт, для кириллической «Б» — 2 байта, а для знака евро «€» — 3 байта, что соответствует таблице диапазонов, приведённой выше.
Типичные ошибки
Частая ошибка — считать, что один символ в UTF-8 всегда занимает 1 байт (как в ASCII): это верно только для латиницы и базовых знаков, а кириллица и большинство других алфавитов занимают 2 и более байт. Вторая ошибка — путать количество символов в строке (len(text) в Python) с её размером в байтах после кодирования: эти величины совпадают только для чисто ASCII-текста. Третья ошибка — забывать, что при подсчёте информационного объёма текста через формулу V=I·K величина I должна соответствовать именно используемой кодировке, а не произвольно выбранному числу бит.
Краткий словарь терминов
Таблица кодировки — соответствие между символами алфавита и их числовыми (а значит, и двоичными) кодами.
ASCII — стандартная 7-битная (в расширенном варианте — 8-битная) таблица кодировки латиницы, цифр и служебных символов.
Unicode — универсальный стандарт кодирования, присваивающий уникальный номер практически каждому символу любого языка мира.
UTF-8 — кодировка Юникода с переменной длиной символа (от 1 до 4 байт), совместимая с ASCII для первых 128 символов.
Кодовая точка — уникальный числовой номер символа в стандарте Юникод.
Равномерное кодирование — способ кодирования, при котором все символы алфавита представлены кодами одинаковой длины (числа бит).
Заключение
Кодирование текста — практический пример применения алфавитного подхода к измерению информации: зная таблицу кодировки, можно точно определить информационный вес символа и, следовательно, объём любого текста. Однобайтовые кодировки просты, но ограничены и несовместимы друг с другом, тогда как Юникод и его кодировка UTF-8 решают проблему представления любых языков мира ценой переменной длины символа. В следующей теме мы перейдём от текстовой информации к графической и рассмотрим, как аналогичный принцип — измерение информационного веса элемента изображения — применяется для вычисления объёма растровых изображений.



