Содержание

Стандарт кодирования unicode отводит под каждый символ. Что такое юникод

Юникод — это система кодирования, которая присваивает уникальный код любому символу, независимо от платформы, независимо от программы, независимо от языка.

На самом деле, даже в самом названии этой заметки есть некоторая неточность — или, вернее, противоречие. Дело в том, что до сих пор нет единодушия в том, как правильно писать английское слово Unicode русскими буквами — юникод или уникод. Мы с вами сейчас воспользуемся первым вариантом написания.

Иногда, когда вы открываете документы или просматриваете страницы вместо польских букв, есть несколько «кустов». Эти ошибки могут быть вызваны неправильной кодировкой символов. Текст, который вы видите на экране, компьютер хранится в виде нулей и единиц, которые упакованы в восемь частей. Один нуль или один бит; Группа из восьми — это байт. Электронные устройства хранят информацию в байтах, включая текст.

Хорошо, но как же все эти кусочки компьютера могут составить историю? Десять будет выглядеть так: таким образом, чтобы писать числа, мы называем двоичными, мы научились использовать десятичные числа. Это делается так, что каждому персонажу присваивается номер. Предложение «Алла имеет кошку» представляет собой набор чисел.

Юникод — это не просто многобайтовая кодировка для представления множества символов, как многие думают, хотя и такое определение в определённом приближении можно считать верным. Официально же определение такое: юникод — это система кодирования, которая присваивает уникальный код любому символу, независимо от платформы, независимо от программы, независимо от языка.

Обратите внимание, что прописные и строчные буквы являются отдельным символом для компьютера, а пустое пространство также является признаком, хотя и не видимым. Кроме того, отдельные цифры обрабатываются одинаково. Например, символу 1 не присваивается номер 1, только.

Нет, но где компьютер знает, какой символ назначен данному номеру? Ответ — кодировка символов. Вообще говоря, это таблица со всеми присвоенными им символами и номерами. Со временем этого количества уже недостаточно — компьютеры приобрели новые возможности и стали более популярными в других странах со специальными буквами.

Стандарт юникод разбит на две части. Первая — это набор чисел, соответствующих каждому символу каждого поддерживаемого алфавита. Она называется Universal Character Set, или просто UCS. Числа, используемые в пространстве кодов UCS, все целые и неотрицательные. Обозначаются эти числа — кодовые позиции — как U+0000, U+0001, U+0002 и т.д. При всём при этом пространство кодов не однородное, а разделено на несколько смысловых областей. Коды от U+0000 до U+007F — это ASCII-символы, за ними расположены знаки символы разных национальных алфавитов, знаки препинания и технические символы а-ля символа перевода каретки на новую строку. Вторая часть стандарта — это, собственно, кодировки, которые обеспечивают побитовое представление каждого кода в тексте.

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

Но даже введение кодовых страниц не решило всех проблем. Первая из них — совместимость стандартов. Хотя первые 127 символов одинаковы для всех стандартов, остальные символы упорядочены в соответствии с их собственным представлением. Угол слова, записанный в этом первом угле, будет открыт после того, как система будет открыта для второго стандарта.

Все символы в юникоде разделены на два типа — протяжённые и бесширинные (модифицирующие). Протяжённые символы — это обычные буквы, которыми набрана эта вот заметка. Модифицирующие — это надбуквенные знаки вроде ударений, точек, «шапочек» и т.д., и т.п. Большая часть букв, имеющие подобные знаки, для всех алфавитов представлены как последовательность протяжённого и модифицирующего символов. Правда, кириллические «ё» и «й» представлены как отдельные протяжённые символы.

Другая проблема заключается в том, что 256 символов по-прежнему недостаточно, чтобы свободно писать документы. В большинстве случаев этого достаточно, но возникают проблемы, когда вам нужно обратиться к г-ну Мёллеру, Пютцу или Страссману в его магистерскую диссертацию. Вставьте кириллицу или введите греческие буквы в сложную математическую формулу.

Необходим новый метод кодирования, который будет включать все возможные символы, используемые на всех языках мира. Это делает его менее распространенным для ошибок. Однако возникла еще одна проблема — так много возможных персонажей не позволяли писать 1 байт для них. Один байт состоит из восьми или нулей, что позволяет их организовать по-разному. Так много символов имеют кодовые страницы. Чтобы увеличить количество символов, поддерживаемых системой кодирования, вам необходимо увеличить количество байтов, необходимых для вставки буквы.

Самой распространённой практической реализацией юникода является UTF-8. Этот стандарт обеспечивает хорошую совместимость со старыми ASCII-текстами благодаря тому, что символы английского алфавита и другие общеупотребительные символы (т.е. символы, имеющие в ASCII коды от 0 до 127) записываются одним байтом. Остальные символы записываются большим количеством байт — от двух до шести.

В последнее время знак турецкой лиры был добавлен в символ Юникода. Число, присвоенное ему, равно 110 Если каждая буква должна была быть занята 3 байтами, даже те, которые были от начала, с одним — увеличивали бы пространство, необходимое для сохранения файла на диск.

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

Разрабатывается юникод и сопутствующие ему стандарты консорциумом Unicode Consortium. Как написано на официальном сайте этой организации www.unicode.org , «Unicode Consortium — это некоммерческая организация, основанная для разработки и развития стандарта Unicode, определяющего представление текстовой информации в современных программных продуктах и стандартах, и для содействия его широкому распространению и использованию. Членами Консорциума является большое количество корпораций и организаций, работающих в областях обработки информации и компьютерной индустрии. Финансовая поддержка Консорциума осуществляется исключительно за счёт членских взносов его участников. Членство в Unicode Consortium открыто для любых организаций или частных лиц, поддерживающих стандарт Unicode и желающих помогать его распространению и реализации». Присоединяйтесь! 🙂

Описание в этой статье основано на бета-версии 8, доступной только узкому кругу бета-тестеров. Поскольку бета-тестирование подходит к концу, очень вероятно, что большинство описанных функций и функций действительно появятся в окончательной версии. Мы расскажем о наиболее значительных изменениях и новостях в отношении текущей версии 51 в каждом из тематических блоков.

Работа с файлами и внешний вид приложения

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

Стандарт Unicode или ISO/IEC 10646 явился результатом сотрудничества Международной организации по стандартизации (ISO) с ведущими производителями компьютеров и программного обеспечения. Причины, изложенные на предыдущей странице, привели их к принципиально новой постановке вопроса: зачем тратить усилия на развитие отдельных кодовых таблиц, если можно создать единую таблицу для всех национальных языков? Такая задача кажется излишне амбициозной, но только на первый взгляд. Дело в том, что из 6700 живых языков официальными языками государств являются около полусотни, причем пользуются они примерно 25 различными письменностями: числа для нашего компьютерного века вполне обозримые.

Закладки будут отображаться только в том случае, если в окне по крайней мере два. При копировании больших объемов данных, которые сохраняются в течение длительного времени, в предыдущих выпусках возможно использование фоновых копий. Конечно, эта популярная функциональность была сохранена и принесла несколько новых выпусков в новой версии.

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

Предварительная прикидка показала, что для кодирования всех этих письменностей достаточно 16-битового диапазона, т. е. диапазона от 0000 до FFFF. Каждой письменности был выделен свой блок в этом диапазоне, который постепенно заполнялся кодами символов этой письменности. На сегодня кодирование всех живых официальных письменностей можно считать завершенным.

Теперь функция создания папок также может создавать структуру каталогов. Дополнительные улучшения при работе с файлами. Синхронизация каталогов содержит два больших улучшения. В основном модуле переименования были добавлены параметры сохранения настроек и средства создания файла визуального перезаписи.

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

Отработанная методика анализа и описания систем письма позволила консорциуму Unicode перейти в последнее время к кодированию остальных письменностей Земли, которые представляют какой-либо интерес: это письменности мертвых языков, выпавшие из современного обихода китайские иероглифы, искуственно созданные алфавиты и т. п. Для представления всего этого богатства 16-битового кодирования уже недостаточно, и сегодня Unicode использует 21-битовое пространство кодов (000000 — 10FFFF), которое разбито на 16 зон, названных плоскостями. Пока что в планах Unicode предусмотрено использование следующих плоскостей:

С вариантами, сделанными в более ранних версиях, первоначальное диалоговое окно конфигурации стало неясным. Новое диалоговое окно конфигурации разделено на более читаемые категории, и каждый раздел посвящен отдельной странице диалога. Вы найдете большинство параметров, известных из предыдущей версии, и множество новых опций.

Это кодировка символов мирового уровня. Подавляющее большинство специальных символов всех языков мира уже на месте. Заклинания «регулярных выражений» — многие люди боятся. Все, что он должен сделать, это посмотреть его официальное введение. Двухбайтовый символ представляет собой многоязычный двухбайтовый код символа. Большинство символов, используемых при использовании компьютеров по всему миру, включая технические символы и специальные символы, могут быть представлены как символы Юникода в виде двухбайтового символа.

    Плоскость 0 (коды 000000 — 00FFFF) — БМП, базовая многоязыковая плоскость (BMP, Basic Multilingual Plane), соответствует исходному диапазону Unicode.

    Плоскость 1 (коды 010000 — 01FFFF) — ДМП, дополнительная многоязыковая плоскость (SMP, Supplementary Multilingual Plane), предназначена для мертвых письменностей.

    Плоскость 2 (коды 020000 — 02FFFF) — ДИП, дополнительная иероглифическая плоскость (SIP, Supplementary Ideographic Plane), предназначена для иероглифов, не попавших в БМП.

    Поскольку каждый двухбайтовый символ представлен в фиксированном 16-битном размере, ширина символа упрощает программирование с использованием международных наборов символов. Как правило, ширина символов занимает больше места памяти, чем многобайтовые символы, но быстрее обрабатывается.

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

    Плоскость 14 (коды 0E0000 — 0EFFFF) — ДСП, дополнительная специальная плоскость (SSP, Supplementary Special-purpose Plane), предназначена для символов специального назначения.

    Плоскость 15 (коды 0F0000 — 0FFFFF) — плоскость частного пользования (Private-Use Plane), предназначена для символов искусственных письменностей.

    Плоскость 16 (коды 100000 — 10FFFF) — плоскость частного пользования (Private-Use Plane), предназначена для символов искусственных письменностей.

    Мы до сих пор избегали низкоуровневых данных о кодировании данных, но понимание немного о битах и ​​байтах поможет понять это. Это единственное значение, ограниченное двумя возможностями, которые мы условно записываем как 0 или компьютеры хранят биты как электрические заряды или магнитные полярности, или каким-то другим способом, который нам не нужно беспокоить. Последовательность из восьми 0-1 бит называется байтом.

    Существует много возможных кодировок. Один символ Юникода отображается в последовательность до четырех байтов. Вы можете сделать это одним из двух способов. Все будет работать нормально, пока вы не попытаетесь распечатать или записать содержимое в файл. Если вы печатаете, а окно терминала не настроено для отображения этого языка, вы можете поставить странный вывод.

Разбивка БМП на блоки приведена в WDH: Стандарт Unicode. Здесь отметим только, что первые 128 кодов (00000 — 0007F) соответствуют кодам ASCII и кодируют блок базовой латиницы. Подробно раскладка письменностей по диапазону Unicode будет описана в моей статье «Unicode и письменности мира». Поскольку нас в дальнейшем будут интересовать только символы БМП, я использую их 16-битовые коды вида XXXX (старшие биты равны нулю и не указываются).

Если вы попытаетесь записать файл, вы можете получить сообщение об ошибке. Это позволяет вам писать в одном документе, например, в цикле и польском алфавите. Это, безусловно, самый универсальный стандарт. Конечно, все они используют один и тот же массив, и у них одинаковые возможности, вся разница в другом способе написания. Самая большая переносимость — это ваши документы в Юникоде. Каждый парсер должен поддерживать его. У вас нет гарантий по одному стандарту.

Если вы используете это, вам не нужна информация о кодировке. Немного информации о программах, которые помогут вам кодировать и преобразовывать символы, можно найти в разделе «Инструменты». В этом учебном руководстве показаны только те шаги, которые вы должны выполнить, чтобы добавить шрифт, который имеет как строчные, так и заглавные буквы, диакритические знаки, характерные для румынского языка. Написание без диакритики может привести к неоднозначным выражениям, таким как «12-летний танк», «роман, рожденный в Риме».

Общее описание

В основе Unicode лежит понятие символа (character). Символ — это абстрактное понятие, которое существует в конкретной письменности и реализуется через свои изображения (графемы ). Это означает, что каждый символ задается уникальным кодом и принадлежит к конкретному блоку Unicode. Например, графема А есть и в английском, и в русском, и в греческом алфавитах. Однако, в Unicode ей соответствуют три разных символа «латинская прописная буква А» (код 0041), «кириллическая прописная буква А» (код 0410) и «греческая прописная буква АЛЬФА» (код 0391). Если мы теперь применим к этим символам преобразование в строчную букву, то соответсвенно получим «латинскую строчную букву А» (код 0061, графема a), «кириллическую строчную букву А» (код 0430, графема а) и «греческую строчную букву АЛЬФА» (код 03B1, графема α), т. е. разные графемы.

Диакритические знаки — это шляпа — для этого — огибающая, запятая и запятая — язык для румын. Он предназначен для любой буквы на любом языке, на любой аппаратной или программной платформе, чтобы соответствовать ее уникальному и недвусмысленному числу. Теперь он будет иметь форму и размер глифы.

Мы выберем графику запятой. Красный контур глифа означает, что он выбран. Для других букв с диакритическими знаками румынского языка сделаны те же самые адаптации. Откроется диалоговое окно «Информация о шрифте». Мы добавляем в поле Фамилия имя, какое имя мы хотим для шрифта.

Может возникнуть вопрос: что такое преобразование в строчную букву? Здесь мы подходим к самому интересному и важному моменту в стандарте. Дело в том, что Unicode — это не просто кодовая таблица. Концепция абстрактного символа позволила создателям Unicode построить базу данных символов, в которой каждый символ описывается своим уникальным кодом (ключом базы данных), полным названием и набором свойств. Например, символ с кодом 0410 описан в этой базе так:

0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430;

Расшифруем эту запись. Она означает, что код 0410 присвоен «кириллической прописной букве А» (полное название символа), которая имеет следующие свойства:

Общая категория строчная буква (Lu = Letter, uppercase)
Класс сочетаний 0
Направление вывода слева направо (L)
Декомпозиция символа нет
Десятичная цифра нет
Цифра нет
Числовое значение нет
Зеркальный символ отсутствует (N)
Полное название в Unicode 1.0 то же
Комментарий нет
Отображение в прописную букву нет
Отображение в строчную букву 0430
Отображение в титульную букву нет

Перечисленные свойства определены для каждого символа Unicode. Это позволило его разработчикам создать стандартные алгоритмы, которые определяют на основе свойств символов правила их визуализации, сортировки и преобразования в прописные/строчные буквы.

В итоге можно сказать, что стандарт Unicode состоит из трех взаимосвязанных частей:

    базы данных символов;

    базы графем (glyphs), определяющих визуальное представление этих символов;

    набора алгоритмов, определяющих правила работы с символами.

В заключение этого раздела приведем графемы блока кириллицы (коды 0400 — 04FF). Обратите внимание, что он включает в себя не только буквы современных кириллических алфавитов (русского, украинского, белорусского, болгарского, сербского, македонского и пр.), но и все буквы первоначальной кириллицы, использовавшиеся в церковнославянской письменности.

Трансформационные форматы

Как мы видели, каждый символ Unicode имеет уникальный 21-битовый код (code point). Однако, для практической реализации такая кодировка символов неудобна. Дело в том, что операционные системы и сетевые протоколы традиционно работают с данными как с потоками байтов. Это приводит, как минимум, к двум проблемам:

    Порядок байтов в слове у разных процессоров различен. Процессоры Intel, DEC и др. хранят в первом байте машинного слова его старший байт, а процессоры Motorola, Sparc и др. — младший байт. Их соответственно называют little-endian и big-endian (эти термины происходят от «остроконечников» и «тупоконечников» у Свифта, споривших о том, с какого конца нужно разбивать яйца).

    Многие байт-ориентированные системы и протоколы допускают использование в качестве данных только байтов из определенного диапазона. Остальные байты рассматриваются как служебные; в частности, нулевой байт принято использовать как символ конца строки. Поскольку Unicode кодирует символы подряд, прямая передача его кодов как цепочки байтов может войти в противоречие с правилами протокола передачи данных.

Для преодоления этих проблем стандарт включает в себя три трансформационных формата UTF-8, UTF-16 и UTF-32, которые определяют соответственно правила кодирования символов Unicode цепочками байтов, парами 16-битовых слов и 32-битовыми словами. Выбор используемого формата зависит от архитектуры вычислительной системы и стандартов хранения и передачи данных. Краткое описание трансформационных форматов можно найти в WDH: Стандарт Unicode .

Проблемы реализации

Думаю, что даже из приведенного выше краткого описания стандарта Unicode ясно, что его полная поддержка основными операционными системами будет означать революцию в области обработки текстов. Пользователь, сидящий за любым терминалом Сети, сможет выбрать любую раскладку клавиатуры, набрать текст на любом языке и передать его на любой компьютер, который правильно этот текст отобразит. Базы данных смогут хранить, правильно сортировать и выводить в отчеты текстовую информацию опять-таки на любом языке. Для того, чтобы этот рай наступил, необходимы пять вещей:

    Операционные системы должны поддерживать трансформационные форматы Unicode на уровне ввода, хранения и отображения текстовых строк.

    Необходимы «умные» драйверы клавиатур, позволяющие нам вводить символы любого блока Unicode и передающие их коды операционной системе.

    Текстовые редакторы должны поддерживать отображение всех символов Unicode и выполнять над ними общепринятый набор символьных операций.

    То же самое должно правильно выполняться СУБД в отношении текстовых и memo-полей.

    Поскольку национальные кодировки еще долгое время будут сосуществовать с Unicode, необходима поддержка преобразований текста между ними.

С сожалением приходится признать, что за десять лет (Unicode 1.0 появился в 1991 г.) в этом направлении сделано гораздо меньше, чем хотелось бы. Даже Windows, содержащая на системном уровне наиболее последовательную поддержку Unicode, полна абсолютно иррациональных ограничений, объясняемых только ее историческим развитием. В Unix ситуация еще хуже, поскольку здесь поддержка Unicode перенесена из ядра на конкретные приложения. Можно утверждать, что на сегодня наиболее серьезно Unicode поддерживается в двух средах: веб-браузерах и виртуальных Java-машинах. Это не удивительно, поскольку обе среды изначально создавались как системно-независимые.

Следует отметить и объективные трудности поддержки Unicode. Для примера остановимся только на отображении графем, для которого нужно установить в системе соответствующие шрифты. Проблема в том, что шрифт, содержащий все графемы Unicode будет иметь совершенно несуразный размер. Например, TrueType-шрифт Arial Unicode MS, содержащий большую порцию символов Unicode, «весит» 24Мб. По мере наполнения Unicode новыми блоками размер таких шрифтов приблизится к 100Мб. Выходом из положения может послужить предложенная Microsoft загрузка символов по требованию, принятая в их браузере Internet Explorer. Однако, пока стандарты о правилах формирования Unicode-шрифтов молчат.

Способы работы с символами Unicode и национальных кодировок в важнейших средах и системах программирования будут рассмотрены в следующих статьях.

Она, может быть, была. Когда-нибудь. Раньше. Или ещё только в планах. Но сейчас её нет.

Любые числа (в определенных пределах) в памяти компьютера кодируются числами двоичной системы счисления. Для этого существуют простые и понятные правила перевода. Однако на сегодняшний день компьютер используется куда шире, чем в роли исполнителя трудоемких вычислений. Например, в памяти ЭВМ хранятся текстовая и мультимедийная информация. Поэтому возникает первый вопрос:

Как в памяти компьютера хранятся символы (буквы)?

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

Соответствие букв определенного алфавита с числами-кодами формирует так называемую таблицу кодирования. Другими словами, каждый символ конкретного алфавита имеет свой числовой код в соответствии с определенной таблицей кодирования.

Однако алфавитов в мире очень много (английский, русский, китайский и др.). Поэтому следующий вопрос:

Как закодировать все используемые на компьютере алфавиты?

Для ответа на этот вопрос пойдем историческим путем.

В 60-х годах XX века в американском национальном институте стандартизации (ANSI) была разработана таблица кодирования символов, которая впоследствии была использована во всех операционных системах. Эта таблица называется ASCII (American Standard Code for Information Interchange – американский стандартный код для обмена информацией). Чуть позже появилась расширенная версия ASCII.

В соответствие с таблицей кодирования ASCII для представления одного символа выделяется 1 байт (8 бит). Набор из 8 ячеек может принять 28 = 256 различных значений. Первые 128 значений (от 0 до 127) постоянны и формируют так называемую основную часть таблицы, куда входят десятичные цифры, буквы латинского алфавита (заглавные и строчные), знаки препинания (точка, запятая, скобки и др.), а также пробел и различные служебные символы (табуляция, перевод строки и др.). Значения от 128 до 255 формируют дополнительную часть таблицы, где принято кодировать символы национальных алфавитов.

Поскольку национальных алфавитов огромное множество, то расширенные ASCII-таблицы существуют во множестве вариантов. Даже для русского языка существуют несколько таблиц кодирования (распространены Windows-1251 и Koi8-r). Все это создает дополнительные трудности. Например, мы отправляем письмо, написанное в одной кодировке, а получатель пытается прочитать ее в другой. В результате видит кракозябры. Поэтому читающему требуется применить для текста другую таблицу кодирования.

Есть и другая проблема. В алфавитах некоторых языков слишком много символов и они не помещаются в отведенные им позиции с 128 до 255 однобайтовой кодировки.

Третья проблема — что делать, если в тексте используется несколько языков (например, русский, английский и французский)? Нельзя же использовать две таблицы сразу …

Чтобы решить эти проблемы одним разом была разработана кодировка Unicode.

Стандарт кодирования символов Unicode

Для решения вышеизложенных проблем в начале 90-х был разработан стандарт кодирования символов, получивший название Unicode. Данный стандарт позволяет использовать в тексте почти любые языки и символы.

В Unicode для кодирования символов предоставляется 31 бит (4 байта за вычетом одного бита). Количество возможных комбинаций дает запредельное число: 231 = 2 147 483 684 (т.е. более двух миллиардов). Поэтому Unicode описывает алфавиты всех известных языков, даже «мертвых» и выдуманных, включает многие математические и иные специальные символы. Однако информационная емкость 31-битового Unicode все равно остается слишком большой. Поэтому чаще используется сокращенная 16-битовая версия (216 = 65 536 значений), где кодируются все современные алфавиты.

В Unicode первые 128 кодов совпадают с таблицей ASCII.

В традиционных кодировках для кодирования одного символа используется 8 бит. Легко подсчитать по

N=2i где

i – количество информации;

N – количество возможных событий; что такой 8-разрядный код позволяет закодировать 256 различных символов.

Присвоение символу определенного числового кода — это вопрос соглашения. В качестве международного стандарта принята кодовая таблица ASCII , кодирующая первую половину символов с числовыми кодами от 0 до 127 (коды от 0 до 32 отведены не символам, а функциональным клавишам).

Национальные стандарты кодировочных таблиц включают международную часть кодовой таблицы без изменений, а во второй половине содержат коды национальных алфавитов, символы псевдографики и некоторые математические знаки. К сожалению, в настоящее время существуют пять различных кодировок кириллицы (КОИ8-Р, Windows, MSDOS, Macintocs и ISO), что вызывает дополнительные трудности при работе с рускоязычными документами.

Хронологически одним из первых стандартов кодирования русских букв на компьютерах был КОИ8 («Код обмена информацией, 8-битный»). Эта кодировка применялась еще в 70-ые годы прошлого века на компьютерах серии ЕС ЭВМ, а с середине 80-х стала использоваться в первых русифицированных версиях операционной системы UNIX.

Пример . Представьте в форме шестнадцатеричного кода слово «ЭВМ» » в 4-х кодировках.

Переводим с помощью калькулятора последовательности кодов из десятичной системы в шестнадцатеричную:

КОИ8-Р:

FС F7 ЕD

СР1251:

DD С2 СС

Maс:

9В 82 8С

ISO:

СD В2 ВС

В конце 90-х годов появился новый международный стандарт Unicode, который отводит под один символ не один байт, а два, и поэтому с его помощью можно закодировать не 256, а 65536 различных символов. Полная спецификация стандарта Unicode включает в себя все существующие, вымершие и искусственно созданные алфавиты мира, а также множество математических, музыкальных, химических и прочих символов.

.

Пример . Представьте в форме шестнадцатеричного кода слово «ЭВМ» в 4-х кодировках.

Последовательности десятичных кодов слова «ЭВМ» в различных кодировках составляем на основе кодировочных таблиц:

КОИ8-Р:

252 247 237

СР1251:

221 194 204

Mac:

157 130 140

ISO:

205 178 188

«Кодирование текстовой информации» — Урок

Тема урока: «Кодирование текстовой информации»

1. Человек различает символы по их начертаниям, а компьютер — по кодам. Каждому символу ставится в соответствие уникальный код. В традиционных кодировках для кодирования одного символа используется 8 бит. Такой 8-разрядный код позволяет закодировать 256 различных символов.

Присвоение символу определенного числового кода – это вопрос соглашения. В качестве международного стандарта принята кодовая таблица ASCII (American Standard Code for Information Interchange), кодирующая первую половину символов с числовыми кодами от 0 до 127 (коды от 0 до 32 отведены не символам, а функциональным клавишам).

Международная кодировка ASCII

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

К сожалению, в настоящее время существуют пять различных кодировок кириллицы (КОИ8-Р, Windows, MS-DOS, Macintosh и ISO), что вызывает дополнительные трудности при работе с русскоязычными документами.
Хронологически одним из первых стандартов кодирования русских букв на компьютерах был КОИ8 («Код обмена информацией, 8-битный»). Эта кодировка применялась еще в 70-ые годы на компьютерах серии ЕС ЭВМ, а с середины 80-х стала использоваться в первых русифицированных версиях операционной системы UNIX.

Кодировка русских букв КОИ8-Р

Наиболее распространенной в настоящее время является кодировка Microsoft Windows, обозначаемая сокращением CP1251 («CP» означает «Code Page», «кодовая страница»).

Кодировка русских букв CP1251

От начала 90-ых годов, времени господства операционной системы MS DOS, остается кодировка CP866.

Кодировка русских букв CP866

Компьютеры фирмы Apple, работающие под управлением операционной системы Mac OS, используют свою собственную кодировку Mac.

Кодировка русских букв MAC

Международная организация по стандартизации (International Standards Organization, ISO) утвердила в качестве стандарта для русского языка еще одну кодировку под названием ISO 8859-5.

Кодировка русских букв ISO 8859-5

В конце 90-ых годов появился новый международный стандарт Unicode, который отводит под один символ не один байт, а два, и поэтому с его помощью можно закодировать не 256, а 65536 различных символов. Полная спецификация стандарта Unicode включает в себя все существующие, вымершие и искусственно созданные алфавиты мира, а также множество математических, музыкальных, химических и прочих символов.

Последовательности десятичных кодов слова «ЭВМ» в различных кодировках на основе кодировочных таблиц:

КОИ8-Р

252 247 237

CP1251

221 194 204

CP866

157 130 140

Mac

157 130 140

ISO

205 178 188

Кодовые таблицы при объяснении демонстрируются через проектор.

2. Коды символов можно найти и с помощью MS Word. (Вставка — Символ). Найти несколько числовых кодов и сравнить их значение со значением в таблице кодов .CP1251.

3. Открываю Блокнот и таблицы кодов CP866 и CP1251. Учащиеся называют любое короткое слово и это слово набирается в Блокноте с помощью кодов CP866 и CP1251 при нажатой клавише Alt в одной, затем в другой кодировке. Коды называют учащиеся, отыскивая их в таблице кодов (в кодировке CP866 набирается код, в кодировке CP1251 набирается перед кодом ноль, например, код «Ж» — 198. При нажатой клавише Alt набираем 0198). Буквы всегда можно ввести и без кодов, но если в текстовом редакторе типа Блокнот нужно получить таблицу, то без кодов не обойтись. Элементы таблицы имеются в кодовой таблице .CP866. Показываю пример. Но здесь важно выбрать шрифт. Он указан ниже таблицы.

4. Открываю любую Web-страницу или сайт на русском языке, например, сайт школы. Меняю кодировки, сравниваем вид страницы.

IV. Закрепление

Перед началом выполнения заданий на компьютере вспомним, каким должно быть расстояние от экрана монитора до глаз. (60-70 см.). Как избежать вредного влияния от монитора? (Экран монитора должен быть чистым. Нельзя прикасаться к нему пальцами)

Вопросы и задания:
1. Во сколько раз уменьшится информационный объем страницы текста при его преобразовании из кодировки Unicode (таблица кодировки содержит 65536 символов) в кодировку Windows CP1251(таблица кодировки содержит 256 символов)? (В 2 раза)

2. Каков информационный объем текста, содержащего слово ИНФОРМАТИКА, в 8-ми битной кодировке? в 16-битной кодировке? (11 байтов, 22 байта)

3. Декодируйте следующие тексты, заданные десятичным кодом: 
а) 087 111 114 100; (Word)
б) 068 079 083; (DOS)
в) 080 097 105 110 116 098 114 117 115 104. (Paintbrush)

4. Как будет выглядеть слово «диск», записанное в кодировке CP1251, в других кодировках? 
( КОИ8-Р: ДХЯЙ ; CP866: фшёъ; Mac: диск ; ISO: фшёъ)

5. В текстовом режиме экран обычно разбивается на 25 строк по 80 символов в строке. Определите объем текстовой информации, занимающей весь экран монитора. (25 х 80 = 2000 байт)

Тексты заданий имеются на каждом компьютере ученика в файле «Кодирование. Задания.doc»

Дополнительно. Создать любую таблицу в Блокноте. Шрифт Lucida Console.

Международный стандарт кодирования текстовых символов Unicode отводит на каждый символ _ байта(ов)

К социально-значимым свойствам информации относятся
(*ответ*) понятность
(*ответ*) достоверность
(*ответ*) актуальность
 прямолинейность
 стилизованность
К.Шеннон в 1948 году предложил формулу для вычисления _ информации для событий с различными вероятностями
(*ответ*) количества
К.Шеннон в 1948 году предложил формулу для вычисления количества информации для событий с _ вероятностями
(*ответ*) разными
 одинаковыми
 большими
 малыми
Количество знаков определяет _алфавита
(*ответ*) мощность
Количество информации, которое используется при кодировании цвета точек растрового изображения, называется _ цвета
(*ответ*) глубиной
Количество получаемой информации, достигает _ значения, если события равновероятны (выберите: максимального или минимального)
(*ответ*) максимального
Количество получаемой информации, достигает максимального значения, если события
(*ответ*) равновероятны
Количество точек в полоске изображения длиной один _- определяет разрешающую способность экрана
(*ответ*) дюйм
 сантиметр
 миллиметр
 дециметр
Количество точек в полоске изображения длиной один дюйм определяет разрешающую _ экрана
(*ответ*) способность
Компьютер оперирует числами в_ системе счисления
(*ответ*) двоичной
 десятичной
 троичной
 пятеричной
Макрообъекты состоят из молекул и атомов, которые, в свою очередь, состоят из элементарных частиц, размеры которых чрезвычайно малы. Этот мир называется
(*ответ*) микромиром
 макромиром
 минимиром
 мегамиром
Максимальное положительное целое число в формате больших целых чисел со знаком равно
(*ответ*) 2 147 483 64710
 2 147 483 64810
 2 147 483 54710
 2 147 483 34710
Максимальное положительное целое число в формате целых чисел со знаком равно
(*ответ*) 32 76710
 32 56710
 32 36710
 32 26710
Международный стандарт кодирования текстовых символов Unicode отводит на каждый символ _ байта(ов)
(*ответ*) 2
 4
 8
 5
Минимальное неотрицательное число в формате с фиксированной запятой равно _ (дайте ответ словом)
(*ответ*) нулю
Минимальное отрицательное целое число в формате больших целых чисел со знаком равно
(*ответ*) -2 147 483 64810
 -2 147 483 64710
 -2 147 483 54810
 -2 147 483 34810
Минимальное отрицательное целое число в формате целых чисел со знаком равно
(*ответ*) -3276810
 -3256810
 -3236810
 -3226810

Двоичное кодирование текстовой информации

Начиная с 60-х годов, компьютеры все больше стали использовать для обработки текстовой информации и в настоящее время большая часть ПК в мире занято обработкой именно текстовой информации.

Традиционно для кодирования одного символа используется количество информации = 1 байту (1 байт = 8 битов).

Для кодирования одного символа требуется один байт информации.

Учитывая, что каждый бит принимает значение 1 или 0, получаем, что с помощью 1 байта можно закодировать 256 различных символов. (28 = 256)

Кодирование заключается в том, что каждому символу ставится в соответствие уникальный двоичный код от 00000000 до 11111111 (или десятичный код от 0 до 255).

Важно, что присвоение символу конкретного кода – это вопрос соглашения, которое фиксируется кодовой таблицей.

Таблица, в которой всем символам компьютерного алфавита поставлены в соответствие порядковые номера (коды), называется таблицей кодировки.

Для разных типов ЭВМ используются различные кодировки. С распространением IBM PC международным стандартом стала таблица кодировки ASCII (American Standard Code for InformationInterchange) – Американский стандартный код для информационного обмена.

Стандартной в этой таблице является только первая половина, т.е. символы с номерами от 0 (00000000) до 127 (0111111). Сюда входят буква латинского алфавита, цифры, знаки препинания, скобки и некоторые другие символы.

Остальные 128 кодов используются в разных вариантах. В русских кодировках размещаются символы русского алфавита.

В настоящее время существует 5 разных кодовых таблиц для русских букв (КОИ8, СР1251, СР866, Mac, ISO).

В настоящее время получил широкое распространение новый международный стандарт Unicode, который отводит на каждый символ два байта. С его помощью можно закодировать 65536 (216= 65536 ) различных символов.

Таблица стандартной части ASCII

Таблица расширенного кода ASCII (один из вариантов)

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

В этом случае легко подсчитать объем информации в тексте. Если 1 символ алфавита несет 1 байт информации, то надо просто сосчитать количество символов; полученное число даст информационный объем текста в байтах.

Пусть небольшая книжка, сделанная с помощью компьютера, содержит 150 страниц; на каждой странице — 40 строк, в каждой строке — 60 символов. Значит страница содержит 40×60=2400 байт информации. Объем всей информации в книге: 2400 х 150 = 360 000 байт.

Обратите внимание! Цифры кодируются по стандарту ASCII в двух случаях – при вводе-выводе и когда они встречаются в тексте. Если цифры участвуют в вычислениях, то осуществляется их преобразование в другой двоичных код.

Возьмем число 57.

При использовании в тексте каждая цифра будет представлена своим кодом в соответствии с таблицей ASCII. В двоичной системе это – 00110101 00110111.

При использовании в вычислениях, код этого числа будет получен по правилам перевода в двоичную систему и получим – 00111001.

 

Билет № 4
1. Дискретное представление информации: кодирование цветного изображения в компьютере (растровый подход). Представление и обработка звука и видеоизображения. Понятие мультимедиа.

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

Кодирование – преобразование входной информации в форму, воспринимаемую компьютером, т.е. двоичный код.

Декодирование – преобразование данных из двоичного кода в форму, понятную человеку.

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

0 – отсутствие электрического сигнала;

1 – наличие электрического сигнала.

Эти состояния легко различать. Недостаток двоичного кодирования – длинные коды. Но в технике легче иметь дело с большим количеством простых элементов, чем с небольшим числом сложных.

Вам приходится постоянно сталкиваться с устройством, которое может находится только в двух устойчивых состояниях: включено/выключено. Конечно же, это хорошо знакомый всем выключатель. А вот придумать выключатель, который мог бы устойчиво и быстро переключаться в любое из 10 состояний, оказалось невозможным. В результате после ряда неудачных попыток разработчики пришли к выводу о невозможности построения компьютера на основе десятичной системы счисления. И в основу представления чисел в компьютере была положена именно двоичная система счисления.

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

Основные понятия информатики (стр. 8 из 15)

Для совместимости компьютеров при обработке текстовой информации принят международный стандарт кодирования символов — код ASCII (AmericanStandardCodeforInformationInterchange), который устанавливает соответствие между символами и их порядковыми номерами в компьютерном алфавите. В таблице ASCII для кодирования одного символа используется 1 байт (8 битов). Стандартными являются первые 128 символов (0-127), сюда входят буквы латинского алфавита, цифры, знаки препинания, спецсимволы и управляющие коды или операции (0-32). Остальные символы (128-255) используют для кодирования национальных алфавитов, научных символов и символов псевдографики. С 1997 года введен новый стандарт Unicode, где под каждый символ отводится 2 байта.

Для подсчета информационного объема текста пользуются алфавитным способом измерения информации. Принимая, что каждый символ занимает 1 байт информации (при мощности алфавита 256), для определения объема текста необходимо подсчитать количество символов в нем.

Вся информация в компьютере кодируется двоичными числами, в том числе графическая, а также звук и видео. Рассмотрим, как создается модель изображения, годная для обработки компьютером. Разобьем картинку вертикальными и горизонтальными линиями на маленькие прямоугольники. Полученный двумерный массив прямоугольников называется растром, а сами прямоугольники — элементами растра, или пикселями (это слово произошло от английского picture’selement — элемент картинки). Далее закодируем числами цвета пикселей. Перечислим по порядку (например, слева направо и сверху вниз) коды цветов пикселей. Получим представление (код) картинки в компьютере.

Разумеется, часть информации о картинке при таком кодировании потеряется. Потери будут тем меньше, чем мельче прямоугольники и чем точнее закодирован цвет каждого из них.

Билет № 15

1) Команда ветвления — разделяет алгоритм на два пути в зависимости от некоторого условия, затем исполнение алгоритма выходит на общее продолжение. Ветвление бывает полное и неполное. Описание ветвления в блок-схемах и на Алгоритмическом языке Ветвление — это составная команда алгоритма, в которой в зависимости от условия предусмотрен переход либо на одно, либо на другое действие. Действия могут быть простыми или составными командами алгоритма.Команда ветвления может использоваться в сокращенной форме, когда в случае несоблюдения условия никакое действие не выполняется. В этом случае в блок-схеме команды ветвления действие отсутствует всегда справа (путь «нет»). Под действием понимается либо простая команда, либо составная команда алгоритма. Разветвляющиеся алгоритмы (алгоритмы ветвления) состоят из команд ветвления и могут быть дополнены командами следования. В отличие от линейных алгоритмов, в которых команды выполняются последовательно одна за другой, в алгоритмическую структуру «ветвление» входит условие в зависимости от выполнения или невыполнения которого реализуется та или иная последовательность команд. Валгоритмическойструктуре«ветвление»таили инаясериякомандвыполняетсявзависимостиот истинностиусловия. Будем называть условием высказывание, которое может быть либо истинным, либо ложным. Условие, записанное на формальном языке, называется условным или логическим выражением.

Условные выражения могут быть простыми и сложными. Простое условие включает в себя два числа, две переменных или два арифметических выражения, которые сравниваются между собой с использованием операций сравнения (равно, больше, меньше и пр.).

Например: 5>3, 2*8 = 4*4 и т. д.

Сложное условие — это последовательность простых условий, объединенных между собой знаками логических операций. Например, 5>3 And2*8 = 4*4.

Алгоритмическая структура «ветвление» может быть зафиксирована различными способами:

· графически, с помощью блок-схемы

· на языке программирования, например на языках VisualBasic и VBA с использованием специальной инструкции ветвления (оператора условного перехода). После первого ключевого слова (If) должно быть размещено условие. После второго ключевого слова (Then) последовательность команд (серия 1), которая должна выполняться, если условие принимает значение «истина». После третьего ключевого слова (Else) размещается последовательность команд (серия 2), которая должна выполняться, если условие принимает значение «ложь». Оператор условного перехода может быть записан в многострочной форме или в однострочной форме.

В многострочной форме он записывается с помощью инструкции If… Then . . . Else. . . EndIf(Если … To … Иначе … Конец Если). В этом случае ключевое слово Thenразмещается на той же строчке, что и условие, а последовательность команд (серия 1) — на следующей. Третье ключевое слово Elseразмещается на третьей строчке, а последовательность команд (серия 2) — на четвертой. Конец инструкции ветвления EndIf размещается на пятой строчке.

В однострочной форме он записывается с помощью инструкции If… Then .. . Else. . . (Если … То … Иначе …). Если инструкция не помещается на одной строке, она может быть разбита на несколько строк. Такое представление инструкций более наглядно для человека. Компьютер же должен знать, что разбитая на строки инструкция представляет единое целое. Это обеспечивает знак «переноса», который задается символом подчеркивания после пробела « _». Третье ключевое слово Elseв сокращенной форме инструкции может отсутствовать. Тогда, в случае если условие ложно, выполнение оператора условного перехода заканчивается и выполняется следующая строка программы.

2)Традиционно для кодирования одного символа используется количество информации, равное 1 байту, то есть / = = 1 байт = 8 битов.

Если рассматривать символы как возможные события, то по формуле (2.1) можно вычислить, какое количество различных символов можно закодировать:

N = 2I= 28 = 256.

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

Кодирование заключается в том, что каждому символу ставится в соответствие уникальный десятичный код от 0 до 255 или соответствующий ему двоичный код от 00000000 до 11111111. Таким образом, человек различает символы по их начертаниям, а компьютер — по их кодам.

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

В процессе вывода символа на экран компьютера производится обратный процесс — декодирование, то есть преобразование кода символа в его изображение.

Важно, что присвоение символу конкретного кода — это вопрос соглашения, которое фиксируется в кодовой таблице. Первые 33 кода (с 0 по 32) соответствуют не символам, а операциям (перевод строки, ввод пробела и так далее).

Коды с 33 по 127 являются интернациональными и соответствуют символам латинского алфавита, цифрам, знакам арифметических операций и знакам препинания.

Коды с 128 по 255 являются национальными, то есть в национальных кодировках одному и тому же коду соответствуют различные символы. К сожалению, в настоящее время существуют пять различных кодовых таблиц для русских букв (КОИ8, СР1251, СР866, Mac, ISO — табл. 2.3), поэтому тексты, созданные в одной кодировке, не будут правильно отображаться в другой.

В настоящее время широкое распространение получил новый международный стандарт Unicode, который отводит на каждый символ не один байт, а два, поэтому с его помощью можно закодировать не 256 символов, а N = 216 = = 65536 различных символов. Эту кодировку поддерживают последние версии платформы MicrosoftWindows&Office.Каждая кодировка задается своей собственной кодовой таблицей. Как видно из табл. 2.3, одному и тому же двоичному коду в различных кодировках поставлены в соответствие различные символы.

Например, последовательность числовых кодов 221, 194, 204 в кодировке СР1251 образует слово «ЭВМ», тогда как в других кодировках это будет бессмысленный набор символов.

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

Билет № 16

1) Повторение — это составная команда алгоритма, в которой в зависимости от соблюдения условия может повторяться выполнение некоторых действий. Под действием, как и прежде, понимается простая или составная команда.

Цикл — многократное повторение последовательности действий по некоторому условию. Известны три типа циклических алгоритмических структур: цикл с предусловием, цикл с постусловием и цикл с параметром. В Паскале существуют операторы, реализующие все три типациклов.

Цикл со счетчиком. Когда заранее известно, какое число повторений тела цикла необходимо выполнить, можно воспользоваться циклической инструкцией (оператором цикла со счетчиком) ForNext. Синтаксис оператора For.Next следующий: строка, начинающаяся с ключевого слова For, является заголовком цикла, а строка с ключевым словом Next — концом цикла, между ними располагаются операторы, являющиеся телом цикла.

В начале выполнения цикла значение переменной Счетчик устанавливается равным НачЗнач. При каждом проходе цикла переменная Счетчик увеличивается на величину шага. Если она достигает величины, большей КонЗнач, то цикл завершается и выполняются следующие за ним операторы.

2) То огромное количество информации, которое требуется человеку для осуществления любой деятельности, следует хранить в структурированном виде, чтобы можно было быстро находить необходимую информацию, делать любые выборки, пополнять, изменять, сортировать информацию. Организованные массивы информации определенного назначения (тематики) называют базами данных (БД). Примеры баз данных: база данных кинотеатров города, база данныхкнижного фонда библиотеки, база данных нормативных правовых актов в сфере образования. Программы, обеспечивающие работу с базами данных, называют системами управления базами данных.

Кодировка символов сейчас

ASCII и UTF-8 — две современные системы кодирования текста. Оба они описаны в этом видео с участием Кейтлин Мерри.

Два стандарта кодировки символов определяют, как символы декодируются из единиц и нулей в текст, который вы видите на экране прямо сейчас, и на разные языки, просматриваемые каждый день во всемирной паутине. Эти два стандарта кодирования — ASCII и Unicode.

ASCII

Американский стандартный код для обмена информацией (ASCII) был разработан для создания международного стандарта кодирования латинского алфавита.В 1963 году был принят ASCII, чтобы можно было интерпретировать информацию между компьютерами; представляющие нижние и верхние буквы, цифры, символы и некоторые команды. Поскольку ASCII кодируется с использованием единиц и нулей, система счисления с основанием 2, он использует семь битов. Семь битов позволяют 2 в степени 7 = 128 возможных комбинаций цифр для кодирования символа. Таким образом, ASCII обеспечил возможность кодирования 128 важных символов:

Как работает кодирование ASCII

  • Вы уже знаете, как конвертировать между денарами и двоичные числа
  • Теперь вам нужно преобразовать буквы в двоичные числа
  • Каждому символу соответствует десятичное число (например, A → 65)
  • ASCII использует 7 битов
  • Мы используем первые 7 столбцов таблицы преобразования для создать 128 различных чисел (от 0 до 127)
Например, 1000001 дает нам число 65 ( 64 + 1 ), которое соответствует букве «А».Вот как ‘HELLO’ кодируется в ASCII в двоичном формате:
Латинский символ ASCII
H 1001000
E 1000101
L 1001100
L 1001100
O 1001111
Давайте применим эту теорию на практике:
  1. Откройте Блокнот или любой другой текстовый редактор, который вы предпочитаете
  2. Введите сообщение и сохраните его, например.грамм. «Данные прекрасны»
  3. Посмотрите размер файла — у меня 18 байт
  4. Теперь добавьте еще слово, например ‘data is SO beautiful’
  5. Если вы снова посмотрите на размер файла, вы увидите, что он изменился — мой файл теперь на 3 байта больше (SO [SPACE]: ‘S’, ‘O’ и пробел)

Unicode и UTF-8

Поскольку ASCII кодирует символы в 7-битном формате, переход к 8-битной вычислительной технологии означал, что нужно было использовать один дополнительный бит. С помощью этой дополнительной цифры Extended ASCII закодирует до 256 символов.Однако возникшая проблема заключалась в том, что страны, которые использовали разные языки, делали разные вещи с этой дополнительной возможностью кодирования. Многие страны добавляли свои собственные дополнительные символы, а разные числа представляли разные символы на разных языках. Япония даже создала несколько систем кодирования японского языка в зависимости от оборудования, и все эти методы были несовместимы друг с другом. Поэтому, когда сообщение было отправлено с одного компьютера на другой, полученное сообщение могло стать искаженным и нечитаемым; японские системы кодирования символов были настолько сложными, что даже когда сообщение отправлялось с одного типа японского компьютера на другой, происходило нечто, называемое «моджибаке»: проблема несовместимых систем кодирования стала более актуальной с изобретением Всемирной паутины, поскольку люди обмениваются цифровыми документами по всему миру, используя несколько языков.Чтобы решить эту проблему, Консорциум Unicode установил универсальную систему кодирования под названием Unicode . Unicode кодирует более 100000 символов, охватывая все символы, которые вы найдете в большинстве языков. Unicode присваивает каждому символу определенное число, а не двоичную цифру. Но с этим были некоторые проблемы, например:
  1. Для кодирования 100000 символов потребуется около 32 двоичных цифр. Unicode использует ASCII для английского языка, поэтому A по-прежнему 65.Однако в 32-битной кодировке двоичное представление буквы A будет 000000000000000000000000000000000001000001. Это тратит много ценного места!
  2. Многие старые компьютеры интерпретируют восемь нулей подряд (ноль) как конец строки символов. Таким образом, эти компьютеры не отправляли символы, идущие после восьми нулей подряд (они не отправляли бы A, если бы оно было представлено как 000000000000000000000000000000000001000001).
Метод кодирования Unicode UTF-8 решает следующие проблемы:
— До символа 128 используется обычное значение ASCII (например, A — 01000001)
— Для любого символа, превышающего 128, UTF-8 разделяет код на два байта и добавление «110» в начало первого байта, чтобы показать, что это начальный байт, и «10» в начало второго байта, чтобы показать, что он следует за первым байтом.Итак, для каждого символа после числа 128 у вас есть два байта:
  [110xxxxx] [10xxxxxx] 
И вы просто заполняете двоичный код для числа между ними:
  [11000101] [10000101] (это число 325 → 00101000101) 
Это работает для первых 2048 символов. Для других символов в начале первого байта добавляется еще одна «1», а также используется третий байт:
  [1110xxxx] [10xxxxxx] [10xxxxxx] 
Это дает вам 16 пробелов для двоичного кода.Таким образом, UTF-8 увеличивается до четырех байтов:
  [11110xxx] [10xxxxxx] [10xxxxxx] [10xxxxxx] 
Таким образом, UTF-8 избегает проблем, упомянутых выше, а также требует индекса и он позволяет вам декодировать символы из двоичной формы в обратном направлении (т.е. он обратно совместим).

Занятия в классе

Есть много забавных занятий для обучения кодированию символов. Ниже мы включили два упражнения, которые вы можете попробовать в своем классе. Какие главные советы вы можете дать по обучению кодировке символов? Делитесь ими в комментариях!
  • Перевод секретных сообщений : опубликуйте короткое секретное сообщение в ASCII разделе комментариев и переводите или отвечайте на сообщения ASCII других участников
  • Двоичные браслеты : создавайте браслеты, используя бусины разного цвета для представления единиц и нулей и написания инициал или имя в ASCII

ASCII и Unicode (UTF).ASCII (Американский стандартный код для… | от Джона Уильямса

Представление текста с использованием чисел. Первоначально он был разработан для телетайпов, по сути, обычного текста без форматирования. ASCII — это 7-битный набор символов, содержащий 128 символов. Он включает верхний и нижний регистр AZ, числа и специальные символы (разрыв строки, возврат каретки, escape и т. д.).

NB Разрывы строк

CR и LF — это управляющие символы ASCII. CR — это байт-код для возврата каретки (со времен пишущих машинок) и LF аналогично для перевода строки.

В разных ОС используется другой байт-код для разрыва строки (Windows использует окончание строки CR LF, а Unix просто использует LF). Это может вызвать проблемы при сохранении документов на разных платформах.

UniCode — это гораздо больший набор символов. Он отображает любой текст на любом языке (https://unicode-table.com/en/#control-character). Первые 128 символов Unicode взаимно однозначно соответствуют ASCII.

Unicode 10.0 , содержит набор из 136 755 символов, охватывающий 139 современных и исторических сценариев, а также несколько наборов символов и эмодзи.
https://en.wikipedia.org/wiki/Unicode

UTF — это кодировка символов, которая кодирует символы, определенные в Unicode.

Эффективность хранения: UTF-8 и эффективность обработки: UTF-32

Кодировка UTF-8

В большинстве современных Unix-подобных систем и веб-страниц кодировка символов по умолчанию используется в UTF-8. Кодирование имеет переменную длину и 8-битные блоки (например, 8, 16, 24 или 32 бита для кодирования символа Unicode.

Кодовые точки больше 127 представлены многобайтовыми последовательностями.Старшие биты любого UTF-8 определяют, сколько байтов содержит двоичный UTF-8. Старший байт имеет две или более старших единицы, за которыми следует 0, в то время как все байты продолжения имеют «10» в старшей позиции. Таким образом, байты, представляющие символы ASCII, не появляются в многобайтовых последовательностях.

0xxxxxxx 0x00..0x7F Только байт 1-байтовой кодировки символов
10xxxxxx 0x80..0xBF Байты продолжения (1–3 байта продолжения)
110xxxxx 0xC0..0xDF Первый байт 2-байтовой кодировки символов
1110xxxx 0xE0..0xEF Первый байт 3-байтовой кодировки символов
11110xxx 0xF0..0xF4 Первый байт 4-байтовой кодировки символов

UTF-16, UTF-32

UTF-16 требует 16 или 32 бит для кодирования персонаж. UTF-32 всегда требует 32 бита для кодирования символа.

Кодировка UTF-32 используется для кодирования (сериализации) символов Unicode в поток байтов. Таким образом, если байты потеряны, каждый байт идентифицирует поток блока и его спецификацию (метку порядка байтов).

Varchar (1 байт на символ) хранит данные ASCII и должен быть вашим типом данных для обычного использования.

Nvarchar (2 байта на символ) хранит данные UNICODE. Если у вас есть требования к хранению данных в формате UNICODE или многоязычных данных, лучшим выбором будет nvarchar.

Стандарт Unicode

Когда люди обмениваются информацией, мы используем предложения, слова и — что наиболее важно для наших целей — буквы. Но компьютеры ничего не знают о письмах. Компьютеры знают только о числах, и, честно говоря, они тоже мало о них знают. Поскольку компьютеры, в конечном счете, представляют собой огромную коллекцию электронных переключателей, они знают только два числа: ноль, если переключатель выключен, и один, когда переключатель включен.8 = 256 \) возможных состояний в байтах, поэтому мы можем представить число от 0 до 255. Но все же все является числом.

Чтобы перейти от цифр к буквам и сохранить текст в компьютере, нам нужно согласовать код. Мы можем решить, что, ожидая текста, цифра 1 означает «а», цифра 2 означает «б» и так далее. Это отображение между числами и символами называется кодировкой .

На заре компьютеров у каждого производителя была своя собственная кодировка, но вскоре они поняли, что данные, записанные в одной системе, не могут быть прочитаны в другой.7 = 128 \) символов.

В ASCII числа от 0 до 31 используются для кодирования «управляющих символов». Они не представляют информацию для печати, но дают инструкции устройствам, использующим ASCII: начать новую строку, удалить предыдущий символ, начать передачу, остановить передачу и так далее. 32 — это пробел, а числа от 33 до 64 используются для представления диапазона неалфавитных символов, включая цифры от 0 до 9. Числа от 65 до 127 кодируют 26 строчных и 26 прописных букв английского алфавита. алфавит, с еще несколькими неалфавитными символами, зажатыми в промежутке.

Но ASCII, как следует из названия, был американским стандартом , и для большей части мира 26 строчных букв и 26 прописных букв — если выражаться британским преуменьшением — будет недостаточно. Когда европейцам нужно было обмениваться данными, включая символы с диакритическими знаками, или русским нужно было писать файлы на кириллице, или грекам на греческом, стандарт ASCII не позволял им этого делать. Но с другой стороны, ASCII использовал только семь бит из байта, кодируя числа от 0 до 127.А байт может хранить любое число от 0 до 255, оставляя 127 бесплатных кодовых точек для захвата.

Проблема, конечно, в том, что 127 кодовых точек было недостаточно для западноевропейцев, русских и греков, чтобы все кодировали все необходимые символы. Итак, как и в дни судей, все люди делали все, что им казалось правильным; каждая группа национальных языков разработала свою собственную кодировку, заглушив нужные символы в верхней половине таблицы ASCII.Внезапно снова возникли все проблемы обмена, которые должен был решить ASCII. Кто-то во Франции мог бы послать сообщение с просьбой предоставить tête-à-tête , но его российский коллега остался бы в недоумении, что бы это могло быть за tЁte-Ю-tЙte . Но ждать! Это было еще хуже: греческий пользователь ПК мог поприветствовать кого-нибудь веселым Καλημέρα, но если бы его друг использовал Mac , ему бы вместо этого захотелось ακγλίώα.

А потом появились японцы.{16} = 65536 \) разные состояния) для представления каждого символа; EUC-JP использовал переменное количество байтов, причем первый байт сообщает вам, сколько байтов в символе; ISO-2022-JP использовал магические «escape-последовательности» символов для перехода между ASCII и JIS. Файлы не всегда сообщали вам, какую кодировку они использовали, поэтому в Японии было обычным делом открывать текстовый файл и видеть экран, полный неверно закодированной тарабарщины. (По-японски «неправильно закодированная тарабарщина» — mojibake .)

Очевидно, была необходимость в новой кодировке; один с достаточно широким охватом, чтобы закодировать всех символов мира, и другой, который может объединить распространение местных «стандартов» в единый глобальный стандарт обработки информации. Эта кодировка — Юникод.

В 1984 году Международная организация по стандартизации приступила к разработке такого глобального стандарта обработки информации. Иногда вы можете услышать Unicode, называемый ISO 10646, что в некотором роде верно.В 1986 году разработчики из Apple и Xerox начали обсуждение предложенной системы кодирования, которую они назвали Unicode. Рабочая группа Unicode расширялась и развивалась параллельно с ISO 10646, а в 1991 году была официально включена в Консорциум Unicode и опубликовала Unicode 1.0. На этом этапе ISO по сути отказалась от попыток заниматься своими делами.

Это не означает, что ISO 10646 мертв. Вместо этого ISO 10646 является официальным международным стандартом определения универсального набора кодированных символов, также известного как UCS.UCS намеренно синхронизируется с отображением символа в кодовую точку, определенным в стандарте Unicode, но работа остается формально независимой. В то же время стандарт Unicode определяет больше, чем просто набор символов; он также определяет широкий спектр алгоритмов, ожидания обработки данных и другую консультативную информацию о работе с глобальными скриптами.

Глобальные скрипты в Юникоде

На момент написания стандарт Unicode был до версии 9.0, и все время кодируются новые скрипты и символы.Набор символов Unicode разделен на 17 плоскостей, каждая из которых покрывает 65536 кодовых точек, всего 1114 112 возможных кодовых точек. В настоящее время только 128 327 из этих кодовых точек имеют символы; 137 468 кодовых точек (включая все два последних самолета) зарезервированы для частного использования.

Частное использование означает, что в рамках организации, сообщества или системы вы можете использовать эти кодовые точки для кодирования любых символов, которые вы сочтете нужными. Однако персонажи частного использования не должны «ускользать» во внешний мир.Некоторые организации поддерживают реестры символов, которые они присвоили кодовым точкам частного использования; например, лингвистическое сообщество SIL закодировало 248 символов для собственного использования. Одна из них — , ЛАТИНСКАЯ БУКВА МАЛЕНЬКАЯ ЗАГЛАВНАЯ L С ПОЯСОМ, которую они закодировали в позиции U + F268. Но ничто не может помешать другой организации назначить различных символов для U + F268 в своих системах. Если выделения начинают конфликтовать, вы теряете смысл использования общего универсального набора символов.Так что используйте символы личного пользования … в частном порядке.

Большинство персонажей живут на первом плане, уровне 0, также известном как базовый многоязычный уровень. BMP сейчас довольно заполнен — ​​осталось только 128 кодовых точек, оставшихся нераспределенными, — но он охватывает почти все языки, которые используются в настоящее время. Плоскость 1 называется дополнительной многоязычной плоскостью и в основном содержит исторические сценарии, символы и эмодзи. Множество смайликов. Самолет 2 содержит расширенные иероглифы CJK (китайский, японский и корейский) с в основном редкими и историческими символами, в то время как самолеты с 3 по 13 в настоящее время полностью не распределены.Так что Unicode еще есть куда расти.

Внутри каждой плоскости Unicode выделяет каждой системе записи диапазон кодовых точек, называемый блоком . Блоки не имеют фиксированного размера и не являются исчерпывающими — как только кодовые точки выделены, их нельзя перемещать, поэтому, если добавляются новые символы из системы письма и их блок заполняется, отдельный блок где-то еще в наборе символов будет создан. Например, несколько раз добавлялись группы латинских символов.Это означает, что теперь для разных латинских символов выделено 17 блоков; один из них, Latin Extended-B, состоит из 208 кодовых точек и содержит латинские символы, такие как Ƕ (латинская заглавная буква Hwair), буквы, используемые в транскрипции пиньинь, и африканские щелчки, такие как U + 013C, ǃ — которые могут выглядеть очень похоже на восклицательный знак, но на самом деле это латинская буква кунг Retroflex Click.

Различия между ǃ (Retroflex Click) и! (восклицательный знак) иллюстрирует фундаментальный принцип Unicode: кодируйте то, что вы имеете в виду , а не то, что вы видите .Если бы мы использовали восклицательный знак для обоих целей только потому, что они были визуально идентичны, мы посеяли бы семантическую путаницу. Разделение кодовых точек сохраняет ваши данные однозначными.

Вот полный список скриптов, уже закодированных в Unicode, начиная с версии 9.0: Адлам, Ахом, анатолийские иероглифы, арабский, армянский, авестийский, балийский, бамум, Басса Вах, батак, бенгальский, бхайкуки, бопомофо, брахми, шрифт Брайля, бугинский , Бухид, канадские аборигены, карийцы, кавказские албанцы, чакма, чам, чероки, общий (то есть символы, используемые в нескольких шрифтах), коптский, клинопись, кипрский, кириллица, десерет, деванагари, дуплоян, египетские иероглифы, эльбасан, эфиопский язык, Грузинский, глаголический, готический, гранта, греческий, гуджарати, гурмукхи, хань (то есть китайские, японские и корейские идеограммы), хангыль, хануну, хатран, иврит, хирагана, императорский арамейский, начертательный пехлеви, начертательный парфянский язык, яванский язык, кайти, Каннада, Катакана, Кая Ли, Харошти, Кхмерский, Ходжи, Худавади, Лаосский, Латинский, Лепча, Лимбу, Линейное А, Линейное В, Лису, Ликийский, Лидийский, Махаджани, Малаялам, Мандайский, Манихейский, Марчен, Митей Маякуи, Менде Кикакуй , Меройский курсив, Меройские иероглифы, Мяо, M odi, монгольский, Mro, Multani, Myanmar, Nabataean, New Tai Lue, Newa, Nko, Огам, Ol Chiki, Древневенгерский, Древний курсив, Древний северный арабский язык, Старый пермик, Старый персидский язык, Древний южноаравийский язык, Древнетюркский язык, Ория, Осейдж, Османья, Пахау Хмонг, Пальмирена, Пау Цин Хау, Пхагс Па, Финикийский, Псалтырь Пехлеви, Реджанг, Рунический, Самаритянин, Саураштра, Шарада, Шавиан, Сиддхам, Знакописание, Сингальский, Сора Сомпенг, Сунданский, Силоти Нагри, Тагри , Тагбанва, Тай Ле, Тай Там, Тай Вьет, Такри, Тамильский, Тангут, Телугу, Тхана, Тайский, Тибетский, Тифинаг, Тирхута, Угаритский, Вай, Варанг Сити, Йи.

При разработке шрифтов вам очень часто нужно знать, как кодируется конкретный символ и где он находится в стандарте Unicode, то есть его кодовая точка . Например, сингальская буква аяна находится в кодовой точке 3461 (мы обычно пишем их в шестнадцатеричном формате, как 0D85). Как я это узнал? Я мог бы найти его в кодовых таблицах, но на самом деле у меня есть удобное приложение на моем компьютере под названием UnicodeChecker, которое не только помогает мне находить символы и их кодовые точки, но и сообщает мне, что стандарт Unicode говорит об этих символах, а также какие шрифты на них используются. моя система их поддерживает.Если у вас Mac, я рекомендую это; если нет, рекомендую найти что-нибудь подобное.

Что делать, если вы разрабатываете ресурсы для сценария, не закодированного в Unicode? Итак, сначала вы должны проверить, было ли это уже предложено для включения, просмотрев веб-сайт Proposed New Scripts; если нет, то вам следует обратиться в список рассылки Unicode, чтобы узнать, работает ли кто-нибудь над предложением; Затем вам следует связаться с организацией Script Encoding Initiative, которая поможет вам пройти через процесс подготовки предложения для Технического комитета Unicode.Это не быстрый процесс; некоторые скрипты в течение последних десяти лет находились на «предварительной стадии», ожидая сбора экспертных заключений по их кодированию.

Как хранятся данные

Когда компьютеры хранят данные в восьмибитных байтах, представляющих числа от 0 до 255, а ваш набор символов содержит менее 255 символов, все просто. Символ умещается в байте, поэтому каждый байт в файле представляет один символ. Одно число соответствует одной букве, и все готово.

Но когда ваш набор символов имеет потенциально 1 112 064 кодовых точки, вам нужна стратегия того, как вы собираетесь хранить эти кодовые точки в байтах по восемь бит. Эта стратегия называется кодировкой символов , и стандарт Unicode определяет три из них: UTF-8, UTF-16 и UTF-32. (UTF означает Unicode Transformation Format , потому что вы преобразуете кодовые точки в байты и наоборот.)

Существует ряд других используемых кодировок символов, которые не являются частью Стандарта, например UTF-7, UTF-EBCDIC и китайская кодировка Unicode GB18030.{32} = 4 294 967 296 \) возможных состояний, что более чем достаточно для представления каждого символа, который когда-либо может быть в Юникоде. Каждый символ представлен в виде группы из 32 бит, растянутых на четыре 8-битных байта. Чтобы закодировать кодовую точку в UTF-32, просто превратите ее в двоичный код, увеличьте до четырех байтов, и все готово.

Например, символ 🎅 (ОТЕЦ РОЖДЕСТВО) живет в Финляндии, прямо за Полярным кругом, и в стандарте Unicode, в кодовой точке 127877. В двоичном формате это 11111001110001111, которое мы можем закодировать четырьмя байтами, используя UTF-32 как следует:

Двоичный 1 11110011 10001111
С мягкой подкладкой 00000000 00000001 11110011 10001111
шестигранник 00 01 F3 85
Десятичный 0 1 243 133

Шестнадцатеричная система счисления часто используется в компьютерной работе: в то время как десятичная дробь «перекатывается» на второе место после каждых 9 (8, 9, 10, 11), шестнадцатеричная отсчитывает до пятнадцати перед тем, как перевернуться (8, 9, A, B, C, D, E, F, 10, 11).Это означает, что две шестнадцатеричные цифры могут кодировать числа от 00 до FF (или от 0 до 255 в десятичном виде), что в точности соответствует диапазону одного байта.

Есть только одна небольшая сложность: должны ли байты появляться в порядке 00 01 F3 85 или в обратном порядке 85 F3 01 00 . По умолчанию UTF-32 хранит данные «сначала большие» ( 00 01 F3 85 ), но некоторые системы предпочитают сначала помещать «малые». Они сообщают вам, что делают это, кодируя специальный символ (ZERO WIDTH NO BREAKING SPACE) в начале файла.То, как этот символ закодирован, говорит вам, как размещается остальная часть файла: если вы видите 00 00 FE FF в начале файла, мы имеем прямой порядок байтов, а если файл начинается с FF FE 00 00 , мы с прямым порядком байтов. Когда ZWNBS используется таким образом, он называется BOM (метка порядка байтов) и не интерпретируется как первый символ документа.

UTF-16

UTF-32 — очень простая и прозрачная кодировка: четыре байта — это один символ, всегда, а один символ всегда четыре байта, поэтому он часто используется как способ обработки данных Unicode внутри программы.Данные считываются в любой кодировке символов и автоматически преобразуются в UTF-32, чтобы их можно было эффективно обрабатывать. Программа делает с ней то, что ей нужно, а затем перекодирует ее, когда приходит время снова записывать данные. Многие языки программирования уже позволяют читать и записывать числа длиной четыре байта, поэтому представление кодовых точек Unicode в виде чисел не проблема. («Широкий символ» в таких языках, как C или Python, представляет собой 32-разрядный тип данных, идеально подходящий для обработки данных UTF-32.) Но UTF-32 не очень эффективен. Первый байт всегда будет нулевым, и верхние семь бит второго байта всегда будут нулевыми. Поэтому UTF-32 не часто используется в качестве формата хранения на диске: нам не нравится идея тратить почти 50% дискового пространства на байты, которые гарантированно будут пустыми.

Итак, можем ли мы найти компромисс, при котором мы используем меньше байтов, но по-прежнему представляем большинство символов, которые мы, вероятно, будем использовать, относительно простым способом? UTF-16 использует группу из 16 бит (2 байта) вместо 32, поскольку первые два байта UTF-32 почти всегда не используются.UTF-16 просто отбрасывает эти два верхних байта и вместо этого использует два байта для представления символов Юникода от 0 до 65535, символов в базовой многоязычной плоскости. Это отлично работало для большинства персонажей, которые люди могли использовать. (По крайней мере, до того, как эмодзи распространились по миру.) Если вы хотите закодировать тайскую букву в pa-tak (ฏ), которая находится в кодовой точке 3599 в стандарте Unicode, мы запишем 3599 в двоичном формате: 0000111000001111 и получите два байта 0E 0F , и это кодировка UTF-16.

С этого момента мы будем представлять кодовые точки Unicode стандартным способом: префикс U + для обозначения кодовой точки Unicode, а затем кодовую точку в шестнадцатеричном формате. Итак, для pa-tak — это U + 0E0F.

Но что, если, как в случае РОЖДЕСТВА ОТЦА, мы хотим получить доступ к кодовым точкам выше 65535? Преобразование его в двоичный дает нам число длиной три байта, и мы хотим представить все наши символы в пределах двух байтов.

Вот где приходит компромисс: чтобы упростить и эффективно представлять символы в BMP, UTF-16 отказывается от возможности легко и эффективно представлять символы за пределами этой плоскости.Вместо этого он использует механизм, называемый суррогатными парами , для кодирования символа из дополнительных плоскостей. Суррогатная пара — это 2-байтовая последовательность, которая выглядит так, как будто она должна быть допустимым символом Unicode, но на самом деле она находится из зарезервированного диапазона, который представляет переход на другую плоскость. Таким образом, UTF-16 использует 16 бит для символа внутри BMP, но две 16-битные последовательности для внешних символов; другими словами, UTF-16 — это , обычно — это кодировка с фиксированной шириной, но в определенных обстоятельствах символ может быть двух или четырехбайтовым.

Суррогатные пары работают так:

  • Сначала вычтите 0x010000 из кодовой точки, которую вы хотите кодировать. Теперь у вас есть 20-битное число.

  • Разделите 20-битное число на два 10-битных числа. Добавьте 0xD800 к первому, чтобы получить число в диапазоне 0xD800..0xDBFF . Добавьте ко второй 0xDC00 , чтобы получить число в диапазоне 0xDC00..0xDFFF . Это ваши два 16-битных кодовых блока.

Итак, для ОТЦА РОЖДЕСТВА мы начинаем с U + 1F385.

  • Уберите 0x010000 , чтобы получить F385 , или 00001111001110000101 .

  • Разделите это на 0000111100 1110000101 или 03C 385 .

  • 0xD800 + 0x03C = D83C

  • 0xDC00 + 0x385 = DF85 .

Итак, ОТЕЦ РОЖДЕСТВЕНСКИЙ в UTF-16 — это D8 3C DF 85 .

Поскольку большинство используемых символов находится в BMP, и поскольку суррогатные пары могут быть интерпретированы как кодовые точки Unicode, некоторые программы могут не беспокоиться об интерпретации обработки суррогатных пар. Хорошая новость заключается в том, что все символы смайликов живут во вспомогательной плоскости, что заставило программистов больше узнать об этой проблеме…

UTF-8

Но UTF-16 по-прежнему использует два целых байта для каждого ASCII и западноевропейского латинского символа, которые, к сожалению, являются единственными символами, которые действительно волнуют любого программиста.Так что, конечно, это никогда не годится.

UTF-8 использует компромисс, введенный UTF-16, немного дальше: символы в наборе ASCII представлены как одиночные байты, так же, как они были изначально в ASCII, в то время как кодовые точки выше 127 представлены с использованием переменного количества байтов. : кодовые точки от 0x80 до 0x7FF — это два байта, от 0x800 до 0xffff — три байта, а старшие символы — четыре байта.

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

Кодовая точка Байт 1 Байт 2 Байт 3 Байт 4
0x00-0x7F 0xxxxxxx
0x80-0x7FF 110xxxxx 10xxxxxx
0x800-0xFFFF 1110xxxx 10xxxxxx 10xxxxxx
0x10000-0x10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Первоначально UTF-8 позволял последовательностям длиной до семи байтов кодировать символы вплоть до 0x7FFFFFFF , но это было ограничено, когда UTF-8 стал стандартом Интернета, чтобы соответствовать диапазону UTF-16.Если нам нужно закодировать более миллиона символов в Unicode, UTF-8 будет недостаточно. Однако мы все еще далеки от этой ситуации.

ОТЕЦ РОЖДЕСТВА займет четыре байта, потому что он больше 0x10000 . Двоичное представление его кодовой точки U + 1F385 — 11111001110000101 , поэтому, вставляя его биты в шаблон справа, мы получаем:

0x1000-0x10FFFF 11110xxx 10x 11111 10 001110 10 000101

Наконец, заполняя нулями, получаем:

11110 000 10 011111 10 001110 10 000101
F0 9F 8E 85

UTF-8 — неплохой компромисс.Это переменная ширина, что означает больше работы для обработки, но преимуществом этого является эффективность — символы не занимают больше байтов, чем им нужно. Работа по обработке смягчается тем фактом, что начальный байт сигнализирует о длине байтовой последовательности. Начальные байты последовательности также обеспечивают однозначную точку синхронизации для программного обеспечения обработки — если вы не узнаете, где вы находитесь внутри байтового потока, просто сделайте резервную копию максимум четырех символов, пока не увидите байт, начинающийся с 0 , 110 , 1110 или 11110 и оттуда.

Из-за этого UTF-8 стал стандартом кодировки de facto в Интернете, и его используют около 90% веб-страниц. Если у вас есть данные, которые вы собираетесь формировать с помощью механизма формирования OpenType, скорее всего, они будут начинаться с UTF-8, а затем будут преобразованы в UTF-32 внутренне.

Свойства персонажа

Стандарт Unicode — это не просто набор символов и их кодовых точек. Стандарт также содержит базу данных символов Unicode, ряд файлов основных данных, содержащих информацию, необходимую компьютерам для правильной обработки этих символов.Например, основной файл базы данных UnicodeData.txt содержит свойство General_Category , которое сообщает вам, представляет ли кодовая точка букву, число, знак, знак препинания и т. Д.

Давайте выберем несколько символов и посмотрим, что о них говорит Unicode. Начнем с кода U + 0041, буквы A . Сначала, глядя в UnicodeData.txt , мы видим

  0041; ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА A; Lu; 0; L ;;;;; N ;;;; 0061;
  

После кодовой точки и официального имени мы получаем общую категорию — Lu , или «Буква в верхнем регистре».Следующее поле, 0, полезно, когда вы комбинируете и разбираете символы, которые мы рассмотрим позже. L говорит нам, что это сильный символ слева направо, что имеет решающее значение, когда мы рассмотрим двунаправленность в следующих главах. В противном случае UnicodeData.txt мало что говорит нам об этой букве — это не символ, состоящий из нескольких символов, склеенных вместе, и не число, поэтому следующие три поля остаются пустыми. N означает, что это не символ, который повторяется при повороте шрифта слева направо (как круглые скобки между английским и арабским языками.Следующие два поля больше не используются. Последние поля относятся к версиям в верхнем и нижнем регистре: в латинском есть верхний и нижний регистры, и этот символ достаточно прост, чтобы иметь единственную однозначную версию в нижнем регистре, код U + 0061. У него нет версии с заглавными буквами или заглавными буквами, потому что она уже написана заглавными буквами, да.

Что еще мы знаем об этом персонаже? Заглянув в Blocks.txt , мы можем обнаружить, что это часть диапазона 0000..007F; Базовая латиница . LineBreak.txt используется алгоритмом разрыва строки, что мы также рассмотрим в главе, посвященной макету.

  0041..005A; AL # Lu [26] ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА A..ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА Z
  

Это говорит нам о том, что верхний регистр A является буквенным символом для перевода строки. PropList.txt — это сборник разметки с информацией о свойствах Unicode, и мы найдем там две записи для нашего персонажа:

  0041..0046; Hex_Digit # L & [6] ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА A..ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА F
0041..0046; ASCII_Hex_Digit # L & [6] ЗАГЛАВНАЯ ЛАТИНСКАЯ БУКВА A..ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА F
  

Они говорят нам, что его можно использовать как шестнадцатеричную цифру, как в более расслабленном смысле, так и строго как подмножество ASCII. (U + FF21, полноразмерная версия , иногда используемая при написании латинских символов в японском тексте, является шестнадцатеричной цифрой, но не шестнадцатеричной цифрой ASCII.) CaseFolding.txt сообщает нам:

  0041; C; 0061; # ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА A
  

Если вы хотите свернуть регистр строки, содержащей A , вы должны заменить ее на код 0061 , который, как мы уже видели, ЛАТИНСКАЯ СТРОЧНАЯ БУКВА A. Наконец, в Scripts.txt мы обнаруживаем …

  0041..005А; Латинская # L & [26] ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА A..ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА Z
  

… что этот код является частью латинского алфавита.Вы знали это, но теперь знает и компьютер.

А теперь рассмотрим более интересный пример. N’ko — это шрифт, используемый для написания языков мандинка и бамбара в Западной Африке. Но если бы мы ничего об этом не знали, чему могла бы нас научить база данных символов Unicode? Давайте посмотрим на образец письма: U + 07DE NKO LETTER KA (ߞ).

Во-первых, из UnicodeData.txt :

  07DE; БУКВА NKO KA; Lo; 0; R ;;;;; N ;;;;;
  

Это говорит мне о том, что это буква «другой» — ни в верхнем, ни в нижнем регистре, а отсутствие информации о преобразовании регистра в конце подтверждает, что N’ko — это однотонный скрипт. R говорит мне, что N’ko пишется справа налево, как иврит и арабский. Согласно LineBreak.txt , это буквенный символ для разрыва строки, и в PropList.txt нет ссылки на него. Но когда мы смотрим в ArabicShaping.txt , мы обнаруживаем кое-что очень интересное:

  07DE; НКО КА; D; No_Joining_Group
  

Буква ߞ является двойным соединяющимся символом, что означает, что N’ko — это связное письмо, подобное арабскому, а буква Ka соединяется с обеих сторон.То есть в середине такого слова, как «н’ко» («я говорю»), буква выглядит так: ߒߞߏ.

Это тип данных, которые системы обработки текста могут программно извлекать из базы данных символов Unicode. Конечно, если вы действительно хотите знать, как обрабатывать текст N’ko и систему письма N’ko в целом, сам стандарт Unicode является хорошей отправной точкой: его раздел о N’ko (раздел 19.4) рассказывает вам о происхождение письма, структура, диакритическая система, пунктуация, система счисления и так далее.

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

Переделка корпуса

Мы видели, что N’Ko — это скрипт unicase; его буквы не имеют верхнего и нижнего регистра.Фактически, лишь крошечное меньшинство систем письма, таких как системы, основанные на латинском алфавите, имеют концепцию прописных и строчных версий символа. Для некоторых языковых систем, таких как английский, это довольно просто и однозначно. Каждая из 26 букв латинского алфавита, используемых в английском языке, имеет один верхний и нижний регистр. Однако в других языках, в которых используются варианты, часто есть символы, для которых нет такого простого отображения. База данных символов Юникода, и особенно файл SpecialCasing.txt , предоставляет машиночитаемую информацию о преобразовании регистра.

Классический пример — немецкий. Когда символ диез-s U + 00DF (ß) находится в верхнем регистре, он становится двумя символами «SS». Здесь явно возникает проблема с обходом, потому что, когда символы «SS» переводятся в нижний регистр, они становятся «ss», а не ß. Для большего удовольствия Unicode также определяет символ U + 1E9E, LATIN CAPITAL LETTER LETTER SHARP S (ẞ), который понижается до ß.

Во время написания этой книги Совет немецкой орфографии ( Rat für deutsche Rechtschreibung ) рекомендовал включить LATIN CAPITAL LETTER SHARP S в немецкий алфавит как заглавную версию ß, что значительно упростит работу. но лишите нас очень полезного примера трудностей преобразования регистра.

Другой классический пример — турецкий. Обычная латинская строчная буква «i» (U + 0069) обычно заглавная буква «I» (U + 0049) — за исключением случаев, когда документ написан на турецком или азербайджанском языке, когда он заглавной буквы «İ». Это связано с тем, что в этих языках используется еще одна буква, ЛАТИНСКАЯ СТРОЧНАЯ БУКВА БЕЗ ТОЧЕК I (U + 1031, ı), которая в верхнем регистре идет до «I». Таким образом, при преобразовании регистра необходимо учитывать лингвистический фон текста.

Преобразование регистра зависит не только от языка, но и от контекста.ГРЕЧЕСКАЯ ЗАГЛАВНАЯ БУКВА СИГМА (Σ) преобразуется в ГРЕЧЕСКУЮ СТРОЧНУЮ БУКВУ (σ), за исключением конца слова, в этом случае она преобразуется в ς, ГРЕЧЕСКАЯ СТРОЧНАЯ БУКВА ОКОНЧАТЕЛЬНАЯ СИГМА.

Другой пример связан с тем, что Unicode может иметь составную форму для одного случая, но не для другого. Кодовая точка U + 0390 в Юникоде занята ГРЕЧЕСКОЙ СТРОЧНОЙ БУКВОЙ ИОТА С ДИАЛИТИКОЙ И ТОНАМИ, которая выглядит так: ΐ. Но по какой-то причине Unicode никогда не кодировал соответствующую греческую заглавную букву IOTA с диалитикой и тонами.Вместо этого, когда это находится в верхнем регистре, требуются три кодовых точки: U + 0399, ГРЕЧЕСКАЯ ЗАГЛАВНАЯ БУКВА IOTA предоставляет Ι; тогда U + 3080 COMBINING DIAERESIS обеспечивает диалитику; и, наконец, U + 0301 COMBINING ACUTE ACCENT обеспечивает тонос.

Кажется, самое подходящее время поговорить об объединении символов, декомпозиции и нормализации.

Нормализация и декомпозиция

Стандарт Unicode имеет ряд заявленных проектных целей: быть универсальным в том смысле, что каждый символ в каждом сценарии, который, вероятно, будет использоваться на компьютере, имеет кодировку; быть эффективным , таким образом, чтобы алгоритмы, используемые компьютерами для ввода и вывода символов Unicode, не требовали слишком большого состояния или накладных расходов; и быть недвусмысленным , поскольку каждая кодовая точка Unicode представляет один и тот же символ.

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

Это несколько контрастирует с целью однозначности, поскольку может быть несколько разных способов сформировать персонажа. Например, рассмотрим символ n̈ (латинская строчная буква n с тремой). Он встречается в якалтекском, малагасийском, креольском языках Кабо-Верде и, прежде всего, в This Is Spın̈al Tap . Несмотря на эту очевидную известность, он не считается достаточно примечательным, чтобы его можно было закодировать в Unicode как отдельный символ, и поэтому его необходимо кодировать с использованием комбинирующих символов .

Комбинированный символ — это знак, который прикрепляется к базовому символу; другими словами, диакритический знак. Чтобы закодировать n̈, возьмем СТРОЧНУЮ ЛАТИНСКУЮ БУКВУ N (U + 006E) и последуем за ней КОМБИНИРОВАННЫМ ДИАРЕЗОМ (U + 0308). Система компоновки отвечает за организацию отображения этих двух символов как одного.

Очевидно, что это полностью соответствует цели дизайна «эффективности» — приложения, которые обрабатывают текст посимвольно, должны теперь знать, что что-то, что визуально выглядит как один символ на странице и семантически относится к одному символу в тексте, действительно создается. до двух символов в строке, исключительно как артефакт правил кодирования Unicode.Плохо написанное программное обеспечение может в конечном итоге разделить два символа и обработать их независимо, вместо того, чтобы рассматривать их как одно неделимое целое.

Теперь рассмотрим символ ṅ (латинская строчная буква n с точкой наверху). Только одна точка отличается, но это совсем другая история; он используется при транслитерации санскрита и, как таковой, был включен в кодировки до Unicode, такие как CS / CSX (Wujastyk, D., 1990, Стандартизация санскрита для электронной передачи данных и отображения на экране , 8-я Всемирная конференция по санскриту, Вена), где ему был присвоен код 239.Многие электронные версии санскритских текстов были подготовлены с использованием этого символа, поэтому, когда дело дошло до его кодирования в Юникоде, цель обратной совместимости означала, что его нужно было закодировать как отдельный символ, U + 1E45.

Но, конечно, он может быть представлен точно так же, как n̈: вы можете сформировать ṅ, вставив после ЛАТИНСКОЙ СТРОЧНОЙ БУКВЫ N (U + 006E) КОМБИНИРУЮЩУЮ ТОЧКУ ВЫШЕ (U + 0307). Два возможных способа кодирования ṅ, но только один возможный способ кодирования n̈. Вот и все, что касается «однозначного»: две строки «U + 006E U + 0307» и «U + 1E45» представляют один и тот же символ, но не равны.

Но подождите — и вы будете часто слышать это, когда дело доходит до Unicode — становится еще хуже! Знак Ом, единицы электрического сопротивления, — Ом (U + 2126 ОМ ЗНАК). Хотя фундаментальный принцип Unicode состоит в том, что символов кодируют семантику, а не визуальное представление , это явно в некотором смысле «то же самое, что и» Ω. (U + 03A9 ГРЕЧЕСКАЯ ЗАГЛАВНАЯ БУКВА ОМЕГА) Они семантически разные, но выглядят одинаково; и все же, давайте посмотрим правде в глаза, с точки зрения пользователя было бы исключительно неприятно, если бы вы искали в строке Ω, но не нашли его, потому что вместо этого строка содержала Ω.

Способ, которым Unicode решает обе эти проблемы, состоит в том, чтобы определить одну из кодировок как каноническую . Стандарт также определяет две операции: Каноническая декомпозиция и Каноническая композиция . Замена каждого символа в строке его канонической формой называется нормализацией .

Существует также «разложение совместимости» для символов, которые очень похожи, но не полностью эквивалентны: ℍ (U + 210D DOUBLE-STRUCK CAPITAL H) может быть упрощено до латинской заглавной буквы H.Но нормализации совместимости используются редко, поэтому мы не будем вдаваться в них здесь.

Самый простой способ выполнить нормализацию — это форма нормализации D или NFD. Это просто применяет каноническую декомпозицию, что означает, что каждый символ, который может быть разбит на отдельные компоненты, разбивается. Как обычно, в базе данных Unicode есть вся информация о том, как разложить символы.

Давайте снова рассмотрим наш пример с греческой прописной буквой IOTA с диалитикой и тонами, которая не кодируется напрямую в Unicode.Предположим, мы решили закодировать его как U + 0399 ГРЕЧЕСКАЯ ЗАГЛАВНАЯ БУКВА IOTA, за которой следует U + 0344 ОБЪЕДИНЕНИЕ ГРЕЧЕСКИХ ДИАЛИТИКА ТОНОС, что кажется разумным способом сделать это. Когда мы применяем каноническую декомпозицию, мы обнаруживаем, что база данных Unicode определяет декомпозицию U + 0344 — она ​​говорит нам, что объединяющая метка разбивается на два символа: U + 0308 COMBINING DIAERESIS и U + 0301 COMBINING ACUTE ACCENT.

Входная строка Ι ̈
0399 0344
NFD Ι ̈ ́
0399 0308 0301

NFD достаточно хорош для большинства применений; если вы сравниваете две строки, и они были нормализованы до NFD, то проверка равенства строк покажет вам, есть ли у вас одинаковые символы.Однако стандарт Unicode определяет еще один шаг: если вы примените каноническую композицию, чтобы вернуть символы в их предпочтительную форму, вы получите форму нормализации C. NFC — рекомендуемый способ хранения и обмена текстом. Когда мы применяем каноническую композицию к нашей струне, йота и диарезис объединяются, образуя U + 03AA ГРЕЧЕСКАЯ ЗАГЛАВНАЯ БУКВА ИОТА С ДИАЛИТИКА, и объединяющий острый акцент остается сам по себе:

Входная строка Ι ̈
0399 0344
NFD Ι ̈ ́
0399 0308 0301
NFC Ϊ ́
03AA 0301

Обратите внимание, что это совершенно другая строка, чем наш ввод, даже если она представляет тот же текст! Но процесс нормализации обеспечивает недвусмысленное представление текста, способ создания «правильной» строки, которую можно использовать при сравнении, поиске и так далее.

Функция OpenType ccmp , которую мы рассмотрим в главе 6, позволяет разработчикам шрифтов выполнять свою собственную нормализацию и упорядочивать входную последовательность глифов способами, которые имеют смысл для шрифта. Приведу два примера: во-первых, в сирийском языке есть объединяющий символ СИРИАК ПТАГА ТОЧКА (U + 0732), который состоит из точки вверху и точки внизу. При размещении этой метки относительно базового глифа часто бывает проще расположить каждую точку независимо. Таким образом, функция ccmp может разделить U + 0732 на точку вверху и точку внизу, и затем вы можете использовать правила OpenType для размещения каждой точки в соответствующем месте для базового глифа.Во-вторых, символ í (U + 00ED ЛАТИНСКАЯ СТРОЧНАЯ БУКВА I С ОСТРЫМ) используется в чешском, дакотском, ирландском и других языках. Если вы на самом деле не добавили глиф с острым ударением в свой шрифт, вам будет передана разложенная строка ЛАТИНСКАЯ СТРОЧНАЯ БУКВА I, КОМБИНИРУЮЩАЯ ОСТРЫЙ АКЦЕНТ. ЛАТИНСКАЯ СТРОЧНАЯ БУКВА I имеет точку сверху, и вы не хотите ставить комбинированный острый ударение на , а не на . ccmp позволит вам заменить «i» на «ı» без точки, прежде чем вы добавите к нему свой акцент.

ОИТ

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

Стандарт Unicode (и связанные с ним приложения к стандарту Unicode, технические стандарты Unicode и технические отчеты Unicode) определяют алгоритмы того, как обрабатывать эти вещи и многое другое: как сегментировать текст на слова и строки, как гарантировать, что и текст с письмом справа налево прекрасно работают вместе, как обрабатывать регулярные выражения и т. д. Хорошо быть знакомым с этими ресурсами, доступными на веб-сайте Unicode, чтобы вы знали, в чем заключаются проблемы, но не обязательно реализовывать их самостоятельно.

В наши дни большинство языков программирования будут иметь стандартный набор процедур, которые помогут вам в некоторой степени — по крайней мере, вы можете рассчитывать на поддержку кодировки UTF-8. В остальном проект ICU — это набор библиотек с открытым исходным кодом, поддерживаемых IBM (разумеется, с участием многих других). Проверьте, есть ли у предпочитаемого вами языка программирования расширение, которое является оболочкой для библиотеки ICU. Если это так, у вас будет доступ к хорошо протестированным и устоявшимся реализациям всех стандартных алгоритмов, используемых для обработки текста Unicode.

Основы Unicode — старое расположение руководства пользователя ICU

Введение в Unicode

Unicode — это стандарт, точно определяет набор символов, а также небольшое количество кодировки для него. Это позволяет вам обрабатывать текст на любом языке эффективно. Это позволяет одному исполняемому файлу приложения работать на глобальная аудитория. ICU, например Java ™, Microsoft® Windows NT ™, Windows ™ 2000 и других современных систем, предоставляет решения для интернационализации на основе в Юникоде.

Эта глава предназначена как введение в кодовые страницы в целом и Unicode в частности.Для получения дополнительной информации см .:

  1. Веб-сайт консорциума Unicode

  2. Что такое Юникод?

  3. IBM® Globalization

Перейти к онлайн-демонстрациям ICU чтобы увидеть, как серверное приложение на основе Unicode может обрабатывать текст на многих языках и во многих кодировках.

Традиционные наборы символов и Unicode

Представление данные в текстовом формате в компьютерах — это вопрос определения набора символов и присваивая каждому из них номер и бит представление.В основе этой базовой идеи лежат три взаимосвязанных концепции:

  1. Набор символов или репертуар — это неупорядоченный набор символов, который может быть представлен числовыми значениями.

  2. Набор кодированных символов отображает символы из набора символов или репертуара в числовые значения.

  3. Схема кодирования символов определяет представление числовые значения из одного или нескольких наборов кодированных символов в битах и ​​байтах.

Для простых кодировок, таких как ASCII, последние две концепции в основном то же самое: ASCII назначает 128 символов и управляющие коды для последовательные числа от 0 до 127.Эти символы и управляющие коды кодируются как простые беззнаковые двоичные целые числа. Следовательно, ASCII как кодированный набор символов, так и схема кодирования символов.

ASCII кодирует только 128 символов, 33 из которых являются управляющими кодами, а не графические, отображаемые символы. Он был разработан, чтобы представлять Текст на английском языке для американской базы пользователей, поэтому недостаточно для представления текста практически на любом языке, кроме Американский английский. Фактически, большинство традиционных кодировок ограничивались один или несколько языков и скриптов.

ASCII предлагается естественным путем в целях расширения: разработан в 1960-х годах для работы в системах с 7-битными байтов, в то время как большинство компьютеров и интернет-протоколов с 1970-х годов используют 8-битные байты, дополнительный бит позволял другим 128-байтовым значениям представлять больше персонажей. Были разработаны различные кодировки, поддерживающие разные языки. Некоторые из них были основаны на ASCII, другие — нет.

языков например, японский язык должен закодировать значительно больше 256 символов. Различные схемы кодирования позволяют использовать большие наборы символов с тысячами или должны быть представлены десятки тысяч символов.Большинство из них кодировки по-прежнему основаны на байтах, что означает, что многие символы требуется два или более байта дискового пространства. Должен быть разработан процесс интерпретировать некоторые байтовые значения.

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

Как правило, минимальные требования для совместимость обмена текстовыми данными заключается в том, что кодировка (набор символов & схема кодирования) должны быть правильно указаны в документе и в протоколе. Например, электронная почта / SMTP и HTML / HTTP предоставляют означает указать «кодировку», как это называется в стандартах Интернета. Однако очень часто кодировка не указывается, указывается неправильно, или отправитель и получатель не согласны с его выполнением.

Схема кодирования ISO 2022 была создана для хранения текста во многих различных языков.Это позволяет встраивать другие кодировки, предварительно объявив их, а затем переключаться между ними. Полная поддержка всех функций и возможные кодировки с ISO 2022 требуют сложной обработки и необходимость поддержки множества кодировок. Для восточноазиатских языков подмножества были разработаны, которые охватывают только один язык или несколько одновременно, но они намного более управляемы. ISO 2022 не подходит для использования в внутренняя обработка. Он предназначен для обмена данными.

Глифы и символы

Программисты часто нужно различать символы и глифы.Персонаж наименьшая смысловая единица в системе письма. Это абстрактное такое понятие, как буква А или восклицательный знак. Глиф — это визуальное представление одного или нескольких персонажей, часто зависимое на соседних символах.

Не всегда взаимно однозначное сопоставление между символами и глифами. На многих языках (арабский является основным пример), то, как выглядит персонаж, сильно зависит от окружающих символы. Стандартный печатный арабский язык имеет целых четыре различных печатные изображения (глифы) для каждой буквы алфавита.В на многих языках две или более буквы могут объединяться в одну может отображаться глиф (называемый лигатурой) или один символ с более чем одним глифом.

Несмотря на разные визуальные варианты определенной буквы, она все еще сохраняет свою идентичность. Например, Арабская буква хе имеет четыре общих визуальных представления использовать. Какой бы из них ни использовался, он по-прежнему сохраняет свою идентичность как буква хех. Именно эту идентичность кодирует Unicode, а не визуальный представление.Это также сокращает количество независимых требуются символьные значения.

Обзор Unicode

Unicode был разработан как однокодированный набор символов, который поддерживает все языки мира. Первая версия Unicode использовала 16-битную числа, что позволило закодировать 65 536 знаков без сложные многобайтовые схемы. С добавлением большего количества символов, и следуя потребностям реализации многих различных платформ, Unicode был расширен, чтобы разрешить более миллиона символов.Несколько других схемы кодирования были добавлены. Это внесло больше сложности в Стандарт Unicode, но гораздо меньше, чем управление большим количеством разные кодировки.

Начиная с Unicode 2.0 (опубликованного в 1996 году), стандарт Unicode начал назначать числа от 0 до 10ffff 16 , который требует 21 бит, но не использует их полностью. Это дает более чем достаточно места для всех письменных языков мира. В оригинальный репертуар охватывал все основные языки, обычно используемые в вычисления.Unicode продолжает расти, и он включает больше скриптов.

Дизайн Unicode несколько отличается от традиционных наборов символов и схем кодирования:

  1. Его репертуар позволяет пользователям эффективно включать текст почти на всех языках в один документ.

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

  3. Многие символы, например буквы с диакритическими знаками и умляуты, могут можно комбинировать из базового символа и модификаторов акцента или умлаута. Такое объединение уменьшает количество разных символов, которые необходимо кодироваться отдельно. «Предварительно составленные» варианты для персонажей, которые существовали в общих наборах символов в то время, были включены для совместимость.

  4. Персонажи и их использование четко определены и описаны. Пока традиционные наборы символов обычно содержат только имя или изображение символа, его номера и байтовой кодировки, Unicode имеет обширная база данных свойств, доступная для скачивания.Это также определяет ряд процессов и алгоритмов для работы со многими аспекты обработки текста, чтобы сделать его более совместимым.

Раннее включение всех символов обычно используемых наборы символов делают Unicode полезной «точкой поворота» для преобразования между традиционными наборами символов и позволяет обрабатывать текст не в Юникоде, сначала преобразовав в Юникод, обработав текст, и преобразовать его обратно в исходную кодировку без потери данных.

The первые 128 значений кодовой точки Unicode присваиваются одним и тем же символам как в US-ASCII.Например, один и тот же номер присваивается одному и тому же персонаж. То же самое верно для первых 256 значений кодовой точки Unicode по сравнению с ISO 8859-1 (Latin-1), который сам по себе является прямым надмножество US-ASCII. Это позволяет легко адаптировать многие приложения к Unicode, потому что числа для многих синтаксически важных символов одинаковые.

Формы и схемы кодирования символов для Unicode

Unicode присваивает символам номера от 0 до 10FFFF 16 , давая достаточно места для однозначного кодирования каждого характер в общем использовании.Такой символьный номер называется «кодом». точка ».

Юникод кодовые точки — это просто неотрицательные целые числа в определенном диапазоне. У них нет неявного двоичного представления или ширины 21 или 32 бита. Для кодирования определены двоичное представление и ширина единицы измерения. формы.

Для внутренней обработки стандарт определяет три формы кодирования, а для хранения файлов и протоколов некоторые из этих форм кодирования имеют схемы кодирования, различающиеся порядком байтов.Разница между формой кодирования и схемой кодирования заключается в том, что кодирование form сопоставляет коды набора символов со значениями, которые соответствуют внутренним данным типы (например, сокращение в C), в то время как схема кодирования отображается в биты и байты. Для традиционных кодировки, они одинаковы, поскольку формы кодирования уже сопоставляются с байтов

. Различные формы кодировки Unicode оптимизированы для различных целей:

  1. UTF-16, форма кодировки по умолчанию, сопоставляет точку кода символа одному или двум 16-битным целым числам.

  2. UTF-8 — это байтовая кодировка, которая предлагает обратную совместимость с основанными на ASCII байтовыми API и протоколами. А символ хранится в 1, 2, 3 или 4 байтах.

  3. UTF-32 — это простейшая, но наиболее требовательная к памяти форма кодирования: в ней используется одно 32-битное целое число на каждый символ Unicode.

  4. SCSU — это схема кодирования, которая обеспечивает простое сжатие Текст в Юникоде. Он предназначен только для ввода и вывода, а не для внутреннее использование.

ICU внутренне использует UTF-16. ICU 2.0 полностью поддерживает дополнительные символы (с кодовыми точками 10000 16 ..10FFFF 16 . Более старые версии ICU обеспечивали только частичную поддержку дополнительных символов.

Для ввод / вывод, схемы кодирования символов определяют байтовую сериализацию текст. UTF-8 сам по себе является формой кодирования и схемой кодирования. потому что он основан на байтах. Для каждого из UTF-16 и UTF-32 есть два определены варианты: тот, который сериализует единицы кода в байтах с прямым порядком байтов порядок (сначала старший байт), и тот, который сериализует код единицы в порядке байтов с прямым порядком байтов (сначала младший байт).В соответствующие схемы кодирования называются UTF-16BE, UTF-16LE, UTF-32BE, и UTF-32LE.

The имена «UTF-16» и «UTF-32» неоднозначны. В зависимости от контекста они относятся к формам кодировки символов, в которых используются 16/32-битные слова. обрабатываются и, естественно, хранятся в порядке байтов платформы, или они относятся к зарегистрированным IANA именам кодировок, т. е. к кодировке символов схемы или байтовые сериализации. Помимо простого байта сериализации, наборы символов с этими именами также используют необязательный байт Знаки заказа (см. Сериализованные форматы (§) ниже).

Обзор UTF-16

Форма кодировки по умолчанию для В стандарте Unicode используются 16-битные кодовые единицы. Значения кодовых точек для большинства общие символы находятся в диапазоне от 0 до FFFF 16 и кодируются только одной 16-битной единицей того же значения. Кодовые точки от 10000 16 до 10FFFF 16 кодируются двумя кодовыми единицами, которые часто называют «суррогатами», и их называют «суррогатной парой», когда вместе они правильно закодировать один символ Юникода.Первый суррогат в паре должен быть в диапазон от D800 16 до DBFF 16 , а второй должен находиться в диапазоне от DC00 16 до DFFF 16 . Каждая кодовая точка Unicode имеет только одну возможную кодировку UTF-16 с либо одна кодовая единица, которая не является суррогатом, либо с правильной парой суррогаты. Значения кодовых точек от D800 16 до DFFF 16 зарезервированы только для этого механизма и никогда сами по себе не будут присвоены никаким символам.

Наиболее часто используемые символы имеют кодовые точки ниже FFFF 16 , но Unicode 3.1 назначает более 40 000 дополнительных символов, которые используют суррогатные пары в UTF-16.

Примечание что лексическое сравнение строк UTF-16 на основе их 16-битного кода единиц не приводит к тому же порядку, что и сравнение кодовых точек. Обычно это не проблема, поскольку используются только редко используемые символы. затронутый. Большинство процессов не полагаются на одни и те же результаты в таких сравнения. При необходимости простая модификация строки сравнение может быть выполнено, что по-прежнему позволяет эффективно использовать кодовые единицы на основе сравнений и делает их совместимыми со сравнениями кодовых точек.ICU для этого есть функции C и C ++ API.

Обзор UTF-8

Кому соответствуют требованиям систем на основе байтов и ASCII, Стандарт Unicode определяет UTF-8. UTF-8 — это байтовый формат переменной длины. кодировка, сохраняющая прозрачность ASCII.

UTF-8 поддерживает прозрачность для всех значений кода ASCII (0..127). Эти ценности делают не появляется ни в одном байте преобразованного результата, кроме как в прямом представление значений ASCII. Таким образом, текст ASCII также является текстом UTF-8.

Характеристики UTF-8 включают:

  1. Кодовые точки Unicode от 0 до 7F 16 кодируются одним байтом одного и того же значения. Следовательно, ASCII символы занимают на 50% меньше места в кодировке UTF-8, чем в UTF-16.

  2. Все остальные кодовые точки закодированы многобайтовыми последовательностями, с первый байт (ведущий байт), указывающий количество следующих за ним байтов (байты следа). Это приводит к очень эффективному синтаксическому анализу. Ведущие байты находятся в диапазоне от c0 16 до fd 16 , байты следа находятся в диапазоне от 80 16 до bf 16 .Значения байтов fe 16 и FF 16 никогда не используются.

  3. UTF-8 относительно компактен и экономичен в использовании байтов, необходимых для кодирования текста в европейских сценариях, но использует На 50% больше места, чем UTF-16, для текста из Восточной Азии. Кодовые точки до 7FF 16 занимают два байта, кодовые точки до FFFF 16 занимают три (на 50% больше памяти, чем UTF-16), а все остальные четыре.

  4. Двоичное сравнение строк UTF-8 на основе их байтов приводит к тому же порядку, что и сравнение значений кодовой точки.

Обзор UTF-32

В кодировке UTF-32 всегда используется одно 32-битное целое число для каждой кодовой точки Unicode. Это приводит к очень простой кодировке.

недостатком является потребление памяти: поскольку значения кодовой точки используют только 21 бит, одна треть памяти всегда не используется, а поскольку чаще всего используемые символы имеют значения кодовой точки до FFFF 16 , они занимают только одну 16-битную единицу в UTF-16 (на 50% меньше) и до трех байтов в UTF-8 (на 25% меньше).

UTF-32 в основном используется в API, которые определены с тем же типом данных для как кодовые точки, так и кодовые единицы. Современные версии стандарта C библиотека, поддерживающая Unicode, использует 32-битный wchar_t с UTF-32 семантика.

Обзор SCSU

SCSU (Стандартный Схема сжатия для Unicode) предназначена для уменьшения размера Текст Unicode для ввода и вывода. Это простое сжатие, которое преобразует текст в поток байтов. Обычно он использует один байт на символ в маленьких шрифтах и ​​два байта на символ в больших, Восток Азиатские шрифты.

Обычно он короче любого из UTF. Однако SCSU сохраняет состояние, что делает его непригодным для внутреннего использования. обработка. Он также использует все возможные байтовые значения, которые могут потребовать дополнительная обработка для таких протоколов, как SMTP (электронная почта).

См. Также http://www.unicode.org/unicode/reports/tr6/ .

Другие кодировки Unicode

Другие кодировки Unicode разрабатывались с течением времени для различных целей. Большинство из них реализовано в ICU, см. Source / data / mappings / convrtrs.текст

  1. BOCU-1: двоичное сжатие Unicode
    An кодирование Unicode, которое примерно так же компактно, как SCSU, но имеет много меньшее количество гос. В отличие от SCSU, он сохраняет порядок кодовых точек и может использоваться в 8-битных письмах без кодировки передачи. BOCU-1 не , а не сохраняет символы ASCII в ASCII-читаемой форме. См. Техническое примечание Unicode №6. .

  2. UTF-7: предназначен для 7-битных писем; простой и не очень компактный. Поскольку почтовые системы были 8-битными безопасными в течение нескольких лет, UTF-7 больше не нужно и не рекомендуется.Большинство символов ASCII читаемые, другие кодируются в формате base64. См. RFC 2152 .

  3. IMAP-mailbox-name: Вариант UTF-7, который подходит для выражения строк Unicode как символов ASCII для имен файлов Unix.
    Имя «IMAP-mailbox-name» специфично для ICU!
    См. RFC 2060 ПРОТОКОЛ ДОСТУПА К ИНТЕРНЕТ-СООБЩЕНИЯМ — ВЕРСИЯ 4rev1 раздел 5.1.3. Международное соглашение об именах почтовых ящиков.

  4. UTF-EBCDIC: удобная для EBCDIC кодировка, аналогичная UTF-8.См. Технический отчет Unicode №16. . Начиная с ICU 2.6, UTF-EBCDIC не реализован в ICU.

  5. CESU-8: схема кодирования совместимости для UTF-16: 8-бит
    An несовместимый вариант UTF-8, который сохраняет 16-битный Unicode (UTF-16) порядок строк вместо порядка кодовых точек. Не для открытого обмена. Видеть Технический отчет Unicode № 26 .

Программирование с использованием UTF

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

В каждой форме кодировки Unicode значения кодовых единиц для синглтонов (кодовые единицы, которые только кодируют символов), ведущие подразделения и конечные подразделения не связаны. Это имеет решающее значение для реализации. Следующие списки эти значения:

  1. Определяет количество единиц для одна кодовая точка с использованием ведущего блока. Это особенно важно для UTF-8, где может быть до 4 байтов на символ.

  2. Определяет границы.Если пользователи ICU получают произвольный доступ к тексту, вы всегда можно определить ближайшие границы кодовой точки с небольшим количество машинных инструкций.

  3. Не имеет перекрытий. Если пользователи ICU ищут строку A в строка B, вы никогда не получите ложного совпадения по кодовым точкам. Пользователям не нужны преобразовать в кодовые точки для поиска по строкам. Ложных совпадений никогда происходит, поскольку конец одной последовательности никогда не совпадает с началом другая последовательность. Перекрытие — одна из самых больших проблем с общими многобайтовые кодировки типа Shift-JIS.Все UTF этого избегают проблема.

  4. Использует простую итерацию. Получение следующей или предыдущей кодовой точки прост и требует небольшого количества машин инструкции.

  5. Может использовать кодировку UTF-16, которая фактически полностью симметрична. ICU пользователи могут определить по любой единичной кодовой единице, является ли она первой, последний или только один для кодовой точки. Перемещение (итерация) в любом направление через текст UTF-16 одинаково быстро и эффективно.

  6. Использует медленную индексацию по кодовым точкам.Эта процедура индексации недостаток всех кодировок переменной ширины. За исключением UTF-32, это неэффективно находить границы кодовой единицы, соответствующие n-му коду point или найти смещение кодовой точки, содержащее n-ю кодовую единицу. Оба включают сканирование с начала текста или с последнего известного граница. ICU, как и большинство распространенных API, всегда индексирует по единицам кода. Это подсчитывает кодовые единицы, а не кодовые точки.

Преобразование между различными UTF выполняется очень быстро. В отличие от преобразование в устаревшие кодировки, такие как Latin-2, преобразование между UTF не требует просмотра таблицы.

ICU обеспечивает два определения основных типов данных для Unicode. UChar32 — это 32-битный тип для кодовые точки и используются для одиночных символов Юникода. Это может быть подписано или без знака. Это то же самое, что и wchar_t, если его ширина составляет 32 бита. UChar — это 16-разрядное целое число без знака для кодовых единиц UTF-16. Это базовый тип для строк (UChar *), и это то же самое, что и wchar_t, если это 16 бит широкий.

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

Сериализованные форматы

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

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

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

Символ ZERO WIDTH NO-BREAK SPACE (FEFF 16 ) может использоваться как подпись, добавляя ее к файлу или потоку. В альтернативная функция U + FEFF в качестве символа управления форматом была скопировано в U + 2060 WORD JOINER, а U + FEFF следует использовать только для Подписи Unicode.

Различные схемы кодирования символов генерируют разные последовательности байтов для U + FEFF:

  1. UTF-8: EF BB BF

  2. UTF-16BE: FE FF

  3. UTF-16LE: FF FE

  4. UTF-32BE: 00 00 FE FF

  5. UTF-32LE: FF FE 00 00

  6. SCSU: 0E FE FF

  7. BOCU-1: FB EE 28

  8. UTF-7 : 2B 2F 76 (38 | 39 | 2B | 2F)

  9. UTF-EBCDIC: DD 73 66 73

ICU предоставляет функцию ucnv_detectUnicodeSignature () для обнаружения подписи Unicode.

Есть нет подписи для CESU-8, отдельной от подписи для UTF-8. UTF-8 и CESU-8 кодирует U + FEFF и фактически все кодовые точки BMP с одинаковым байтов. Возможность ошибочной идентификации одного как другого — одна причин, по которым CESU-8 следует использовать только в ограниченных, закрытых, определенные среды.

В UTF-16 и UTF-32, где подпись также различает порядок байтов с прямым порядком байтов и прямым порядком байтов, он также называется байтовым знак заказа (BOM).Подпись работает для UTF-16, так как кодовая точка который имеет кодировку с заменой байтов, FFFE 16 , никогда не будет допустимый символ Юникода. (Это «несимвольный» код.) В Интернет-протоколы, если спецификация кодировки «UTF-16» или Используется «UTF-32», предполагается наличие байта подписи последовательность (BOM), которая определяет порядок байтов, что не так для имен схемы / кодировки кодирования с «BE» или «LE».

Если текст указывается для кодировки в кодировке UTF-16 или UTF-32 и не начинается с спецификации, тогда его следует интерпретировать как UTF-16BE или UTF-32BE соответственно.

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

Если подпись была обнаружена, то «символ» подписи U + FEFF должен быть удален из потока Unicode после конверсия. Удаление байтов подписи перед преобразованием может вызвать преобразование не выполняется для кодировок с отслеживанием состояния, таких как BOCU-1 и UTF-7.

Распознавать подпись или нет, зависит от протокола или приложения.

  1. Если протокол указывает имя набора символов, тогда поток байтов должен быть интерпретируется в соответствии с определением этого имени. Только «UTF-16» и имена «UTF-32» включают распознавание меток порядка байтов, которые специфичны для них (и преобразователи ICU для этих имен делают это автоматически). Ни одна из других кодировок Unicode не определена для включать любую обработку подписи / спецификации.

  2. Если имя кодировки не указано, например, для текстовых файлов в большинство файловых систем, то приложения обычно должны полагаться на эвристику, чтобы определить кодировку файла.Многие форматы документов содержат встроенные или неявное объявление кодировки, но для текстовых файлов это разумно использовать подписи Unicode в качестве простой и надежной эвристики. Это особенно часто встречается в системах Windows. Однако некоторые инструменты для обработка обычного текстового файла (например, многие инструменты командной строки Unix) не подготовлен для подписей Unicode.

Стандарт Unicode является отраслевым стандартом

Стандарт Unicode является отраслевым стандартом и аналогичен ISO 10646-1.Примерно в 1993 году эти два стандарта были объединены в один и тот же стандартный набор символов. Оба стандарта имеют одинаковый характер репертуар и одинаковые формы и схемы кодирования.

Одно отличие заключалось в том, что стандарт ISO определял значения кодовой точки от 0 до 7FFFFFFF 16 , а не только до 10FFFF 16 . Рабочая группа ISO решила добавить поправку к стандарту. В поправка устраняет эту разницу, объявляя, что никакие символы не будут когда-либо были назначены кодовые точки выше 10FFFF 16 .Главная причина для рабочей группы ISO решение — это совместимость между UTF. UTF-16 не может кодировать какие-либо кодовые точки выше этого предела.

Это означает, что пространство кодовых точек для Unicode и ISO 10646 теперь одинаково! Эти изменения в ISO 10646 были внесены недавно и должны быть внесены в издание ISO 10646: 2003, которое также объединяет все части стандарт в один.

Прежнее, большее пространство кода — это причина, по которой определение ISO для UTF-8 определяет последовательности из пяти и шесть байтов, чтобы покрыть весь этот диапазон.

Еще одно отличие состоит в том, что стандарт ISO определяет формы кодирования «UCS-4» и «UCS-2». UCS-4 — это по существу UTF-32 с теоретическим верхним пределом 7FFFFFFF 16 , используя 31 из 32 бит. Однако на практике комитет ISO принял, что символы выше 10FFFF не будут кодироваться, поэтому по существу нет разницы между формами. Стенды «4» для «четырехбайтовой формы».

UCS-2 — это подмножество UTF-16, которое ограничено в кодовые точки от 0 до FFFF, исключая суррогатные кодовые точки.Таким образом, он не может представлять символы с кодовыми точками выше FFFF. (называемые дополнительными символами).

Преобразование между UCS-2 и UTF-16 не требуется. Разница только в трактовке суррогатов.

Стандарты различаются по типу информации, которую они предоставляют: Стандарт Unicode предоставляет больше свойств символов и описывает алгоритмы и т. д., в то время как стандарт ISO определяет коллекции, подмножества и тому подобное.

Стандарты синхронизируются, и соответствующие комитеты работают вместе, чтобы добавить новые символы и присвоить значения кодовых точек.

Безболезненное руководство — Настоящий Python

Обработка кодировок символов в Python или любом другом языке временами может показаться болезненной. В таких местах, как Stack Overflow, есть тысячи вопросов, возникающих из-за путаницы с исключениями, такими как UnicodeDecodeError и UnicodeEncodeError . Это руководство предназначено для устранения тумана Exception и демонстрации того, что работа с текстовыми и двоичными данными в Python 3 может быть удобной.Поддержка Unicode в Python сильна и надежна, но для ее освоения требуется время.

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

К концу этого руководства вы будете:

  • Получите концептуальные обзоры кодировок символов и систем нумерации
  • Поймите, как кодирование вступает в игру с помощью Python str и байтов
  • Знать о поддержке в Python систем нумерации с помощью различных форм int литералов
  • Ознакомиться со встроенными функциями Python, связанными с кодировками символов и системами нумерации.

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

Примечание : Эта статья ориентирована на Python 3. В частности, все примеры кода в этом руководстве были сгенерированы из оболочки CPython 3.7.2, хотя все второстепенные версии Python 3 должны вести себя (в основном) одинаково при обработке текста.

Если вы все еще используете Python 2 и вас пугают различия в том, как Python 2 и Python 3 обрабатывают текстовые и двоичные данные, то, надеюсь, это руководство поможет вам сделать переход.

Что такое кодировка символов?

Существуют десятки, если не сотни кодировок символов.Лучший способ понять, что это такое, — рассмотреть одну из простейших кодировок символов — ASCII.

Независимо от того, являетесь ли вы самоучкой или имеете формальное образование в области информатики, скорее всего, вы видели таблицу ASCII один или два раза. ASCII — хорошее место для начала изучения кодировки символов, потому что это небольшая и ограниченная кодировка. (Как оказалось, слишком мало.)

Включает:

  • Строчные английские буквы : a от до z
  • Заглавные английские буквы : A от до Z
  • Некоторые знаки препинания и символы : "$" и "!" , чтобы назвать пару
  • Пробельные символы : фактический пробел ( "" ), а также новая строка, возврат каретки, горизонтальная табуляция, вертикальная табуляция и некоторые другие
  • Некоторые непечатаемые символы : символы, такие как backspace, "\ b" , которые нельзя напечатать буквально так, как буква A может

Итак, какое более формальное определение кодировки символов?

На очень высоком уровне это способ преобразования символов (таких как буквы, знаки препинания, символы, пробелы и управляющие символы) в целые числа и, в конечном итоге, в биты.Каждый символ может быть закодирован в уникальную последовательность битов. Не волнуйтесь, если вы не уверены в концепции битов, потому что мы скоро к ним вернемся.

Различные выделенные категории представляют собой группы персонажей. Каждому одиночному символу соответствует кодовая точка , которую можно представить как целое число. В таблице ASCII символы разбиты на разные диапазоны:

Диапазон кодовой точки Класс
от 0 до 31 Контрольные / непечатаемые символы
от 32 до 64 Пунктуация, символы, числа и пробел
65-90 Прописные буквы английского алфавита
91–96 Дополнительные графемы, например [ и \
97–122 Строчные буквы английского алфавита
от 123 до 126 Дополнительные графемы, например { и |
127 Управляющий / непечатаемый символ ( DEL )

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

Кодовая точка Персонаж (Имя) Кодовая точка Персонаж (Имя)
0 NUL (Нулевой) 64 @
1 SOH (начало заголовка) 65 А
2 STX (начало текста) 66 Б
3 ETX (конец текста) 67 К
4 EOT (конец передачи) 68 Д
5 ENQ (Запрос) 69 E
6 ACK (подтверждение) 70 Факс
7 BEL (Звонок) 71 г
8 BS (Backspace) 72 H
9 HT (горизонтальный выступ) 73 I
10 LF (перевод строки) 74 Дж
11 VT (вертикальный выступ) 75 К
12 FF (подача формы) 76 л
13 CR (возврат каретки) 77 м
14 SO (сдвиг) 78 N
15 SI (сдвиг внутрь) 79 О
16 DLE (выход из канала передачи данных) 80 П
17 DC1 (Управление устройством 1) 81 Q
18 DC2 (Управление устройством 2) 82 R
19 DC3 (Управление устройством 3) 83 S
20 DC4 (Управление устройством 4) 84 т
21 NAK (отрицательное подтверждение) 85 U
22 SYN (синхронный холостой ход) 86 В
23 ETB (конец блока передачи) 87 Вт
24 CAN (Отмена) 88 Х
25 EM (конец среднего) 89 Y
26 SUB (Заменитель) 90 Z
27 ESC (выход) 91 [
28 FS (разделитель файлов) 92 \
29 GS (Разделитель групп) 93 ]
30 RS (Разделитель записей) 94 ^
31 США (разделитель единиц) 95 _
32 СП (Космос) 96 `
33 ! 97 а
34 " 98 б
35 # 99 с
36 $ 100 д
37 % 101 e
38 и 102 f
39 ' 103 г
40 ( 104 ч
41 ) 105 i
42 * 106 j
43 + 107 к
44 , 108 л
45 109 кв.м
46 . 110 n
47 / 111 или
48 0 112 п
49 1 113 кв
50 2 114 р
51 3 115 с
52 4 116 т
53 5 117 u
54 6 118 в
55 7 119 w
56 8 120 x
57 9 121 л
58 : 122 z
59 ; 123 {
60 < 124 |
61 = 125 }
62 > 126 ~
63 ? 127 DEL (удалить)

Строка

Модуль Модуль

Python string - это удобный универсальный инструмент для строковых констант, которые попадают в набор символов ASCII._` {|} ~ "" " printable = цифры + ascii_letters + знаки препинания + пробел

Большинство этих констант должны самодокументироваться в своих именах идентификаторов. Вскоре мы рассмотрим, что такое шестнадцатеричных цифр и восьмицифровых цифр .

Эти константы можно использовать для повседневных операций со строками:

>>>
  >>> импортная строка

>>> s = "Что не так с ASCII?!?!?"
>>> s.rstrip (строка. пунктуация)
"Что не так с ASCII"
  

Примечание : строка .printable включает в себя все string.whitespace . Это немного не согласуется с другим методом проверки того, считается ли символ пригодным для печати, а именно str.isprintable () , который сообщит вам, что ни один из {'\ v', '\ n', '\ r', '\ f ',' \ t '} считаются пригодными для печати.

Тонкое различие связано с определением: str.isprintable () считает что-то печатаемым, если «все его символы считаются печатаемыми в repr () .”

Немного освежить

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

Бит — это сигнал, который имеет только два возможных состояния. Есть разные способы символического представления бита, которые означают одно и то же:

  • 0 или 1
  • «да» или «нет»
  • Верно или Ложно
  • «включено» или «выключено»

Наша таблица ASCII из предыдущего раздела использует то, что мы с вами называем просто числами (от 0 до 127), но более точно называемые числами с основанием 10 (десятичными).

Вы также можете выразить каждое из этих чисел с основанием 10 последовательностью битов (основание 2). Вот двоичные версии от 0 до 10 в десятичном виде:

Десятичный Двоичный (компактный) Двоичный (заполненная форма)
0 0 00000000
1 1 00000001
2 10 00000010
3 11 00000011
4 100 00000100
5 101 00000101
6 110 00000110
7 111 00000111
8 1000 00001000
9 1001 00001001
10 1010 00001010

Обратите внимание, что по мере увеличения десятичного числа n вам потребуется больше значащих битов для представления набора символов, включая это число.

Вот удобный способ представления строк ASCII как последовательности битов в Python. Каждый символ из строки ASCII получает псевдокодирование в 8 бит с пробелами между 8-битными последовательностями, каждая из которых представляет один символ:

>>>
  >>> def make_bitseq (s: str) -> str:
... если не s.isascii ():
... поднять ValueError ("Допускается только ASCII")
... return "" .join (f "{ord (i): 08b}" для i в s)

>>> make_bitseq ("биты")
'01100010 01101001 01110100 01110011'

>>> make_bitseq ("ЗАГЛАВКИ")
'01000011 01000001 01010000 01010011'

>>> make_bitseq ("25 долларов.43 ")
'00100100 00110010 00110101 00101110 00110100 00110011'

>>> make_bitseq ("~ 5")
'01111110 00110101'
  

Примечание : .isascii () был введен в Python 3.7.

Строка f f "{ord (i): 08b}" использует мини-язык спецификации формата Python, который является способом указания форматирования для полей замены в строках формата:

  • Левая часть двоеточия, ord (i) , представляет собой фактический объект, значение которого будет отформатировано и вставлено в вывод.Использование функции Python ord () дает вам кодовую точку base-10 для одного символа str .

  • Правая часть двоеточия — это спецификатор формата. 08 означает шириной 8, 0 с дополнением , а b функционирует как знак для вывода результирующего числа с основанием 2 (двоичное).

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

Нам нужно больше бит!

Есть критически важная формула, связанная с определением бита. Учитывая количество битов, n , количество различных возможных значений, которые могут быть представлены в n битах, равно 2 n :

  def n_possible_values ​​(nbits: int) -> int:
    вернуть 2 ** нбит
  

Вот что это значит:

  • 1 бит позволит вам выразить 2 1 == 2 возможных значений.
  • 8 бит позволят вам выразить 2 8 == 256 возможных значений.
  • 64 бита позволят вам выразить 2 64 == 18,446,744,073,709,551,616 возможных значений.

Из этой формулы следует следствие: учитывая диапазон различных возможных значений, как мы можем найти количество битов, n , которое требуется для полного представления диапазона? Вы пытаетесь найти n в уравнении 2 n = x (где вы уже знаете x ).

Вот что из этого получается:

>>>
  >>> из математического импорта ceil, log

>>> def n_bits_required (nvalues: int) -> int:
... вернуть ceil (log (nvalues) / log (2))

>>> n_bits_required (256)
8
  

Причина, по которой вам нужно использовать потолок в n_bits_required () , состоит в том, чтобы учесть значения, которые не являются чистыми степенями 2. Скажем, вам нужно сохранить набор символов из 110 символов. Наивно, это должно занять log (110) / log (2) == 6.781 бит, но нет такого понятия, как 0,781 бит. 110 значений потребуют 7 бит, а не 6, при этом последние слоты не нужны:

>>>
  >>> n_bits_required (110)
7
  

Все это служит доказательством одной концепции: ASCII, строго говоря, является 7-битным кодом. Таблица ASCII, которую вы видели выше, содержит 128 кодовых точек и символов, от 0 до 127 включительно. Для этого требуется 7 бит:

>>>
  >>> n_bits_required (128) # от 0 до 127
7
>>> n_possible_values ​​(7)
128
  

Проблема в том, что современные компьютеры почти ничего не хранят в 7-битных слотах.Они передают данные в единицах по 8 бит, обычно известных как байт .

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

Это означает, что дисковое пространство, используемое ASCII, наполовину пусто. Если неясно, почему это так, вспомните приведенную выше таблицу преобразования десятичных чисел в двоичные. Вы можете выразить числа 0 и 1 всего одним битом, или вы можете использовать 8 битов, чтобы выразить их как 00000000 и 00000001, соответственно.

Вы, , можете выразить числа от 0 до 3 всего с 2 битами или от 00 до 11, или вы можете использовать 8 битов, чтобы выразить их как 00000000, 00000001, 00000010 и 00000011, соответственно. Самая высокая кодовая точка ASCII, 127, требует только 7 значащих битов.

Зная это, вы можете видеть, что make_bitseq () преобразует строки ASCII в представление байтов str , где каждый символ занимает один байт:

>>>
  >>> make_bitseq ("биты")
'01100010 01101001 01110100 01110011'
  
Недостаточное использование

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

Эти разные кодировки не только конфликтовали друг с другом, но и каждая из них сама по себе оставалась крайне неполным представлением персонажей мира, несмотря на то, что в них использовался один дополнительный бит.

Спустя годы одна мега-схема кодирования символов стала управлять всеми ими. Однако, прежде чем мы перейдем к делу, давайте поговорим на минутку о системах нумерации, которые являются фундаментальной основой схем кодирования символов.

Покрытие всех баз: другие системы счисления

При обсуждении ASCII выше вы видели, что каждый символ отображается на целое число в диапазоне от 0 до 127.

Этот диапазон чисел выражается в десятичной системе счисления (основание 10). Это способ, которым вы, я и остальные из нас, людей, привыкли считать, и нет более сложной причины, чем то, что у нас 10 пальцев.

Но есть и другие системы нумерации, которые особенно распространены в исходном коде CPython. Хотя «базовое число» одно и то же, все системы нумерации — это просто разные способы выражения одного и того же числа.

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

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

  • Двоичный : базовый 2
  • Восьмеричное : основание 8
  • Шестнадцатеричное (шестнадцатеричное) : основание 16

Но что для нас означает утверждение, что в определенной системе счисления числа представлены в базе N ?

Вот лучший из известных мне способов сформулировать, что это означает: это количество пальцев, на которые вы рассчитываете в этой системе.

Если вам нужно гораздо более полное, но все же мягкое введение в системы счисления, то книга Чарльза Петцольда Code — невероятно крутая книга, в которой подробно исследуются основы компьютерного кода.

Один из способов продемонстрировать, как разные системы нумерации интерпретируют одно и то же, — использовать конструктор Python int () . Если вы передадите str в int () , Python по умолчанию будет считать, что строка выражает число в базе 10, если вы не укажете иное:

>>>
  >>> int ('11 ')
11
>>> int ('11 ', base = 10) # 10 уже по умолчанию
11
>>> int ('11 ', base = 2) # Двоичный
3
>>> int ('11 ', base = 8) # Восьмеричный
9
>>> int ('11 ', base = 16) # Шестнадцатеричный
17
  

Существует более распространенный способ сообщить Python, что ваше целое число набрано с основанием, отличным от 10.Python принимает буквальных форм каждой из трех альтернативных систем нумерации, указанных выше:

Тип литерала Префикс Пример
н / д н / д 11
Двоичный литерал 0b или 0B 0b11
Восьмеричный литерал 0o или 0O 0o11
Шестнадцатеричный литерал 0x или 0X 0x11

Все это подформы целочисленных литералов .Вы можете видеть, что они дают те же результаты, что и вызовы int () с нестандартными базовыми значениями . Все они всего лишь от до Python:

>>>
  >>> 11
11
>>> 0b11 # Двоичный литерал
3
>>> 0o11 # Восьмеричный литерал
9
>>> 0x11 # шестнадцатеричный литерал
17
  

Вот как вы можете ввести двоичный, восьмеричный и шестнадцатеричный эквиваленты десятичных чисел от 0 до 20. Любой из них совершенно допустим в оболочке интерпретатора Python или в исходном коде, и все они имеют тип int :

Десятичный двоичный восьмеричный шестигранник
0 0b0 0o0 0x0
1 0b1 0o1 0x1
2 0b10 0o2 0x2
3 0b11 0o3 0x3
4 0b100 0o4 0x4
5 0b101 0o5 0x5
6 0b110 0o6 0x6
7 0b111 0o7 0x7
8 0b1000 0o10 0x8
9 0b1001 0o11 0x9
10 0b1010 0o12 0xa
11 0b1011 0o13 0xb
12 0b1100 0o14 0xc
13 0b1101 0o15 0xd
14 0b1110 0o16 0xe
15 0b1111 0o17 0xf
16 0b10000 0o20 0x10
17 0b10001 0o21 0x11
18 0b10010 0o22 0x12
19 0b10011 0o23 0x13
20 0b10100 0o24 0x14

Удивительно, насколько распространены эти выражения в стандартной библиотеке Python.Если вы хотите в этом убедиться, перейдите туда, где находится ваш каталог lib / python3.7 / , и проверьте использование шестнадцатеричных литералов, например:

  $ grep -nri --include "* \. Py" -e "\ b0x" lib / python3.7
  

Это должно работать в любой системе Unix, имеющей grep . Вы можете использовать «\ b0o» для поиска восьмеричных литералов или «\ b0b» для поиска двоичных литералов.

Каков аргумент в пользу использования этих альтернативных синтаксисов литералов int ? Короче говоря, это потому, что 2, 8 и 16 — это степени двойки, а 10 — нет.Эти три альтернативные системы счисления иногда предлагают способ выражения значений в удобной для компьютера манере. Например, число 65536 или 2 16 — это всего лишь 10000 в шестнадцатеричном формате или 0x10000 в шестнадцатеричном формате Python.

Введите Unicode

Как вы видели, проблема с ASCII заключается в том, что это недостаточно большой набор символов, чтобы вместить мировой набор языков, диалектов, символов и глифов. (Он даже не достаточно велик для одного английского.)

Unicode в основном служит той же цели, что и ASCII, но он просто охватывает в некотором смысле способ большего набора кодовых точек. Есть несколько кодировок, которые возникли в хронологическом порядке между ASCII и Unicode, но на самом деле о них пока не стоит упоминать, потому что Unicode и одна из его схем кодирования, UTF-8, стали широко использоваться.

Думайте о Юникоде как об огромной версии таблицы ASCII, имеющей 1114 112 возможных кодовых точек. Это от 0 до 1,114,111 или от 0 до 17 * (2 16 ) — 1 или 0x10ffff в шестнадцатеричном формате.Фактически, ASCII — идеальное подмножество Unicode. Первые 128 символов в таблице Unicode в точности соответствуют символам ASCII, которые, как вы разумно ожидали, от них будут.

Для обеспечения технической точности, Unicode сам по себе является , а не кодировкой . Скорее, Unicode — это , реализованный с помощью различных кодировок символов, которые вы скоро увидите. Unicode лучше рассматривать как карту (что-то вроде dict ) или таблицу базы данных с двумя столбцами.Он отображает символы (например, "a" , "" или даже "ቈ" ) в различные положительные целые числа. Кодировка символов должна предлагать немного больше.

Unicode содержит практически все символы, которые вы можете себе представить, включая дополнительные непечатаемые. Один из моих любимых — надоедливый знак письма справа налево, который имеет кодовую точку 8207 и используется в тексте с языковыми алфавитами как слева направо, так и справа налево, например в статьях, содержащих абзацы на английском и арабском языках. .

Примечание: Мир кодировок символов — одна из многих мелких технических деталей, над которыми некоторые люди любят придираться. Одна из таких деталей заключается в том, что фактически можно использовать только 1111998 кодовых точек Unicode по нескольким архаичным причинам.

Unicode против UTF-8

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

Вы также видели выше, что Unicode технически не является полноценной кодировкой символов. Это почему?

Есть одна вещь, о которой Unicode не говорит вам: он не говорит вам, как получить фактические биты из текста — только кодовые точки. В нем недостаточно информации о том, как преобразовать текст в двоичные данные и наоборот.

Unicode — это абстрактный стандарт кодирования, а не кодирование. Вот где в игру вступают UTF-8 и другие схемы кодирования. Стандарт Unicode (карта символов для кодовых точек) определяет несколько различных кодировок из своего единственного набора символов.

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

Это подводит нас к давно назревшему определению. Что означает формально кодировать и декодировать ?

Кодирование и декодирование в Python 3

Тип

Python 3 str предназначен для представления удобочитаемого текста и может содержать любой символ Юникода.

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

Кодирование и декодирование — это процесс перехода от одного к другому:

Кодирование и декодирование (Изображение: Real Python)

В .encode () и .decode () параметр кодировки по умолчанию равен «utf-8» , хотя, как правило, более безопасно и однозначно указать это:

>>>
  >>> "резюме".кодировать ("utf-8")
b'r \ xc3 \ xa9sum \ xc3 \ xa9 '
>>> "Эль-Ниньо" .encode ("utf-8")
b'El Ni \ xc3 \ xb1o '

>>> b "r \ xc3 \ xa9sum \ xc3 \ xa9" .decode ("utf-8")
'продолжить'
>>> b "Эль-Нинь \ xc3 \ xb1o" .decode ("utf-8")
'Эль-Ниньо'
  

Результатом str.encode () является -байтовый объект . Оба байтовых литерала (например, b "r \ xc3 \ xa9sum \ xc3 \ xa9" ) и представления байтов допускают только символы ASCII.

Вот почему при вызове «Эль-Ниньо».encode ("utf-8") , ASCII-совместимый "El" может быть представлен как есть, но n с тильдой заменяется на "\ xc3 \ xb1" . Эта запутанная последовательность представляет собой два байта, 0xc3 и 0xb1 в шестнадцатеричном формате:

>>>
  >>> "" .join (f "{i: 08b}" для i в (0xc3, 0xb1))
'11000011 10110001'
  

То есть для символа - требуется два байта для его двоичного представления в UTF-8.

Примечание : Если вы наберете help (str.encode) , вы, вероятно, увидите значение по умолчанию encoding = 'utf-8' . Будьте осторожны, исключая это и просто используйте "резюме" .encode () , потому что значение по умолчанию может быть другим в Windows до Python 3.6.

Python 3: все на Unicode

Python 3 полностью использует Unicode и UTF-8. Вот что это значит:

  • Исходный код Python 3 по умолчанию считается UTF-8.Это означает, что вам не нужна кодировка # - * -: UTF-8 - * - в верхней части файлов .py в Python 3.

  • Весь текст ( str ) по умолчанию — Unicode. Закодированный текст Unicode представлен в виде двоичных данных ( байт, ). Тип str может содержать любой буквальный символ Unicode, например «Δv / Δt» , и все они будут сохранены как Unicode.

  • Python 3 принимает множество кодовых точек Unicode в идентификаторах, что означает résumé = "~ / Documents / resume.pdf " действителен, если это вам нравится.

  • Модуль

    Python re по умолчанию использует флаг re.UNICODE , а не re.ASCII . Это означает, например, что r "\ w" соответствует символам слова Unicode, а не только буквам ASCII.

  • По умолчанию кодирует в str.encode () и байт. Decode () — это UTF-8.

Есть еще одно свойство, которое является более тонким: кодировка по умолчанию для встроенной open () зависит от платформы и значения локали .getpreferredencoding () :

>>>
  >>> # Mac OS X High Sierra
>>> импортировать локаль
>>> locale.getpreferredencoding ()
'UTF-8'

>>> # Windows Server 2012; другие сборки Windows могут использовать UTF-16
>>> импортировать локаль
>>> locale.getpreferredencoding ()
'cp1252'
  

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

Один байт, два байта, три байта, четыре

Важнейшей особенностью является то, что UTF-8 представляет собой кодировку переменной длины . Заманчиво замалчивать, что это означает, но стоит вникнуть в это.

Вернитесь к разделу, посвященному ASCII. Все в расширенной области ASCII требует не более одного байта пространства. Вы можете быстро доказать это с помощью следующего выражения генератора:

>>>
  >>> all (len (chr (i) .encode ("ascii")) == 1 для i в диапазоне (128))
Истинный
  

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

>>>
  >>> ibrow = "🤨"
>>> len (ibrow)
1
>>> ibrow.encode ("utf-8")
б '\ xf0 \ x9f \ xa4 \ xa8'
>>> len (ibrow.encode ("utf-8"))
4

>>> # Calling list () для байтового объекта дает вам
>>> # десятичное значение для каждого байта
>>> список (b '\ xf0 \ x9f \ xa4 \ xa8')
[240, 159, 164, 168]
  

Это тонкая, но важная особенность len () :

  • Длина одного символа Unicode в виде Python str будет всегда равной 1, независимо от того, сколько байтов он занимает.
  • Длина одного и того же символа, закодированного в байтов , будет находиться в диапазоне от 1 до 4.

В таблице ниже приведены общие типы символов, которые помещаются в каждый сегмент длины в байтах:

Десятичный диапазон Hex Диапазон Что включено Примеры
0 до 127 "\ u0000" до "\ u007F" США ASCII "A" , "\ n" , "7" , "&"
128 до 2047 "\ u0080" до "\ u07FF" Большинство латинских алфавитов * "ę" , "±" , "" , "ñ"
2048 до 65535 "\ u0800" до "\ uFFFF" Дополнительные части многоязычного самолета (БМП) ** "" , "" , "" , "‰"
65536 до 1114111 "\ U00010000" до "\ U0010FFFF" Другое *** "" , "𐀀" , "" , "🂲" ,

* Например, английский, арабский, греческий и ирландский
** Огромный набор языков и символов — в основном китайский, японский и корейский по объему (также ASCII и латинские алфавиты)
*** Дополнительный китайский , Японские, корейские и вьетнамские символы, а также другие символы и смайлы

Примечание : Чтобы не упустить из виду общую картину, существует дополнительный набор технических функций UTF-8, которые здесь не рассматриваются, поскольку они редко видны пользователю Python.

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

В статье

Wikipedia, посвященной UTF-8, не обойтись без технических подробностей, и всегда существует официальный стандарт Unicode, который поможет вам при чтении.

А как насчет UTF-16 и UTF-32?

Вернемся к двум другим вариантам кодировки, UTF-16 и UTF-32.

На практике разница между ними и UTF-8 существенна. Вот пример того, насколько велика разница при двустороннем преобразовании:

>>>
  >>> letter = "αβγδ"
>>> rawdata = letter.encode ("utf-8")
>>> rawdata.decode ("utf-8")
'αβγδ'
>>> rawdata.decode ("utf-16") # 😧
'뇎닎 돎듎'
  

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

Совершенно неверные результаты, подобные этому, возможны, если одна и та же кодировка не используется в двух направлениях. Два варианта декодирования одного и того же объекта байтов байтов могут дать результаты, которые даже не на одном языке.

В этой таблице указаны диапазон или количество байтов в UTF-8, UTF-16 и UTF-32:

Кодировка байт на символ (включительно) переменной длины
UTF-8 с 1 по 4 Есть
UTF-16 от 2 до 4 Есть
UTF-32 4 Нет

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

>>>
  >>> text = "記者 鄭啟源 羅智堅"
>>> len (text.encode ("utf-8"))
26
>>> len (text.encode ("utf-16"))
22
  

Причина этого в том, что кодовые точки в диапазоне от U + 0800 до U + FFFF (от 2048 до 65535 в десятичной форме) занимают три байта в UTF-8 по сравнению с двумя в UTF-16.

Я ни в коем случае не рекомендую вам садиться в поезд UTF-16, независимо от того, работаете ли вы на языке, символы которого обычно находятся в этом диапазоне.Среди прочего, одним из веских аргументов в пользу использования UTF-8 является то, что в мире кодирования отличная идея - сливаться с толпой.

Не говоря уже о том, что это 2019 год: память компьютера дешевая, поэтому экономия 4 байтов за счет использования UTF-16, вероятно, не стоит того.

Встроенные функции Python

Вы прошли через трудную часть. Пришло время использовать то, что вы уже видели в Python.

Python имеет группу встроенных функций, которые так или иначе связаны с системами нумерации и кодировкой символов:

Их можно логически сгруппировать в зависимости от их назначения:

  • ascii () , bin () , hex () и oct () предназначены для получения другого представления ввода.Каждый производит str . Первый, ascii () , создает представление объекта только в формате ASCII с экранированными символами, отличными от ASCII. Остальные три дают двоичное, шестнадцатеричное и восьмеричное представление целого числа соответственно. Это всего лишь представлений , а не фундаментальное изменение ввода.

  • байтов () , str () и int () являются конструкторами классов для своих соответствующих типов, байтов , str и int .Каждый из них предлагает способы принуждения ввода к желаемому типу. Например, как вы видели ранее, хотя int (11.0) , вероятно, более распространен, вы также можете увидеть int ('11 ', base = 16) .

  • ord () и chr () являются инверсиями друг друга в том смысле, что функция Python ord () преобразует символ str в его кодовую точку base-10, а chr () делает противоположный.

Вот более подробный взгляд на каждую из этих девяти функций:

Функция Подпись принимает Тип возврата Назначение
ascii () ascii (obj) Варьируется ул. Только ASCII-представление объекта с экранированными символами, отличными от ASCII
бин () бин (номер) номер: внутренний ул. Двоичное представление целого числа с префиксом «0b»
байт () байтов (iterable_of_ints)

байтов (s, enc [, errors])

байтов (bytes_or_buffer)

байтов ([i])

Варьируется байтов Преобразование входных данных в байтов , сырые двоичные данные
chr () chr (i) i: int

i> = 0

i <= 1114111

ул. Преобразование целочисленной кодовой точки в один символ Юникода
шестигранник () шестнадцатеричный (номер) номер: внутренний ул. Шестнадцатеричное представление целого числа с префиксом «0x»
внутр () int ([x])

int (x, base = 10)

Варьируется внутренний Coerce (преобразовать) вход в int
окт () окт (номер) номер: внутренний ул. Восьмеричное представление целого числа с префиксом «0o»
порядковый номер () орд (в) c: str

len (c) == 1

внутренний Преобразование одиночного символа Юникода в его целочисленную кодовую точку
ул. () str (object = ’‘)

str (b [, enc [, errors]])

Варьируется ул. Привести (преобразовать) ввод к str , текст

Вы можете развернуть раздел ниже, чтобы увидеть несколько примеров каждой функции.

ascii () дает представление объекта только в формате ASCII с экранированными символами, отличными от ASCII:

>>>
  >>> ascii ("abcdefg")
"'abcdefg'"

>>> ascii ("халепеньо")
"'Джалепе \\ xf1o'"

>>> ascii ((1, 2, 3))
'(1, 2, 3)'

>>> ascii (0xc0ffee) # Шестнадцатеричный литерал (int)
"12648430"
  

bin () дает двоичное представление целого числа с префиксом «0b» :

>>>
  >>> корзина (0)
'0b0'

>>> корзина (400)
'0b110010000'

>>> bin (0xc0ffee) # Шестнадцатеричный литерал (int)
'0b110000001111111111101110'

>>> [bin (i) for i in [1, 2, 4, 8, 16]] # `int` + понимание списка
['0b1', '0b10', '0b100', '0b1000', '0b10000']
  

байтов () приводит входные данные к байтам , представляя необработанные двоичные данные:

>>>
  >>> # Итерация целых чисел
>>> байты ((104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100))
привет мир

>>> bytes (range (97, 123)) # Итерация целых чисел
b'abcdefghijklmnopqrstuvwxyz '

>>> bytes ("real 🐍", "utf-8") # Строка + кодировка
б'реал \ xf0 \ x9f \ x90 \ x8d '

>>> байтов (10)
б '\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00'

>>> байтов.fromhex ('c0 ff ee')
б '\ xc0 \ xff \ xee'

>>> bytes.fromhex ("72 65 61 6c 70 79 74 68 6f 6e")
b 'альпифон'
  

chr () преобразует целочисленную кодовую точку в один символ Unicode:

>>>
  >>> chr (97)
'а'

>>> chr (7048)
'ᮈ'

>>> chr (1114111)
'\ U0010ffff'

>>> chr (0x10FFFF) # Шестнадцатеричный литерал (int)
'\ U0010ffff'

>>> chr (0b01100100) # Двоичный литерал (int)
'd'
  

hex () дает шестнадцатеричное представление целого числа с префиксом «0x» :

>>>
  >>> шестнадцатеричный (100)
'0x64'

>>> [hex (i) для i в [1, 2, 4, 8, 16]]
['0x1', '0x2', '0x4', '0x8', '0x10']

>>> [hex (i) для i в диапазоне (16)]
['0x0', '0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7',
 '0x8', '0x9', '0xa', '0xb', '0xc', '0xd', '0xe', '0xf']
  

int () приводит к вводу int , опционально интерпретируя ввод в заданной базе:

>>>
  >>> int (11.0)
11

>>> int ('11 ')
11

>>> int ('11 ', основание = 2)
3

>>> int ('11 ', основание = 8)
9

>>> int ('11 ', основание = 16)
17

>>> int (0xc0ffee - 1.0)
12648429

>>> int.from_bytes (b "\ x0f", "маленький")
15

>>> int.from_bytes (b '\ xc0 \ xff \ xee', "большой")
12648430
  

Функция Python ord () преобразует один символ Юникода в его целочисленный код:

>>>
  >>> ord ("а")
97

>>> ord ("ę")
281

>>> ord ("ᮈ")
7048

>>> [ord (i) вместо i в "привет, мир"]
[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
  

str () приводит к вводу str , представляя текст:

>>>
  >>> str ("строка строки")
'строка строки'

>>> str (5)
'5'

>>> str ([1, 2, 3, 4]) # Как [1, 2, 3, 4].__str __ (), но используйте str ()
'[1, 2, 3, 4]'

>>> str (b "\ xc2 \ xbc чашка муки", "utf-8")
Стакана муки

>>> str (0xc0ffee)
"12648430"
  

Строковые литералы Python: способы снять шкуру с кошки

Вместо использования конструктора str () принято вводить str буквально:

>>>
  >>> еда = "креветки и крупа"
  

Это может показаться достаточно простым. Но интересная сторона дела заключается в том, что, поскольку Python 3 полностью ориентирован на Unicode, вы можете «набирать» символы Unicode, которые вы, вероятно, даже не найдете на своей клавиатуре.Вы можете скопировать и вставить это прямо в оболочку интерпретатора Python 3:

>>>
  >>> алфавит = 'αβγδεζηθικλμνξοπρςστυφχψ'
>>> печать (алфавит)
αβγδεζηθικλμνξοπρςστυφχψ
  

Помимо размещения фактических, неэкранированных символов Unicode в консоли, есть и другие способы ввода строк Unicode.

Один из самых плотных разделов документации Python - это раздел, посвященный лексическому анализу, в частности раздел, посвященный строковым и байтовым литералам.Лично мне пришлось прочитать этот раздел один, два или, может быть, девять раз, чтобы он действительно проникся.

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

Первый и самый распространенный способ - буквально набрать сам символ, как вы уже видели. Сложная часть этого метода - это нахождение фактических нажатий клавиш. Вот где в игру вступают другие методы получения и представления персонажей. Вот полный список:

Последовательность побега Значение Как выразить "а"
"\ ooo" Знак с восьмеричным числом ооо "\ 141"
"\ xhh" Символ с шестнадцатеричным значением hh "\ x61"
"\ N {name}" Символ с именем имя в базе данных Unicode "\ N {СТРОЧНАЯ ЛАТИНСКАЯ БУКВА A}"
"\ uxxxx" Символ с 16-битным (2-байтовым) шестнадцатеричным значением xxxx "\ u0061"
"\ Uxxxxxxxx" Символ с 32-битным (4-байтовым) шестнадцатеричным значением xxxxxxxx "\ U00000061"

Вот некоторые доказательства и подтверждения вышеизложенного:

>>>
  >>> (
... "а" ==
... "\ x61" ==
... "\ N {СТРОЧНАЯ ЛАТИНСКАЯ БУКВА A}" ==
... "\ u0061" ==
... "\ U00000061"
...)
Истинный
  

Теперь есть два основных предостережения:

  1. Не все эти формы подходят для всех персонажей. Шестнадцатеричное представление целого числа 300 - 0x012c , что просто не подходит для 2-значного escape-кода "\ xhh" . Наивысшая кодовая точка, которую вы можете втиснуть в эту escape-последовательность, - "\ xff" ( "ÿ" ).Аналогично для "\ ooo" , он будет работать только до "\ 777" ( "ǿ" ).

  2. Для \ xhh , \ uxxxx и \ Uxxxxxxxx требуется ровно столько цифр, сколько показано в этих примерах. Это может вызвать зацикливание из-за того, что таблицы Unicode обычно отображают коды для символов с ведущим U + и переменным количеством шестнадцатеричных символов. Ключевым моментом является то, что таблицы Unicode чаще всего не заполняют эти коды нулями.

Например, если вы обратитесь на unicode-table.com за информацией о готической букве faihu (или fehu), "𐍆" , вы увидите, что она указана как имеющая код U + 10346 .

Как поместить это в "\ uxxxx" или "\ Uxxxxxxxx" ? Ну, вы не можете поместить его в "\ uxxxx" , потому что это 4-байтовый символ, и чтобы использовать "\ Uxxxxxxxx" для представления этого символа, вам нужно будет ввести последовательность слева:

>>>
  >>> "\ U00010346"
'𐍆'
  

Это также означает, что форма "\ Uxxxxxxxx" является единственной escape-последовательностью, которая может содержать любой символ Unicode.

Примечание : Вот короткая функция для преобразования строк, которые выглядят как «U + 10346» , в нечто, с чем может работать Python. Он использует str.zfill () :

>>>
  >>> def make_uchr (код: str):
... return chr (int (code.lstrip ("U +"). zfill (8), 16))
>>> make_uchr ("U + 10346")
'𐍆'
>>> make_uchr ("U + 0026")
'&'
  

Другие кодировки, доступные в Python

На данный момент вы видели четыре кодировки символов:

  1. ASCII
  2. UTF-8
  3. UTF-16
  4. UTF-32

Есть масса других.

Одним из примеров является Latin-1 (также называемый ISO-8859-1), который технически является значением по умолчанию для протокола передачи гипертекста (HTTP) согласно RFC 2616. Windows имеет свой собственный вариант Latin-1, называемый cp1252.

Примечание : ISO-8859-1 все еще широко распространен. Библиотека запросов следует RFC 2616 «в буквальном смысле» в использовании ее в качестве кодировки по умолчанию для содержимого ответа HTTP или HTTPS. Если слово «текст» находится в заголовке Content-Type и не указана другая кодировка, тогда запросов будет использовать ISO-8859-1.

Полный список принятых кодировок скрыт в документации модуля кодеков , который является частью стандартной библиотеки Python.

Есть еще одна полезная распознаваемая кодировка, о которой следует знать, это "unicode-escape" . Если у вас есть декодированный str и вы хотите быстро получить представление его экранированного литерала Unicode, вы можете указать эту кодировку в .encode () :

>>>
  >>> alef = chr (1575) # Или "\ u0627"
>>> alef_hamza = chr (1571) # Или "\ u0623"
>>> алеф, алеф_хамза
('ا', 'أ')
>>> алеф.кодировать ("unicode-escape")
б '\\ u0627'
>>> alef_hamza.encode ("unicode-escape")
б '\\ u0623'
  

Вы знаете, что говорят о предположениях…

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

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

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

Вот пример того, где что-то может пойти не так. Вы подписаны на API, который отправляет вам рецепт дня, который вы получаете в байтах и всегда без проблем декодировали с помощью .decode ("utf-8") . В этот день часть рецепта выглядит так:

>>>
  >>> data = b "\ xbc чашка муки"
  

Похоже, рецепт требует немного муки, но мы не знаем, сколько:

>>>
  >>> данные.декодировать ("utf-8")
Отслеживание (последний вызов последний):
  Файл "", строка 1, в 
UnicodeDecodeError: кодек utf-8 не может декодировать байт 0xbc в позиции 0: недопустимый начальный байт
  

Эээ . Есть эта надоедливая UnicodeDecodeError , которая может укусить вас, когда вы делаете предположения о кодировании. Вы уточняете у хоста API. И вот, данные на самом деле отправляются в кодировке Latin-1:

. >>>
  >>> data.decode ("латиница-1")
Стакана муки
  

Ну вот.В Latin-1 каждый символ помещается в один байт, тогда как символ «¼» занимает два байта в UTF-8 ( "\ xc2 \ xbc" ).

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

Если вам действительно нужно отказаться от поставки и угадать кодировку, взгляните на библиотеку chardet , которая использует методологию Mozilla, чтобы сделать обоснованное предположение о неоднозначно закодированном тексте.Тем не менее, такой инструмент, как chardet , должен быть вашим последним средством, а не первым.

Шансы и окончания:

unicodedata

Было бы упущением не упомянуть unicodedata из стандартной библиотеки Python, которая позволяет вам взаимодействовать и выполнять поиск в базе данных символов Unicode (UCD):

>>>
  >>> импортировать unicodedata

>>> unicodedata.name ("€")
«ЗНАК ЕВРО»
>>> unicodedata.lookup («ЗНАК ЕВРО»)
'€'
  

Заключение

В этой статье вы раскрыли обширную и впечатляющую тему кодировки символов в Python.

Здесь вы много узнали:

  • Основные понятия кодировок символов и систем нумерации
  • Целочисленные, двоичные, восьмеричные, шестнадцатеричные, строковые и байтовые литералы в Python
  • Встроенные функции Python, связанные с системами кодирования и нумерации символов
  • Обработка текста в Python 3 по сравнению с двоичными данными

Теперь идите и закодируйте!

Ресурсы

Чтобы получить более подробную информацию о затронутых здесь темах, посетите эти ресурсы:

В документации Python есть две страницы по теме:

Что такое UTF-8? - Twilio

UTF-8 - это стандарт кодировки символов переменной ширины, который использует от одного до четырех восьмибитных байтов для представления всех допустимых кодовых точек Unicode.21), более чем достаточно для покрытия текущих 1112 064 кодовых точек Unicode.

Вместо символов на самом деле правильнее ссылаться на кодовых точек при обсуждении систем кодирования. Кодовые точки позволяют абстрагироваться от символа термина и являются элементарной единицей хранения информации при кодировании. Большинство кодовых точек представляют собой один символ, но некоторые представляют такую ​​информацию, как форматирование.

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

Обратная совместимость с ASCII

UTF-8 использует один байт для представления кодовых точек от 0 до 127. Эти первые 128 кодовых точек Unicode взаимно однозначно соответствуют отображению символов ASCII, поэтому символы ASCII также являются допустимыми символами UTF-8.

Как работает UTF-8: пример

Первый байт UTF-8 указывает, сколько байтов будет следовать за ним.Затем биты кодовой точки «распределяются» по следующим байтам. Лучше всего это пояснить на примере:

Unicode присваивает французскую букву é кодовой точке U + 00E9. Это 11101001 в двоичном формате; он не является частью набора символов ASCII. UTF-8 представляет это восьмибитное число с использованием двух байтов.

Старшие биты обоих байтов содержат метаданные. Первый байт начинается с 110 . Единицы указывают, что это двухбайтовая последовательность, а 0 указывает, что за ней последуют биты кодовой точки.Второй байт начинается с 10, чтобы указать, что это продолжение последовательности UTF-8.

Это оставляет 11 «слотов» для битов кодовой точки. Помните, что для кодовой точки U + 00E9 требуется всего восемь бит. UTF-8 дополняет ведущие биты тремя значениями 0 , чтобы полностью «заполнить» оставшиеся пробелы.

Результирующее представление UTF-8 для é (U + 00E9): 1100001110101001 .

Как Twilio обрабатывает символы UTF-8?

UTF-8 является доминирующей кодировкой во всемирной паутине, поэтому ваш код, скорее всего, закодирован с использованием этого стандарта.

Для SMS-сообщений Twilio использует самый компактный из доступных методов кодирования. Twilio по умолчанию использует GSM-7 и возвращается к UCS-2, если ваше сообщение содержит символы, отличные от GSM-7. Использование стандартов кодирования GSM-7 и UCS-2 может повлиять на количество сегментов, необходимых для отправки вашего сообщения.

Twilio Copilot Smart Encoding автоматически обнаруживает символы Юникода, которые легко пропустить, такие как умные кавычки (〞) или длинное тире (-), и заменяет их аналогичным символом. Благодаря этому количество сегментов сообщения и цены будут как можно более низкими.

Не беспокойтесь, если ваша строка в кодировке UTF-8 "Ooh làlà" будет доставлена ​​по SMS - Программируемое SMS-сообщение Twilio поможет вам.

Учебник по кодированию | Даниэль Мисслер

Мы все сталкивались с различными типами кодировки символов при использовании Интернета. Некоторые из них включают ASCII, ANSI, Latin-1, ISO 8859-1, Unicode, UTF-7, UTF-8, UCS-2, URL-кодирование и т. Д. Их много, и для многих это очень сложно. чтобы помнить о различиях между этими стандартами и о том, когда использовать один или один из них.другой.

Итак, давайте это исправим. Постоянно. Здесь, сейчас, на одной странице.

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

Лучший способ быстро понять основы кодирования символов - это начать с того, как появился ASCII.

  1. Когда разрабатывались UNIX и C, нуждались только в безударных Английские символы . Таким образом, ASCII был создан таким образом, чтобы все английское (и непечатаемые вещи, такие как пробелы и переводы строк) могли уместиться в 127 местах, что заняло всего 7 бит (0-127).
  2. Но поскольку компьютеры использовали 8-битные байты, различных правительств и групп начал придумывать что делать с остальными 128 местами (128-255). Проблема в том, что они не договорились, что с ними делать, и начался хаос.В результате документы, отправленные из системы в систему, часто не могли быть прочитаны, потому что они использовали разные стандарты характера.
  3. Наконец, были созданы системы IBM (OEM) и ANSI (Microsoft), которые определили кодовые страницы, состоящие из ASCII для нижних 127 символов и затем заданный языковой вариант для первых 128 символов. Таким образом, кодовые страницы 437 (IBM), 737 (греческий), 862 (турецкий) и т. Д. Состояли из 256 символов каждая, с ASCII в качестве первых 127, а затем на соответствующем языке для остальных 128.Сюда любой, кто использует одну и ту же кодовую страницу, сможет обмениваться документами, не имея своего контент искажен.

Эта система горячей замены кодовых страниц хромала, пока Интернет не подключил всех и не доказал a) 8 бит недостаточно, и b) обмен текстом между системами по всему миру станет нормой, а не исключение. Это привело к фундаментальному сдвигу в способах кодирования. Это приводит нас к следующему:

Полезно думать о методах кодирования как о делении на две основные категории - старый способ и новый способ.

  1. Старый образ: каждый персонаж имеет конкретное и прямое представление на компьютере.
  2. Новый путь: каждый персонаж представляет собой концепцию и может быть представлен различными способами .

Старый путь

Как уже упоминалось, ASCII является одним из первых типов кодирование, и он использует старый способ. Другими словами, символы ASCII хранятся в памяти в фиксированном количестве бит - постоянно, каждый раз. Таким образом, код ASCII «D» всегда выглядит на компьютере так:

0100 0100

… который равен 68 в десятичном формате, 44 в шестнадцатеричном и т. Д.Проблема с этим подходом в том, что он не масштабируется. 8 бит содержат только 256 комбинаций, и хотя английский язык состоит только из 26 символов (52 для заглавных букв), вам все равно нужно добавлять символы, числа, непечатаемые символы и т. Д. И это всего лишь английский. Как только вы начнете добавлять все остальные языки, многие из которых используют символы с диакритическими знаками и другие специальные типы символов, 256 становится очень низким числом.

Новый путь

Более новое и лучшее решение - вообще не отображать символы напрямую, а вместо этого отображать их на очень конкретный концептуальный объект , который затем может быть описан компьютером несколькими способами (с использованием большего количества бит / байтов по мере необходимости).Это то, что делает Unicode - он отображает каждую букву каждого языка в уникальный номер (называемый кодовой точкой), поэтому «D» в верхнем регистре в Unicode соответствует:

U + 0044

Это всегда case (извините) независимо от используемого шрифта. Одно понятие (буква) на одну кодовую точку. Таким образом, «D» в верхнем регистре всегда означает U + 0044 , а «d» в нижнем регистре - это не просто «D» , которое выглядит иначе - это совершенно другой объект со своим собственным номером (U +0064).Цифры после u + всегда в шестнадцатеричном формате. Итак, теперь, когда у вас есть набор отдельных чисел (кодовых точек) для символов, вы можете решить, как обрабатывать их с помощью компьютера. Это часть кодирования, которую мы рассмотрим ниже в разделе стандартов.

Ключевое различие между старым и новым способом состоит в том, что старый способ сочетал сами символы с тем, как они были представлены на компьютере, тогда как новая система разделяет эти части.

Так, например, в ASCII буква « D » всегда 7 бит, как и любая другая английская буква, но в Юникоде буква « D » - это просто идея , которая может быть представлена ​​на компьютер различными способами.

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

Примечание о «обычном тексте»

Прежде чем продолжить, мы должны обратиться к концепции «простого текста». «Обычный текст» - неправильное название; его на самом деле не существует.Говорить о «обычном» тексте применительно к компьютеру - это все равно, что пойти в супермаркет и попросить «обычную» еду или попросить человека, говорящего на 200 языках, говорить «нормально». Короче говоря, все слова «обычный», «нормальный» и «простой» субъективны, а компьютеры не любят субъективного.


Объявления электронной почты и веб-кодирования (соответственно)

Единственный способ описать, как что-то кодируется на компьютере, - это указать ему, какой стандарт использовать. Период. Всегда явно определяйте кодировку в своих документах; это значительно сократит количество неожиданных результатов, которые вы испытаете.

Ниже я даю некоторую информацию об общих стандартах кодировки символов. Я сделаю это в повторяющемся формате, охватывающем историю, характеристики и любые ссылки на стандарт.

ASCII (Американский стандартный код для обмена информацией)

История: ASCII - одна из первых компьютеризированных систем символов в мире (после EBCDIC). Первоначально это была только английская система символов без акцента, которая использовалась еще при создании языка программирования C и операционных систем UNIX.

Характеристики: Это 7-битная система (0-127). Символы от 0 до 31 не печатаются, а от 32 до 127 - это стандартные символы, которые люди часто ошибочно называют «обычным текстом».

Ссылка: стандарт ASCII (wikipedia.org), таблица ASCII.

Расширенный ASCII

История: Расширенный ASCII - это что-то вроде неофициального имени. На самом деле это просто относится к тому, как различные группы обрабатывают верхние 128 символов сверх общепринятого ASCII.Таким образом, любая система, совместимая с ASCII для первых 0–127 символов, но имеющая большее количество символов выше, считается «расширенной» ASCII.

Характеристики: Опять же, на самом деле нет четкого определения того, что такое «расширенный» ASCII, поскольку это своего рода неправильное употребление. Любая символьная система с содержанием от 128 до 256 в дополнение к 0–127 считается реализацией расширенного ASCII. К ним относятся как кодовые страницы, так и Unicode.

Ссылка: Extended ASCII (wikipedia.org)

Кодовые страницы IBM

История: IBM Code Pages (также называемые OEM-кодовыми страницами) были созданы IBM как решение для всех, кто использовал неиспользуемый 8-й бит в ASCII для своих собственные цели и вызывающие недоумение.Они создали набор сопоставлений кода, который включал стандартный ASCII в качестве нижних 128 символов, но затем различные языки в верхних 128, например. Греческий, турецкий, иврит и т. Д. Кодовая страница IBM 437 - это исходный набор символов для IBM PC.

Характеристики: кодовые страницы содержат полные 256 символов, доступных из 8-битной системы, и включают согласованный ASCII в нижних 127 (с некоторыми случайными изменениями), а затем верхние 128 зависят от языка, как указано название.Так, например, кодовая страница IBM 869 - это греческий язык в верхней половине и ASCII в нижней половине, что в сумме составляет 256 символов.

Ссылка: Справочник по кодовым страницам IBM (ibm.com)

Кодовые страницы ANSI

История: Кодовые страницы ANSI представляют собой наборы символов, очень похожие на кодовые страницы IBM, но использовавшиеся в операционных системах Microsoft. Название «ANSI» интересно, поскольку оно подразумевает, что сопоставления стандартизированы ANSI, но это не так. Название появилось потому, что кодовая страница ANSI 1252 предположительно была основана на проекте, представленном в ANSI, но до сих пор ANSI не сделал ни один из стандартов «ANSI» официальными.Так что их лучше всего воспринимать как стандарты Microsoft.

Характеристики: Кодовые страницы ANSI, как и их аналоги от IBM, содержат полные 256 символов, доступные из 8-битной системы, и включают согласованный ASCII в нижних 127 (с некоторыми случайными вариациями), а затем в верхних 128 различаются в зависимости от на языке, как указано в названии. Так, кодовая страница ANSI 1256, например, арабская в верхней половине и ASCII в нижней половине, что в сумме составляет 256 символов.

Ссылка: Кодовые страницы ANSI (wikipedia.org)

Unicode

История: Unicode - результат титанических усилий по созданию единой системы отображения (и кодирования) кода, которая могла бы использоваться повсеместно во всем мире. Он был разработан для замены кодовых страниц, которые представляют собой различные языковые сопоставления символов по 256 символов каждая. Первая версия Unicode была запущена в 1988 году, ее создали представители Xerox и Apple.

Характеристики: как описано в разделе концепций (я рекомендую прочитать его в первую очередь), важно понимать, что Unicode отделяет отображение символов от кодировки символов.Что касается отображения, Unicode сопоставляет практически каждую букву или символ на каждом языке с уникальной кодовой точкой, каждая из которых описывается буквой U +, за которой следуют четыре шестнадцатеричных символа, например заглавная английская буква «D» представлена ​​как U + 0044. Таким образом Unicode определяет 1,114,112 (2 20 +2 16 ) отдельных кодовых точек.

UTF-8/16/32

Что касается кодирования, Unicode имеет множество способов преобразования этих кодовых точек в фактические биты и байты на компьютере; они называются форматами преобразования Unicode (UTF).Вы, несомненно, встречали UTF-8 в своих путешествиях, и это один из вариантов. Но UTF-8 - не единственный способ закодировать заглавную букву «D» (U + 0044) в Unicode. Вот таблица, в которой показаны некоторые альтернативы:


unicode.org

Приведенная выше диаграмма раскрывает еще одно заблуждение относительно Unicode: цифра 8 в UTF-8 не указывает, сколько битов кодируется в кодовой точке. Окончательный размер закодированных данных зависит от двух факторов: a) размера кодовой единицы и b) количества используемых кодовых единиц.Таким образом, 8 в UTF-8 обозначает размер кодовой единицы , а не количество битов, которые будут использоваться для кодирования кодовой точки.


unicode.org


Изображение с: http://www.cl.cam.ac.uk/~mgk25/unicode.html

Итак, теперь мы видим, что UTF-8 может фактически хранить кодовую точку, используя между один и четыре байта. Я считаю полезным рассматривать размер единицы кода как «уровень детализации» или «размер строительного блока», который у вас есть. Таким образом, с UTF-16 у вас все еще может быть максимум четыре байта, но размер вашей кодовой единицы составляет 16 бит, поэтому ваше минимальное количество байтов равно двум.

В качестве примера различных способов кодирования одного и того же контента по-разному, вот диаграмма, которая показывает различные способы кодирования английской заглавной буквы «D» без ударения.


fileformat.info

Ссылка: Стандарт Unicode, FAQ по Unicode

Кодирование UCS

История: Универсальный набор символов (UCS) описан в стандарте ISO / IEC 10646 и был начат в 1989 году. Консорциум Unicode работал с ISO над параллельной разработкой стандарта Unicode и ISO / IEC 10646.Набор символов, имена символов и кодовые точки Unicode точно соответствуют UCS (за очень немногими исключениями).

Характеристики: Стандарт UCS в основном является родственным стандарту Unicode; они очень похожи. Различия заключаются в том, что UCS является стандартом ISO, в то время как Unicode поддерживается Консорциумом Unicode, а Unicode поддерживает ряд дополнительных функций помимо UCS, например поддержка языков с письмом справа налево.

Опять же, имейте в виду, что UCS / Unicode могут использоваться взаимозаменяемо во многих сценариях.Вот как их стандарты соотносятся друг с другом:


UCS to Unicode Mapping

UCS-2/4

UCS-2 - устаревшая система, которую часто путают с UTF-16. Возникает путаница, потому что UCS-2 всегда использовал два (2) байта на символ, а первоначальная концепция Unicode также предусматривала два байта на символ, но сейчас это не так. UTF-16 имеет кодировку минимум из двух байтов для любой кодовой точки, но UTF-16 может использовать более 2 байтов на символ (до четырех), потому что он поддерживает суррогатных пар (пары 16-битных слов).

Короче говоря, UCS-2 представлял собой схему кодирования фиксированной длины с кодировкой всех кодовых точек в два байта, а UTF-16 - это переменной длины с двумя байтами как минимум . Но поскольку у них обоих было , что-то , связанное с «двумя байтами», они часто путаются. В любом случае это спорный вопрос, поскольку UCS-2 устарел; если вам нужна 16-битная база, всегда используйте UTF-16.

UCS-4 идентичен с точки зрения отображения символов UTF-32. Обе схемы фиксированной длины кодируют , которые кодируют каждую точку кода UCS / Unicode до 32 бит.

Ссылка: универсальная система символов (UCS) (ISO 10646) (wikipedia.org)

UTF-7

История: SMTP указывает, что данные передаются в ASCII, и не допускает байтов, превышающих стандарт 0-127 классифицировать. Целью UTF-7 было создание системы для кодирования символов Unicode ниже 128 в формате, который прошел бы через классическую реализацию SMTP без искажений.

Характеристики: UTF-7 - это 7-битная система кодирования с переменной длиной кода. Он называется UTF, но на самом деле сам по себе не является стандартом Unicode.Он кодирует только символы ниже 128 (у него есть только 7 бит для работы), используя один из двух методов: Примерно 65 символов ASCII UTF-7 кодирует их непосредственно в представление ASCII. В остальном он преобразует символ в UTF-16, а затем выполняет для них модифицированное кодирование Base 64. Фактические шаги из Википедии:

  1. Выразите символы UTF-16 в двоичном формате
  2. Объедините двоичные последовательности
  3. Перегруппируйте биты в группы по шесть
  4. Если в последней группе меньше шести, добавьте нули
  5. Заменить каждая группа из шести бит с кодом Base64

Ссылка: UTF-7 (wikipedia.org)

ISO 8859

История: ISO 8859 - ранний стандарт ISO (до UCS / Unicode), который пытался унифицировать системы отображения кода.

Характеристики: ISO 8559 - это 8-битная система , которая группирует различные алфавиты в части, которые затем называются 8859-1, 8859-2 и т. Д. Вот как они разбиваются:

  1. Часть 1: Latin-1 | Западноевропейский
  2. Часть 2: Latin-2 | Центральноевропейская
  3. Часть 3: Latin-3 | Южноевропейский
  4. Часть 4: Latin-4 | Североевропейский
  5. Часть 5: Латинско-кириллица
  6. Часть 6: Латинско-арабский
  7. Часть 7: Латинско-греческий
  8. Часть 8: Латинско-иврит
  9. Часть 9: Latin-5 | Турецкий
  10. Часть 10: Latin-6 | Nordic
  11. Часть 11: Латинско-тайский
  12. Часть 13: Latin-7 | Baltic Rim
  13. Часть 14: Latin-8 | Кельтский
  14. Часть 15: Latin-9
  15. Часть 16: Latin-10 | Юго-Восточная Европа

Этот стандарт в значительной степени устарел благодаря UCS / Unicode.Это похоже на стандарт, которого ИСО желает, чтобы никогда не было. По возможности избегайте этого и используйте вместо этого Unicode.

Ссылка: ISO 8859 (wikipedia.org)

Кодирование URL-адресов

История: RFC 1738 (стандарт для URL-адресов) гласит: «Только буквенно-цифровые символы [0-9a-zA-Z], специальные символы– $ - _. +! * '(), –И зарезервированные символы, используемые для их зарезервированных целей, могут использоваться в URL без кодирования ».

  • Тильда ~
  • Скобки []
  • Командная галочка `
  • Для любого из перечисленных символов, которые нельзя (или не следует) помещать в URL изначально для правильного URL-кодирования необходимо использовать следующий алгоритм кодирования:

    1. Найдите кодовую точку ISO 8859-1 для рассматриваемого символа
    2. Преобразуйте эту кодовую точку в два шестнадцатеричных символа
    3. Добавьте знак процента (%) перед двумя шестнадцатеричными символами

    Вот почему вы видите так много экземпляров % 20 в своих URL-адресах.Это кодировка URL для пробела.

    Ссылка: W3C URL Encoding Reference, URL Encoding (bloobery.com)

    Здесь я попытаюсь ответить на ряд общих вопросов в формате вопрос / ответ. Однако, если у вас есть время, я предлагаю вам сначала ознакомиться с разделами о концепциях и / или стандартах.

    В чем разница между Unicode и UCS (ISO 10646)?

    Думайте о Unicode и UCS как о в основном одном и том же, когда дело доходит до сопоставления символов. В этом отношении они почти зеркально отражают друг друга.Однако Unicode добавляет ряд функций, таких как возможность правильно отображать сценарии с написанием справа налево, выполнять сортировку и сравнение строк и т. Д. Если у вас возникнут сомнения, вы, вероятно, захотите использовать Unicode.

    Что такое основной многоязычный самолет (BMP)?

    BMP - это один из 17 наборов от общего пространства кода Unicode. Это первый (уровень 0), в нем больше всего назначений персонажей. Его цель - унифицировать наборы символов всех предыдущих систем и поддерживать все системы письма, которые используются в настоящее время.

    Я запуталась. Какие схемы кодируют до какой длины?

    • ASCII -> 7 бит
    • «Расширенный ASCII» -> 8 бит
    • UTF-7 -> 7 бит
    • Карты кодов IBM (OEM) -> 8 бит
    • Карты кодов ANSI (Microsoft) -> 8 бит
    • ISO 8859 -> 8 бит
    • UTF-8 -> 1-4 байта
    • UTF-16 -> 2-4 байта
    • UTF-32 -> 4 байта
    • UCS-2 -> 2 байта (устарело)
    • UCS-4 -> 4 байта

    Надеюсь, это было полезно, и если у вас есть какие-либо вопросы, комментарии или исправления, пожалуйста, оставьте комментарий ниже или свяжитесь со мной напрямую.