Как стать автором
Обновить

Суперсемейка против Unicode: Эластика и ее противник гибкий UTF-8

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров3.8K

Оперативная память (RAM)

Оперативная память состоит из большого набора ячеек. Одна ячейка это один бит. Бит – минимальная единица хранения информации в ячейки оперативной памяти. Бит имеет булевое значение, это означает, что бит может быть единицей (1) или нулем (0). 1 означает наличие тока, а 0 – его отсутствие.

Биты (ячейки оперативной памяти) объединяются в группы по 8 бит в каждой и таким образом образуют байты. Одна единица байта равна 8 бит. Процессор (RAM) не может обращаться к конкретному биту, поэтому биты объединяются в группы по 8 бит каждая, чтобы процессор мог к ним обращаться.

Байт – это минимальная ячейка адресации. Простыми словами: байт, это самая маленькая единица ячейки к которой процессор может обращаться, чтобы взять у нее информацию. Один байт состоит из 8 бит.

 Картинка: https://youtu.be/Wh22_O8jXVQ?si=5FH-OUzqto-wvMoN

Не смотря на то, что булевое значение (то есть 1 или 0) состоит из одного бита, в памяти он записан как один байт, потому что как упоминалось выше – байт это минимальная ячейка в которую CPU может что то записать (сохранить)

 Картинка: https://youtu.be/Wh22_O8jXVQ?si=5FH-OUzqto-wvMoN

В каждой байтовой ячейке самый правый бит называется “младшим битом”, а самый левый – “старшим битом”. У байтовых ячеек также есть адреса (их названия). По этим самым адресам собственно к ним и обращается CPU. Это называется “байтовая адресация”.

 Картинка: https://youtu.be/Wh22_O8jXVQ?si=5FH-OUzqto-wvMoN

Объединение нескольких байтов называется “машинное слово”. Машинное слово – это максимальное количество байтов, которые за раз может обработать CPU. В наше время машинное слово в компьютере состоит из 4-х байт (32 бит) или же из 8-и байт (64 бит). Количество байт в одном машинном слове компьютера определяет разрядность компьютера (Пример из жизни: это тот самый параметр который видим где написано 32x или 64x).

 Картинка: https://youtu.be/Wh22_O8jXVQ?si=5FH-OUzqto-wvMoN + мое дополнение
Картинка: https://youtu.be/Wh22_O8jXVQ?si=5FH-OUzqto-wvMoN + мое дополнение

<aside> ? Суммируем информацию:

Размер ячейки памяти в современных компьютерах составляет 8 бит, то есть 1 байт. Это связано с тем, что байт является наименьшей единицей информации в компьютере, и он используется для кодирования всех символов, чисел и команд.

Машинное слово – это наименьшая единица памяти, с которой может оперировать (выполнять действия над данными) процессор. Его размер определяется разрядностью процессора. В современных компьютерах используются процессоры с разрядностью 32 или 64 бита, поэтому размер машинного слова составляет 4 или 8 байтов соответственно.

Таким образом, количество байтов, которые за раз может обработать CPU, определяется разрядностью процессора.

Бит: минимальная единица хранения информации. Он может принимать два значения: 0 или 1
Байт: наименьшая единица данных к которым CPU может обращаться и обрабатывать их. Его еще называют “минимальной ячейкой адресации”.
Машинное слово: единица максимального количества байтов, которые CPU может обрабатывать. Оно представляет собой набор битов, которые обрабатываются процессором за один такт (за раз).

</aside>

Почему в большинстве компьютеров, 1 байт равен 8 бит?

На самом деле байт это просто набор битов, то есть цифра 8 (количество битов в одном байте) это не какое то волшебное число. Другими словами, один байт мог бы содержать в себе сколько угодно бит.

Дело в том что наибольшее развитие компьютерных технологий происходило в Америке, и именно там появлялись первые стандарты кодирования символов.

Кодировки символов – это такие таблицы в которых указан цифровой код (бинарное название), Alt-code (если зажать клавишу Alt и ввести цифры которые указаны в этой кодировке, то мы выведем символ под которым он закодирован. На пример если нажать Alt + 65 на Numpad-е, то мы выведем букву “А” в верхнем регистре) и т.д.

Таблица ASCII-8 (без цифрового кода)

Идея была в том, чтобы один символ мог помещаться в одну ячейку памяти, то есть в один байт. При создании системы кодировки символов, практически не учитывались потребности в символах других языков, поэтому в одной из первых версий кодировки ASCII было всего 64 символа, которые умещались всего в 6 бит. Таким образом на тот период размер одного байта составлял 6 бит.

Спустя время (в 1967 году) вышла версия ASCII, которая уже состояла из 7 битов и 128 символов, а спустя еще какое то время (в 1981 году) уже из 8 битов, но по прежнему все также из 128 символов.

Причиной расширение размера таблицы ASCII было следующее:

  • Появились потребности в новых символах

  • При отправке текста на кодировке ASCII 7, могли происходить искажения символов.

Основные изменения между кодировкой ASCII 7 и ASCII 8:

  • Некоторые символы били убраны и заменены на Американские буквы в нижнем регистре

  • Не смотря на то что кодировка ASCII стала 8 битной, она по прежнему содержит в себе 128 символов. Вместо добавления дополнительных символов при помощи добавленного 8-го бита, данный 8-ой бит решили использовать в качестве “проверочного бита”: Он заменял собою другой бит, если тот в свою очередь подвергался искажению при отправке.

Почему не сделать размер одного байта больше 8-и бит?

Размер одного байта мог бы также состоять из любого количества битов, к примеру даже 30 бит. Но в таком случае если бы один байт состоял из 30 битов, при том что для кодировки основных символов, таких как знаки пунктуации, буквы латинского и кириллического алфавита, цифр и т.д. достаточно 8 бит на одну единицу байта, это было пустой тратой памяти компьютера т.к. оставшиеся ячейки байта бы просто не использовались бы. Таким образом у процессора бы уходило больше времени на обработку информации, что было бы не эффективно.

Стандартные кодировки символов в индустрии

Это кодировки были разработаны организацией Unicode. В данных кодировках 1 байт равен 8-и битам. На данный момент существует 3 основных стандарта кондировки символов:

  • Кодировка UTF-8: он состоит из одного байта (то есть 8 бит), но не всегда. У UTF-8 есть свои нюансы, о них мы поговорим ниже. Это достаточно глубокая тема, поэтому по желанию ее можно рассмотреть позже, пока что помнив лишь то, что по умолчанию данная кодировка состоит из одного байта и вмещает в себя до 256 символов.

  • Кодировка UTF-16: он состоит из двух байтов (то есть 16 бит). Это означает что один символ весит 16 бит. В данную кодировку вмещается 2 ^ 16 = 65536 различных символов.

  • Кодировка UTF-32: он состоит из четырех байт (то есть 32 бит). Это означает что один символ весит 32 бит. В данную кодировку вмещается 2 ^ 32 = 4 294 967 296 различных символов.

Теперь поговорим про нюанс / особенность кодировки UTF-8

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

Другими словами: UTF-8 – это кодировка, которая использует переменное количество байтов для кодирования одного символа. Она может кодировать один символ от 1 до 6 байтами.

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

Пример: Представим, что у нас есть два мессенджера: один поддерживает только кодировку ASCII-8, а другой поддерживает только UTF-8. В обоих мессенджерах мы можем написать слово “Hello” т.к. обе кодировки поддерживают буквы (“H”, ”e” , “l”, “o”) в данном слове. Но, мы не сможем написать слово “Hello表” в мессенджере, который использует ASCII-8, потому что в этой кодировке нет данного “表” символа (иероглифа), однако, мы бы смогли написать “Hello表” в мессенджере, который использует кодировку UTF-8 т.к. эта кодировка является переменной (гибкой) кодировкой, то она вывела бы слово “Hello” используя для каждого его символа один байт, а для символа “表” – три байта. То есть кодировка UTF-8 может подстраиваться под тот или иной символ расширяя или уменьшая свое кол-во байт отдельно для каждого символа. Ниже рассмотрим как это происходит.

Каким образом UTF-8 изменяет кол-во байт на символ?

UTF-8 (Unicode transformation format)

Кодировка UTF-8 (Unicode transformation format) это один из типов кодирования организации Юникод. Причина, по которой эта кодировка называется UTF-8, заключается в том, что он обрабатывает 8 бит (то есть 1 байт) (а если UTF-16, то это уже соответственно 16-битная операция). Символы в этой кодировке могут храниться от 1 до 4 байт (в теории, возможно и до 6 байт, но в данной статье мы рассмотрим только до 4-ех) в зависимости от того как был закодирован символ. К примеру, латинские буквы и цифры в UTF-8 закодированы под один байт, в то время как китайские иероглифы – под два байта.

1-байтовая кодировка в UTF-8

Для символов до 128, достаточно 1 байта. Это мы можем вычислить если возведем 2 в степени количество бит. Вот формула: 2 ^ кол-во бит. В данной ситуации это 2 ^ 8. Напоминаем, что 8 бит = 1 байт.

Итак, а как нам узнать, находится ли символ в пределах 1 байта или же в пределах 2-4 байт? — Ответ: нам нужно посмотреть на наличие нуля (“0”) в начале байта символа. Для этого нам нужно знать как он закодирован в двоичном коде. Далее объясню на примере, чтобы было проще.

Пример:

Картинка: https://www.attheminute.com/article/character-encodings-what-is-ascii-unicode-and-utf-8

Представим, что выше я привел пример двоичного кода буквы “А”. Чтобы понять сколько байт занимает ее символ, нам достаточно посмотреть на самый старший ее бит (это тот что левее всех в байте). Как мы видим, он начинается с “0”. Это означает, что в символ “А” занимает 1 байт памяти, то есть 8 бит. Проще говоря, если двоичный код символа начинается с “0”, это значит, что символ занимает 1 байт. Если это было бы 2, 3, или 4 байтовые операции, то они не начинались бы с “0”. Кстати, вот двоичная кодировка символа “А”: 01000001.

2-байтовая кодировка в UTF-8

В символах занимающие 2 байта памяти, первый байт (8 бит) всегда начинается с цифры “110”, а следующие после него байты начинаются с “10”. Итого остается 11 доступных бит. Это означает что в 2 байта кодировки UTF-8 умещается 2 ^ 11 = 2 048 символов.

Чтобы лучше понять систему, можно представить 110 и 10 как метафору: что 110 это “пароль”, который обозначает начало двухбайтовой кодировки, а 10 идущий сразу после, это как “крючок”, который показывает что эти два байта связанные. Кстати, эти ячейки указанные “x”, это уже просто ячейки с набором цифр “1” и “0” для кодировки символа.

Картинка: https://www.attheminute.com/article/character-encodings-what-is-ascii-unicode-and-utf-8

3-байтовая кодировка в UTF-8

Тут аналогично, как и в двух байтовой кодировке, в символах занимающие 3 байта памяти, первый байт (8 бит) всегда начинается с цифры “1110”, а следующие после него байты начинаются с “10”. Итого остается 16 доступных бит. Это означает что в 3 байта кодировки UTF-8 умещается 2 ^ 16 = 65 536 символов.

Картинка: https://www.attheminute.com/article/character-encodings-what-is-ascii-unicode-and-utf-8

4-байтовая кодировка в UTF-8

Здесь, все также продолжаем добавлять “1" к началу приведенного выше примера. Ниже привел представление UTF-8 в таблице по байтам:

Зачем использовать UTF-16 если 3-х байтный UTF-8 вмещает одинаковое кол-во символов?

Мировым стандартом сейчас является кодировка UTF-8, не смотря на это есть ситуации, когда бывает эффективнее использовать UTF-16 и в редких случаях UTF-32. Но если обратить внимание на кол-во символов вмещающихся в UTF-16 и 3-х битный UTF-8, то можно заметить, что в них обоих одинаково вмещается 65536 символов, с чего собственно появляется вопрос:

“А зачем тогда использовать UTF-16, если трех байтный UTF-8 может содержать одинаковое кол-во символов?”.

Дело в том, что между ними есть маленькая разница. Разница в том, что UTF-16 состоит из 2-х байт, а трех байтный UTF-8 из 3-х байт. Если взять в пример китайские символы (иероглифы), то если вы зачастую печатаете именно на них, то вам будет экономнее использовать кодировку UTF-16 вместо трех битной кодировки UTF-8.

Комментарии автора

Друзья, надеюсь данная статья была для вас полезной, на сбор информации и написание статьи в общей сложности ушло 3 дня. За этот период я узнал уймо нового о кодировках, а в особенности об UTF-8. Изначально данный текст являлся моим конспектом на данную тему, но я решил, что стоит поделится им открытом доступе т.к. лично на русских источниках мне было сложно найти годную информацию на эту тему. Спасибо Хабру за предоставления своей платформы и просто за то что он есть, часто его читаю!

Вспомогательные источники

Информация

Unicode vs ASCII: What's the difference and where does UTF-8 fit in?
Is ASCII code in matter of fact 7 bit or 8 bit?
ENG Wikipedia: UTF-8
RU Wikipedia: UTF-8

Изображения

Иконки
• Под каждым изображением указана ссылка на ее источник. Изображения ссылки на которых не были указаны означают, что их автором являюсь я. Если вдруг решите использовать, то, пожалуйста, упомяните меня :)

Теги:
Хабы:
Всего голосов 6: ↑3 и ↓3+2
Комментарии13

Публикации

Ближайшие события