Как компьютер кодирует буквы, числа и картинки: биты, байты, RGB

Информатикаобновлено 07.10.202610 мин чтенияесть тренажёр

Кодирование информации — это запись букв, чисел, картинок и звуков с помощью условных знаков; компьютер для этого использует только нули и единицы. Один такой знак — бит, а 8 бит составляют байт. Ниже — как закодировать текст через ord и chr, числа в двоичной системе и цвет пикселя RGB, с примерами на Python.

Загружаем…

Что такое кодирование информации

Кодирование информации — это перевод сообщения из одной формы записи в другую по заранее известному правилу. Азбука Морзе, ноты, номер телефона, штрихкод на упаковке — всё это коды.

Главное в любом коде — правило, известное и тому, кто записывает, и тому, кто читает. Если правило неизвестно, прочитать сообщение не получится: оно превращается в бессмысленный набор знаков. Компьютер устроен так, что внутри него есть только два состояния: есть сигнал или нет. Поэтому всё, что он хранит, приходится записывать двумя символами — 0 и 1. Буква, число, цвет точки на экране — для процессора это одинаковые цепочки нулей и единиц, а смысл им придаёт программа, которая знает правило. Информатик Джаннет Уинг (Wing) называет такой переход от реальной вещи к её модели абстракцией и считает его частью вычислительного мышления[3].

По федеральной образовательной программе основного общего образования двоичную систему и перевод целых чисел от 0 до 1024 изучают в 8 классе информатики[1]. Тема кодирования информации в ФОП опирается на это: сначала понимаем, как записать число нулями и единицами, а потом — как свести к числам всё остальное.

Бит и байт: единицы измерения

Бит — это одна двоичная цифра, 0 или 1, наименьшая единица информации, к которой сводится любое кодирование в компьютере. Байт — это 8 бит подряд; одним байтом можно записать 256 разных значений, от 0 до 255.

Почему 256? Каждый бит удваивает число вариантов: один бит даёт 2 варианта, два бита — 4, три — 8, а восемь — 2⁸ = 256. В школьной информатике более крупные единицы считают через 1024, то есть через 2¹⁰. Путать это с 1000 не стоит, иначе ответ в задаче разойдётся с правильным.

ЕдиницаСколько содержитЧто примерно помещается
1 бит0 или 1Ответ «да» или «нет»
1 байт8 битОдна латинская буква в кодировке ASCII
1 Кбайт1024 байтаСтраничка короткого текста латиницей
1 Мбайт1024 КбайтНебольшая фотография в сжатом виде
1 Гбайт1024 МбайтФильм в среднем качестве

Последние две строки таблицы — ориентир, а не точное правило: размер фотографии и фильма сильно зависит от качества и сжатия. В задачах по информатике переводят единицы строго: из бит в байты делят на 8, из байт в килобайты — на 1024.

Сколько бит нужно на один символ

Если в алфавите N символов, на каждый символ нужно i бит, где 2^i не меньше N. Для алфавита из 32 букв хватает 5 бит, потому что 2⁵ = 32.

Это правило — основа задач на информационный объём, и кодирование информации в учебниках по ФОП начинается именно с него. Представьте, что вы кодируете своим кодом алфавит из 6 символов. Двух бит мало: они дают только 4 комбинации (00, 01, 10, 11). Трёх бит хватает с запасом: 8 комбинаций, две останутся лишними. Значит, на символ уйдёт 3 бита: меньше нельзя, иначе двум символам достанется одинаковый код.

Символов в алфавитеБит на символКомбинаций
212
от 5 до 838
от 17 до 32532
от 129 до 2568256

Объём всего сообщения равен числу символов, умноженному на бит на символ: I = K · i. Текст из 100 символов алфавита в 32 буквы занимает 100 · 5 = 500 бит, это 62,5 байта.

Кодирование текста: функции ord и chr

Чтобы закодировать текст, каждому символу присваивают номер — код. В Python функция ord() возвращает код символа, а chr() по коду возвращает символ.

for bukva in "Кот":
    print(bukva, ord(bukva))
print(chr(65), chr(97))
К 1050
о 1086
т 1090
A a

У заглавной латинской A код 65, у строчной a — 97, у русской К — 1050. Именно поэтому при сравнении строк заглавные буквы оказываются «меньше» строчных: Python сравнивает коды. В редакторе на этой странице есть программа, которая выводит коды букв слова и их двоичную запись. Нажмите «▶ Запустить», затем замените слово на своё имя и посмотрите, как меняются числа. Если хотите узнать, как буквы превращаются в строки и обратно, загляните в статью о строках в Python.

ASCII, Юникод и UTF-8

Кодировка — это таблица, где каждому символу сопоставлен номер. Первые 128 номеров совпадают в ASCII и в Юникоде: это латинские буквы, цифры и знаки препинания.

Кодировки ASCII хватало только для английского текста. Для других алфавитов придумывали собственные кодировки, и одна и та же последовательность байт в разных таблицах означала разные буквы — отсюда знакомые всем «кракозябры». Юникод решил проблему: в нём у каждого символа любого языка, включая эмодзи, свой номер. Строки в Python 3 хранят именно символы Юникода, так сказано в официальной документации Python[2]. Руководство PEP 8 от Python Software Foundation рекомендует сохранять сами файлы с программами в UTF-8.

Но номер символа — ещё не байты на диске. Способ закодировать номер байтами называется UTF-8. В нём латинская буква занимает 1 байт, русская — 2 байта. Это легко проверить в Python, установленном на компьютере:

print(len("cat".encode("utf-8")))
print(len("кот".encode("utf-8")))
3
6

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

Как записываются числа

Целые числа компьютер хранит в двоичной системе: каждый разряд — степень двойки. Число 13 записывается как 1101, потому что 13 = 8 + 4 + 1.

print(bin(13))
print(int("1101", 2))
print(bin(255), hex(255))
0b1101
13
0b11111111 0xff

Приставка 0b в Python означает «дальше двоичная запись», 0x — шестнадцатеричная. Число 255 — это восемь единиц, то есть самое большое значение одного байта. Подробно перевод туда и обратно, с упражнениями, разобран в статье о двоичной системе счисления. Кодирование информации о дробных числах устроено сложнее, и именно поэтому в Python 0.1 + 0.2 не равно точно 0,3: дробь 0,1 в двоичной системе бесконечная, и компьютер хранит её приближённо.

Кодирование информации о цвете: пиксели и RGB

Картинку на экране делят на маленькие точки — пиксели, и для каждой записывают цвет числом. В модели RGB цвет задают три числа от 0 до 255: сколько красного, зелёного и синего.

Три канала по 8 бит дают 24 бита на пиксель и 2²⁴ = 16 777 216 возможных цветов. Чистый красный — (255, 0, 0), белый — (255, 255, 255), чёрный — (0, 0, 0). Если цветов меньше, бит нужно меньше: для чёрно-белой картинки без оттенков достаточно 1 бита на пиксель, для палитры из 256 цветов — 8 бит.

shirina, vysota = 640, 480
bit_na_piksel = 24
bity = shirina * vysota * bit_na_piksel
print(bity // 8, "байт")
print(bity // 8 // 1024, "Кбайт")
921600 байт
900 Кбайт

Картинка 640 на 480 точек с 24-битным цветом без сжатия занимает 900 Кбайт. Форматы вроде JPEG и PNG уменьшают этот размер, но это уже сжатие — отдельная тема. Цвет в модуле turtle тоже можно задать тройкой RGB, так что тему легко потрогать руками на уроке черепашьей графики.

Задачи на кодирование информации и её объём

Чтобы решить задачу на объём, нужны 3 числа: сколько символов или пикселей, сколько бит на каждый и в каких единицах просят ответ.

  1. Найдите i. Если дан алфавит или число цветов, подберите наименьшую степень двойки, которая не меньше этого числа.
  2. Найдите K. Число символов в тексте или пикселей в картинке (ширина на высоту).
  3. Перемножьте. I = K · i, ответ получится в битах.
  4. Переведите единицы. Делите на 8, затем на 1024 столько раз, сколько нужно.

Пример: текст из 2048 символов, на каждый отводится 16 бит. Объём: 2048 · 16 = 32 768 бит = 4096 байт = 4 Кбайт. Удобно раскладывать числа на степени двойки: 2048 = 2¹¹, 16 = 2⁴, произведение — 2¹⁵ бит, а это 2¹² байт, то есть 4 Кбайт. Такие вычисления проще проверить в редакторе Python, чем на калькуляторе. Сдавать ответ стоит только после того, как вы сверили единицы измерения с вопросом.

«Кодирование и шифрование — одно и то же». Это не подтверждается: такое правило открыто всем, его цель — записать информацию, а шифр нужен, чтобы её скрыть от посторонних.

«Внутри компьютера где-то хранятся настоящие буквы и картинки». Это миф: в памяти лежат только числа в двоичной записи, а буквой или цветом они становятся, когда программа применяет к ним таблицу символов.

Когда считать биты вручную не нужно

Подсчёт бит вручную не нужен в повседневной работе с файлами: программы сами выбирают формат записи. Вот 4 случая, когда формулы только отвлекают.

  • Сохранение текста в редакторе. Современные редакторы обычно сами пишут файл в UTF-8, где буква занимает 1–4 байта.
  • Размер готовой фотографии. Файл уже сжат, и формула «ширина × высота × 24» даст число в несколько раз больше настоящего.
  • Обычная программа на Python. Целые числа в Python не ограничены 8 или 32 битами, переполнения как в учебных задачах не будет.
  • Ребёнку 7–8 лет. Двоичные коды ему проще показать игрой с карточками, чем формулами.

Чего делать нельзя

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

  • Нельзя переводить килобайты через 1000, если в школьной задаче не сказано иначе: используют 1024.
  • Не следует округлять число бит на символ вниз: для 33 символов 5 бит мало, нужно 6.
  • Не стоит забывать про пробелы и знаки препинания — они тоже символы и занимают место.
  • Не стоит считать, что русская буква всегда занимает 1 байт: в UTF-8 это 2 байта.
  • Не допускается передавать chr() отрицательное число — Python выдаст ValueError.

Чтобы понять, где хранятся все эти байты, полезно прочитать, как устроен компьютер изнутри: память, процессор и устройства ввода-вывода.

Источники

[1] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования».

[2] The Python Tutorial (официальная документация Python 3). Python Software Foundation.

[3] Wing J. M. Computational thinking // Communications of the ACM. 2006. Vol. 49, № 3. P. 33–35.

Вопросы и ответы

Почему компьютер использует именно 0 и 1?

Два состояния легко надёжно различить: есть ток или нет, намагничено или нет. С десятью уровнями сигнала ошибок было бы гораздо больше.

Сколько бит в одном байте?

Восемь. Байт может хранить любое целое значение от 0 до 255.

Как узнать код любого символа?

Запустите в Python print(ord('ж')) — получите 1078. Для обратного превращения есть chr.

Что такое шестнадцатеричный цвет вроде #FF0000?

Это те же три числа RGB, записанные в шестнадцатеричной системе: FF — 255 красного, 00 — ноль зелёного и синего. Получается чистый красный.

Как кодируется звук?

Громкость измеряют много раз в секунду и записывают каждое измерение числом. Чем чаще измерения и чем больше бит на каждое, тем точнее звук и тем больше файл.

Зачем школьнику эта тема, если всё делает компьютер?

Она объясняет, почему файлы имеют такой размер, почему появляются «кракозябры» и почему дроби считаются неточно. Без этого не получится понять многие ошибки в собственных программах.