Наборы символов, кодировки и кракозябры

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

Наборы символов, кодировки и кракозябры

Текст состоит из символов, поэтому для представления текста в компьютере, то есть его кодирования с помощью двоичных цифр 0 и 1, нужно уметь кодировать символы. Существуют различные способы кодирования символов, наиболее популярным из которых сейчас является стандарт Юникод (Unicode). Юникод включает в себя знаки практически всех языков мира. Первая версия стандарта Юникод была принята в 1991 году, а в 2020 году была принята его 13-я версия. Основные отличия версий состоят в том, что в них появляются новые письменности и новые символы. В первой версии было 24 письменности и 7161 символ, а в 13-й версии — 154 письменности и 143 859 символов.

Прообразами современных методов кодирования являются азбука Морзе (1838 год), в которой символы кодируются с помощью точек и тире, а также шрифт Брайля (1824 год), в котором символы кодируются с помощью 6 или 8 точек.

ASCII

В 1963 году в США была разработана и утверждена таблица ASCII (American Standard Code for Information Interchange, американский стандартный код для обмена информацией). В английском языке 26 букв, таким образом, для представления больших и маленьких букв, цифр, знаков арифметических операций и знаков препинания достаточно около 100 символов. Поэтому сначала для представления одного символа отводилось 7 бит. Этого достаточно для представления 128 символов с кодами от 0 до 127. Каждому символу сопоставляется некоторый код, в результате чего получается таблица, которая называется набором символов (character set или charset). В качестве синонима часто используется термин кодировка (encoding) и кодовая страница (code page), хотя этот термин правильнее использовать только для однобайтных кодировок.

Для передачи и хранения информации в основном используются группировки бит по 8 (8 бит составляют один байт). В коде ASCII 8-й бит использовался как вспомогательный для контроля ошибок (бит чётности), которые могли возникнуть при передаче или хранении информации.

Бит чётности выставляется в 0 или 1 так, чтобы общее число единичных бит было чётным. Например, код буквы A — 65 или 1000001. Тогда бит чётности будет равен 0 и 8-битный код будет 01000001. Код символа пробел имеет значение 32 или 0100000. Тогда бит чётности будет равен 1 и 8-битный код пробела будет 10100000.

С распространением компьютеров появилась необходимость в расширении количества символов. Было предложено множество различных решений. Так, например, вместо строчных английских букв добавлялись символы национальных языков. Однако в русском языке 33 буквы, поэтому исключали букву Ё, а схожие по начертанию буквы заменялись английскими: А, В, Е, К, М, Н, О, Р, С, Т, Х. Другой способ состоял в использовании специальных управляющих символов SO и SI (Shift Out и Shift In) с кодами 14 и 15 для переключения языка. Однако удобнее оказалось решение с отказом от бита чётности и использование 8 бит для кодирования 256 символов с кодами от 0 до 255. При этом первая половина таблицы ASCII с кодами от 0 до 127 была всегда одинаковой и использовалась для кодирования управляющих символов, арифметических знаков, знаков препинания, цифр и букв английского алфавита.

Управляющих символов в таблице ASCII всего 33: это символы с кодами от 0 до 31 и символ с кодом 127. У управляющих символов нет визуального изображения. В первоначальной версии таблицы ASCII от 1963 года управляющих символов было 29, а в версии 1967 года добавили еще 4 символа. Многие из управляющих символов уже утратили своё значение и стандарт POSIX требует, чтобы только 8 из них поддерживались. Вот эти символы:

  • символ NULL с кодом 0 - пустой символ. В некоторых языках программирования этот символ используется для обозначения конца строки;
  • символ BEL с кодом 7 издаёт звуковой сигнал;
  • cимвол BS (BackSpace) с кодом 8 — удаление предыдущего символа;
  • символ TAB с кодом 9 — горизонтальная табуляция, используется для выравнивания текста. Обычно этим символом задаётся красная строка;
  • символ LF (Line Feed, перевод строки) с кодом 10 — переход на строку вниз;
  • символ VT (Vertical Tab) с кодом 11 — вертикальная табуляция;
  • символ FF (Form Feed) с кодом 12 — переход на новую страницу;
  • символ CR (Carriage Return, возврат каретки) с кодом 13 — переход на начало строки.

Конец строки в разных операционных системах может кодироваться по-разному. Например, в операционных системах семейства UNIX это символ LF, а в операционных системах семейства Windows и MS DOS — это два символа: CR LF.

Наконец, самый загадочный управляющий символ с кодом 127, про который часто забывают, — это символ DEL, удаляющий текущий символ.

Коды в диапазоне от 32 до 47 используются для вспомогательных символов, скобок, знаков арифметических операций. Самый часто встречающийся символ в текстах — пробел — имеет код 32.

Для цифр отведён диапазон от 48 до 57. Чтобы получить значение цифры, из её кода нужно вычесть 48 (110000 в двоичной системе).

Заглавные английские буквы начинаются с кода 65 (коды буквы A), а строчные — с кода 97 (код буквы а).

Вторая часть таблицы получила название расширенной и использовалась для кодирования символов национальных языков. Так как единого стандарта на расширенную часть таблицы ASCII не было, то появились различные способы для кодирования символов национальных языков. Именно благодаря этому в русском языке появился термин кракозябра.

Для русского языка было предложено несколько кодовых таблиц:

  • CP866 (IBM Code Page 866, Альтернативная кодировка ГОСТ) — реализована в операционных системах MS-DOS, начиная с версии 4.01, также частично используется в Windows;
  • CP1251 (Windows-1251) — используется в системах Windows (кроме подсистемы MS-DOS);
  • KOI8-R (КОИ-8, Код Обмена Информацией) — использовался в операционных системах семейства UNIX;
  • MacCyrillic — использовалась на компьютерах Macintosh.

Если русский текст, подготовленный в одной кодировке, попытаться прочитать в другой, то получатся "кракозябры". Например:

КОДИРОВКА (CP1251) соответствует ╩╬─╚╨╬┬╩└ (CP866);

Вопрос (KOI8-R) соответствует бНОПНЯ (CP1251).

Чтобы прочитать такой текст, его нужно перекодировать из одной кодировки в другую. С развитием сети Интернет проблема с различными кодировками стала очень ощутимой. Также требовалось добавление новых символов. Таблица ASCII содержит всего 256 различных символов, поэтому требовалось новое решение.

Unicode

Стандарт Unicode (Юникод или Уникод) был предложен в 1991 году. Основная идея стандарта в увеличении количества кодируемых символов за счёт увеличения кодового пространства. Вместо одного байта в стандарте Юникод символы могут занимать 2 и более байт. Символы с кодами от 0 до 127 соответствуют символам набора ASCII. Стандарт продолжает развиваться, и в его новые версии добавляются новые символы и письменности. Например, в 10-й версии (2017 год) был добавлен символ биткойна ₿, добавлено много символов эмодзи. В первой версии было 24 письменности и 7 161 символ, а в последней 13-й версии (2020 год) — 154 письменности и 143 859 символов.

Для практического использования было создано несколько семейств кодировок (Unicode transformation format, UTF): UTF-8, UTF-16, UTF-32.

Очень популярной является кодировка UTF-8, которая обеспечивает совместимость с 7-битной системой ASCII: символы ASCII с кодами от 0 до 127 в формате UTF-8 остаются без изменений и также занимают один байт. Остальные символы Юникода кодируются последовательностями длиной от 2 до 4 байт. Таким образом, код UTF-8 является неравномерным.

Кодировка UTF-16 каждому символу сопоставляет последовательность двухбайтовых (то есть 16-битных) слов. Обычно используется 2 или 4 байта для одного символа.

Кодировка UTF-32 каждому символу сопоставляет код длиной 4 байта (то есть 32-бита). Этот код является равномерным.

В кодировках UTF-16 и UTF-32 можно указывать порядок следования байт: младший байт может записываться перед старшим (little-endian, UTF-16LE, UTF-32LE), либо после старшего (big-endian, UTF-16BE, UTF-32BE).

Для самоконтроля.
Латинская буква A в таблице ASCII имеет код 65 или в двоичном виде 01000001.
В кодировке UTF-8 она будет кодироваться точно также.
В кодировке UTF-16BE код будет состоять из двух байт 00000000 01000001 или 0 65, а в кодировке UTF-16LE — 01000001 00000000 или 65 0.
В кодировке UTF-32BE код будет состоять из четырёх байт 00000000 00000000 00000000 01000001 или 0 0 0 65, а в кодировке UTF-32LE — 01000001 00000000 00000000 00000000 или 65 0 0 0.

Для указания, какая кодировка используется, в начале текстового файла может передаваться маркер последовательности байтов BOM (byte order mark) длиной от 2 до 4 байт, который может иметь следующие значения:

  • UTF-8 EF BB BF
  • UTF-16BE FE FF
  • UTF-16LE FF FE
  • UTF-32BE 00 00 FE FF
  • UTF-32LE FF FE 00 00

Если вы внимательно прочитали статью, то вам не составит труда пройти тест из 10 вопросов на портале Эрудит.Онлайн «Кодирование символьной информации».

Конкурс «Кодирование символьной информации».
Конкурс «Кодирование символьной информации».
Конкурс «Кодирование символьной информации».

Другие интересные статьи на нашем канале:

#информатика #компьютер #вычислительная техника #коды #кодировка #информационные технологии