Здравствуй и хорошей, товарищ!
На связи Тюрин Роман, это канал Симпличные условия, где о сложном говорится просто. Это третья часть рассказа, поэтому я надеюсь, мой читающий друг, ты знаком с первыми двумя:
Часть 1 - шифр Морзе, код Бодо и Мюррея, понятие бита
Часть 2 - кодировка ASCII - как прочесть это слово и что это. Проблема национальных кодировок и причина появления крокозябр
Содержание:
Появление Unicode
Как кодируют в Unicode: UTF-8
Как шифруется один символ?
UTF-16 - а это тогда зачем?
Пара трюков на Python
Немного магии на Windows
К тебе, читатель
Видели ли вы, сколько существует китайских иероглифов? Из прошлой части вы, должно быть, помните, что для национальных символов выделено 128 мест в расширенном ASCII. Будь я жителем Китая или Индии, я бы не смог пользоваться компьютером: такого количества явно не хватило бы на все буквы алфавита.
Появление Unicode
Ну и чего? Придумали. Таблица, включающая в себя 144 697 символов, охватывающая 159 современных и исторических сценариев, а также эмодзи и небуквенные символы вроде математических операторов, псевдографики, знаков ударения и умляутов, стрелок и даже игральных карт и досок для игры в маджонг. Имя ей - таблица символов Unicode (читается как "Юникóд").
"Консорциум Юникода" (так и назвались) начал делать ее в 1991 году, спустя 2 года представив первый стандарт. Слово стандарт стало в народе просто называться версией: гораздо удобнее вместо ISO/IEC 10646-1 сказать, что вышла версия 1.1. В этой версии в таблице были представлены 34 168 символов.
В версии 5.1, вышедшей в 2008 году, добавили даже символы Фестского диска, плитки для игры в Маджонг и даже символы домино!
А в версии 6.0 ввели игральные карты, дорожные знаки, географические карты, алхимические знаки, эмотиконы и эмодзи. Да, существованию эмодзи мы обязаны именно таблице Юникода. Такое название у Юникода говорит о том, что данные символы universal - универсальные для всех устройств и стран: их можно использовать ВЕЗДЕ.
Кстати, если ты хочешь узнать, что такое эмотикон, то я скажу тебе: это пиктограмма, изображающая эмоцию. Если хочешь узнать, что такое пиктограмма, то это схематичное изображение , где по узнаваемым чертам можно понять, что изображено. К примеру, улыбка :-) Или возьми дорожный знак - тоже пиктограммы.
Сейчас, на момент 17 июля 2022 года действует версия 14.0 с 144 697 символами.
Возникает только вопрос: КАК с 256 символов доросли до такого впечатляющего разнообразия?
Как кодируют в Unicode: UTF-8
Я не зря выше каждый раз называю Unicode таблицей. Это именно таблица символов, каждая версия выпускается в электронном виде и в виде книги. У них даже есть ISBN (читается как "АйЭсБиЭн"). А вот уже кодирование символов описывает Unicode Transformation Format, действующий на основе 8-битной системы: UTF-8.
Записываются буквы Юникода, начиная с большой буквы U и знака плюс: U+0420. Я взял код русской буквы "Р". 0420 - это шестнадцатеричная система (в ней 16 символов: от 0 до 9 и от A до F, заменяющие 10-15). В привычных нам числах это - 1056. Сейчас еще более менее нормально, но на 10 000, 20 0000 уже как-то неудобно писать.
Мы с тобой этого не видим, но код выглядит так: U+000420. Первые два нуля отведены под плоскости: от 00 до 1F.
Консорциум разделил символы на несколько логичных (а может и нет) частей - плоскостей. Плоскость (plane на английском)- это диапазон чисел из 65536 (2 в 16 степени) позиций. Одна плоскость - 65 тысяч, две плоскости - это 130 тысяч и т.д. Всего их 17 и нумеруются они в шестнадцатеричной системе.
Плоскость 0 (Basic Multilingual Plane, BMP)- это все используемые сейчас языки: здесь и кириллица, и арабский, и математические операторы, знаки валют и т.п. Все символы этой плоскости имеют коды, которые начинаются с 00: U+000420, например. Для удобства, первые нули убирают. Делаем правило: если 4 числа - это нулевая плоскость. Первые 128 символов здесь взяты с ASCII.
Плоскость 1, дополнительная (Supplementary Multilingual Plane, SMP) - для исторических языков вроде "Критского линейного письма А" или древнеперсидского, эмотиконов, игральных карт, шахмат и эмодзи. У них спереди будет стоять 1. Например: U+10313 (этрусская буква Р - 𐌓, либо U+1F60A - 😊).
Плоскость 2 и плоскость 3 - китайские символы. Я не шучу. В нулевую вошли все языки мира, а в две - китайские иероглифы. Помнишь же, сколько символов в плоскости? Так вот первая - для используемых, вторая - для старых.
Плоскости с 4 по 13 вообще еще не используются, они для инопланетных языков. Плоскости 14-16 - тоже малопонятны: одна для специализированных символов, остальные две - для частного использования, если кто-то вдруг придумает свой язык и захочет на нем общаться.
Как шифруется один символ?
Теперь как же они зашифрованы. В прошлой кодировке на один знак уходило 8 бит. Это 1 байт. Теперь? А теперь вводится понятие "переменная длина". Существуют символы, которые кодируются одним 1 байтом, двумя, тремя, четырьмя. Чем дальше от начала позиция символа в таблице, тем больше байт уйдет на ее кодировку.
На символ английского алфавита будет приходиться один байт. На русский язык - два байта, на самаритянский - 3 байта. Поэтому чаще всего в интернете документацию пишут на английском языке.
Но вот задача: 11110100 10001111 10111111 10111111. Как понять: здесь по одному байту смотреть или по несколько? Давай я поведаю тебе об управляющих би́тах. С ASCII Unicode взял нерасширенный вариант кодировки: это управляющие символы, знаки и английские буквы. Всего 128. Они умещаются в 7 бит: от 0 (0000000) до 127(1111111). Последний 8 бит назовем управляющим.
Последний символ ASCII - 01111111 (число 127 - удаление). Если вместо нуля ты решишь написать 1, чтобы было 11111111 или 10000000, то создатели Юникода спросят тебя: "Слушай, дорогой, что ты делаешь?". Этот ноль в начале - управляющий бит. Если это ноль, значит, для кодирования используется один байт.
Следующий символ (128 по очереди) - 11000010 10000000. Все. После английского языка кончились символы, которые кодируются одним байтом. Начинаются те, что кодируются двумя. О том, что используется два байта говорит 110 вначале. Это - ведущие биты. Следующий байт будет начинаться с 10 - так становится понятно, что он идет за старшим.
Начало самаритянского алфавита - место, где начинает отводиться по 3 байта на символ: 11100000 10100000 10000000. А четыре байта - 11110100 10001111 10111111 10111111 - откидываем все ведущие символы: 100 001111 111111 111111 - это U+10FFFF - последний символ таблицы Юникода.
Систематизирую:
1 байт - ведущий бит 0
2 байта - ведущие биты 110, остальные - 10
3 байта - ведущие биты 1110, остальные - 10
4 байта - ведущие биты 11110, остальные - 10
UTF-16 - а это тогда зачем?
Для начала покажу таблицу.
Смысл в том, что все символы из нулевой плоскости будут кодироваться всего двумя байтами. Потому что вариантов - 2 в 16 степени - 65536. А для остальных плоскостей - добавляем еще два байта. Они здесь называются кодовой парой. И если порядок байтов стоит смотреть слева направо, то кодировка будет называться UTF-16BE (big endian). А если наоборот - справа налево - UTF-16LE (little endian). Смысл в том, куда уходит тяжелый конец - в начало или в конец кодовой пары. Я сделал табличку для пояснения.
Пара трюков на Python
Для тех, кто не программирует на этом языке, а просто читает мою статью - переходите к следующей части. Остальная аудитория - это информация для вас😊.
Для начала нужна сама таблица символов. Возьму для эксперимента греческую букву дельту - Δ.
Трюк 1. Просто нажимаете Copy, чтобы скопировать символ.
Трюк 2. В консоли или функции print вводите название символа через \N (Name):
"\N{Greek Capital Letter Delta}"
Трюк 3. Можно взять его 4 бита и отобразить через \u (unicode):
"\u0394"
Трюк 4. Также через указание байта:
"\U0000394"
Трюк 5. Функции ord и chr работают напрямую с таблицей UTF-8. ord - позволяет узнать десятичную версию числа, а chr - по десятичному номеру взять символ.
ord('\u0394') - это даст число 916
chr(916)
Трюк 6. Можно узнать HEX (шестнадцатеричное представление) байтов. Для дельты - это 11001110 10010100 в двоичной, CE 94 - в HEX. Байт обозначается '\b'.
'Δ'.encode('utf-8') - выведет b'\xce \x94'
Трюк 7. Есть библиотека unicodedata.
Немного магии на Windows
Если под рукой есть таблица символов, то можно побаловаться в Microsoft Word, введя номер символа (например, 0489), после чего нажать Alt + X (плюс не нужно). Таким образом будет срабатывать распознавание символов Юникода.
Также если не хочется искать в таблице нужный код, а на древнерусском "миллион" написать хочется, то в Windows есть "Таблица символов", которая через значок лупы быстро находится. Здесь будут символы только из нулевой плоскости:
К тебе, читатель
Спасибо, что дочитал эту историю до конца, читатель. Я тебе очень благодарен за это.
Многое про необычности построения символов и алгоритмы нормализации я включать не стал, чтобы не растягивать статью. Если хочешь, то благодаря тебе и твоим комментариям может появиться 4 часть. Также я не нашел, как применять символы Unicode в Whatsapp или Telegram. Возможно, это знаешь ты.
Подписывайся на канал, ставь лайк этой истории, делись ею в соцсетях, отправляй маме, папе, бабушке и дедушке, и всем друзьям. До встречи в следующей статье!