сколько байтов отводится на кодирование одного символа в кодировке unicode
Ordnung muß sein. Ordnung über alles (18+)
Инструменты пользователя
Инструменты сайта
Боковая панель
Навигация
Линкшэринг
socialite Display:icon facebook twitter
ALARM!
Добавить новую страницу
Реклама
Содержание
Юникод и байты
Про Юникод написано много, но мне кажется, что это одна из тем, про которую «чисто ради интереса» никто читать не полезет. Поэтому я решил поделиться здесь одной штукой, которая, как я в разговорах со многими замечал, не всем известна. Речь о том, «сколько байт занимает юникод».
Старые кодировки (например WINDOWS-1251, KOI8-R) совершенно четко определяют, какие конкретные значения одного байта используются для кодирования одного символа (человеческого или служебного). И отсюда вытекает их известная проблема с тем, что они не могут кодировать больше 256 символов. Для того, чтобы с этой проблемой бороться универсально, был придуман Юникод.
Вот дальше идет то самое частое, потому что очень логичное, заблуждение о том, что Юникод — это кодировка, где для каждого символа отводится 2 байта, а значит она может кодировать 65536 символов. Больше того, хоть я и не смотрел специально, кажется именно так она и была задумана в самом начале. Но сейчас все совсем не так.
Довольно быстро возникла необходимость кодировать гораздо больше, чем 65536 символов (чуть больше миллиона сейчас) и, что главное, появилась необходимость кодировать их по-разному. Поэтому в отличие от старых кодировок стандарт Юникода полностью разделяет две вещи:
Номера, присваиваемые символам, полностью абстрактны. Это не байты, не двубайты, а просто числа. Например символу «Заглавная кириллическая буква А» назначен номер 1040, он же — 410 в шестнадцатеричной системе. И формально в Юникоде это принято записывать как U+0410.
А вот способов представлять это число в памяти или записывать в файлы существует больше одного. Называются они «формы кодирования«. Вот наиболее распространенные.
Есть несколько форм кодирования, которые официально входят в стандарт.
Самый существенный его минус — это то, что по количеству байт в строке невозможно определить ее длину в символах.
UTF-16 (или, что почти одно и то же — UCS-2)
Это, собственно, то, с чего начинался Юникод: для кодирования одного символа используются двухбайтовые целые. Этого хватает для того, чтобы хранить большинство нужных и распространенных на практике символов. И только для редких символов, включенных в Юникод позднее, используются пары двухбайтовых целых.
Кстати, UCS-2 — это как раз UTF-16 без этих дополнительных символов, то есть строго символ = 2 байта.
На практике редкие символы действительно редки (часто встречались с древнегреческой музыкальной грамотой?), поэтому во многих системах для внутреннего представления символов используется именно UTF-16, например в NTFS для имен файлов, в Delphi для WideString’ов, и Java, насколько я знаю, тоже внутри вся в UTF-16 работает со строками.
Однако двухбайтовость делает затруднительным использование UTF-16 для обмена данными из-за двух проблем: наличия нулевых байтов в строке и разночтения порядка следования старшего и младшего байтов на разных платформах.
UTF-32 (или, что почти одно и то же — UCS-4)
Это — форма для перфекционистов. Для представления символа используется строго 4 байта, которыми можно представить абсолютно любой юникодный символ. С недавнего времени тот же Python на большинстве платформ использует именно четырехбайтовое представление для юникодных строк.
Отличия от UCS-4 совсем умозрительные и непрактические.
Минус у этого представления, помимо плохой переносимости, как у UTF-16, еще и в том, что UTF-32 попросту занимает еще больше места.
Другие формы
Помимо UTF’ов, внесенных в стандарт Юникода, существует еще несколько знакомых многим способов представления юникодных номеров.
Ну и еще напоследок — представление в Javascript. Суть та же, что и у (X|HT)ML’а, только запись другая: \u0410, \u0160…
То, что я тут написал — довольно упрощенное прдставление, где я не касался всяких форм нормализации, символов, которые не символы, и прочих «высших и низших суррогатов». Хотя вчера успел совершенно замучить жену цитатами из стандарта Юникода, который читал, чтобы уточнить пару вещей для статьи. Штука, конечно, интересная, но удивительно запутанная. Если кого это все заинтересует, то лучше всего начать со статьи про Юникод в русской Wikipedia (очень хорошая).
Сколько байтов занимает один символ Unicode?
Я немного смущен кодировками. Насколько я знаю, старые символы ASCII занимали один байт на символ. Сколько байтов требуется символу Unicode?
и что делают UTF-7, UTF-6, UTF-16 и т. д. в смысле? Являются ли они разными версиями Unicode?
прочитал статья в Википедии о Unicode но это довольно сложно для меня. Я с нетерпением жду простого ответа.
10 ответов
вы не увидите простой ответ, потому что его нет.
во-первых, Unicode не содержит «каждый символ из каждого языка», хотя он, конечно, пытается.
Unicode сам по себе является отображением, он определяет кодовые точки, А кодовая точка-это число, связанное с обычно символ. Я говорю обычно, потому что есть такие понятия, как сочетание символов. Вы можете быть знакомы с такими вещами, как акценты, или умляуты. Их можно использовать с другим персонажем, такие как a или u для создания нового логического символа. Поэтому символ может состоять из 1 или более кодов.
чтобы быть полезным в вычислительных системах, нам нужно выбрать представление для этого информацию. Это различные кодировки unicode, такие как utf-8, utf-16le, utf-32 и т. д. Они отличаются в значительной степени размером своих codeunits. UTF-32-это самая простая кодировка, у нее есть codeunit, который составляет 32 бит, что означает, что индивидуальная кодовая точка подходит комфортно в центр. Другие кодировки будут иметь ситуации, когда кодовая точка будет нуждаться в нескольких кодовых единицах, или эта конкретная кодовая точка не может быть представлена в кодировке вообще (это проблема, например, с UCS-2).
из-за гибкости объединения символов даже в пределах заданной кодировки количество байтов на символ может варьироваться в зависимости от символа и формы нормализации. Это протокол для работы с персонажами, которые имеют более чем одно представление (можно сказать «an ‘a’ with an accent» который является 2 кодовыми точками, одна из которых является комбинирующим символом или «accented ‘a'» который является одной кодовой точкой).
Как ни странно, никто не указал, как рассчитать сколько байт занимает один символ Юникода. Вот правило для строк в кодировке UTF-8:
Итак, быстрый ответ: он занимает от 1 до 4 байт, в зависимости от первого, который укажет, сколько байтов он займет.
обновление
As prewett указал, это правило применяется только к UTF-8
я знаю, этот вопрос старый и уже есть принятый ответ, но я хочу предложить несколько примеров (надеюсь, что это будет полезно кому-то).
насколько я знаю, старые символы ASCII занимали один байт на символ.
право. На самом деле, поскольку ASCII является 7-битной кодировкой, он поддерживает 128 кодов (95 из которых можно распечатать), поэтому он использует только половину байта (если это имеет смысл).
сколько байтов делает Unicode характер требуется?
Unicode просто сопоставляет символы с кодовыми точками. Он не определяет, как их кодировать. Текстовый файл содержит не символы Юникода, а байты/октеты, которые могут представлять символы Юникода.
я полагаю, что один символ Юникода может содержать все возможные характер с любого языка-я прав?
нет. Но почти. Так что в принципе да. Но все равно нет.
Так сколько байты нужны для каждого символа?
то же, что и ваш 2-й вопрос.
и что означает UTF-7, UTF-6, UTF-16 и т. д.? Являются ли они своего рода Unicode версии?
нет, это кодировки. Они определяют, как байты / октеты должны представлять символы Юникода.
пара примеров. Если некоторые из них не могут быть отображены в вашем браузере (возможно, потому, что шрифт их не поддерживает), перейдите в http://codepoints.net/U+1F6AA (заменить 1F6AA С кода в hex), чтобы увидеть изображение.
UTF-32 каждый символ имеет 4 байта характер.
UTF-16 использует 16 бит для каждого символа и представляет только часть символов Юникода, называемых BMP (для всех практических целей его достаточно). Java использует эту кодировку в своих строках.
в Unicode ответ дается нелегко. Проблема, как вы уже отметили, заключается в кодировках.
учитывая любое английское предложение без диакритических символов, ответ для UTF-8 будет столько же байтов, сколько символов, а для UTF-16-количество символов, умноженное на два.
единственная кодировка, в которой (на данный момент) мы можем сделать заявление о размере,-UTF-32. Там всегда 32bit на символ, хотя я предполагаю, что кодовые точки подготовлен к будущему UTF-64:)
что делает это так сложно, по крайней мере две вещи:
10FFFF-последняя кодовая точка unicode по определению, и она определена таким образом, потому что это Технический предел UTF-16.
Это также самая большая кодовая точка UTF-8 может кодироваться в 4 байта, но идея кодирования UTF-8 также работает для 5 и 6 байтовых кодировок для покрытия кодовых точек до 7FFFFFFF, т. е. половина того, что может UTF-32.
существует отличный инструмент для вычисления байтов любой строки в UTF-8:http://mothereff.in/byte-counter
Ну, я просто вытащил страницу Википедии на ней тоже, и в вступительной части я увидел, что «Unicode может быть реализован различными кодировками символов. Наиболее часто используемых кодировок: UTF-8 (который использует один байт за любые ASCII символы, которые имеют одинаковые значения кодов в кодировке UTF-8 и ASCII кодировки, и до четырех байтов для других персонажей), ныне устаревшей кодировке UCS-2 (который использует два байта для каждого символа, но не может кодировать каждый символ в текущей кодировке Unicode стандарт)»
Как показывает эта цитата, ваша проблема заключается в том, что вы предполагаете, что Unicode-это единственный способ кодирования символов. На самом деле существует несколько форм Unicode, и, опять же в этой цитате, один из них даже имеет 1 байт на символ, как и то, к чему вы привыкли.
таким образом, ваш простой ответ, который вы хотите, заключается в том, что он меняется.
для UTF-16 символу требуется четыре байта (две единицы кода), если он начинается с 0xD800 или больше; такой символ называется «суррогатной парой».»Более конкретно, суррогатная пара имеет вид:
где [. ] указывает двухбайтовую кодовую единицу с заданным диапазоном. Anything = 0xE000 недопустимо (кроме маркеров спецификации, возможно).
UTF-8 vs UTF-16. Несколько советов программистам
Введение
С появлением первых устройств цифровой передачи информации и электронно-вычислительных машин возникла задача кодирования текстовых символов с помощью последовательностей единиц и нулей. Минимальная единица представления информации – байт. Исходя их этого в 1963 году в США разработана, стандартизована, а впоследствии расширена кодовая таблица ASCII (American standard code for information interchange), использовавшая 8 битную кодировку. В первую очередь с помощью этой таблицы предполагалось кодирование цифр и букв английского языка. Первые 128 символов таблицы представлены на рис.1:
Рис.1. Первые 128 символов таблицы ASCII.
Номер ячейки в таблице (рис.1) является кодом символа. В качестве примера рассмотрим кодирование слова Hello. Номера ячеек таблицы ASCII, в которых размещены буквы: 72 (H), 101 (e), 108 (l), 111 (o). Код слова в бинарном представлении выглядит следующим образом:
00010010 (H) 10100110 (e) 00110110 (l) 00110110 (l) 11110110 (o) (старший бит справа).
Выделенные подчеркиванием и жирным коды в двоичном представлении соответствуют номерам ячеек в таблице (рис.1). Алгоритм формирования кода следующий:
1. Выделены жирным – биты управления кодированием (префикс). 010 – кодируется заглавная буква алфавита, 011 – строчная.
2. Выделены подчеркиванием – порядковые номера букв в английском алфавите.
Таким образом, с помощью первых 128 ячеек таблицы ASCII могли быть закодированы основные символы, цифры и буквы английского языка. Остальные 128 ячеек (8 битная кодировка позволяет закодировать 256 символов) могли использоваться для кодирования других языков. Однако, учитывая разнообразие символов и языков, 8 бит недостаточно.
Стандарт Юникод
Консорциум Unicode (Юникод) – некоммерческая организация, главной задачей которой являлась разработка стандарта кодирования (стандарт Юникод) с поддержкой наибольшего числа языков и символов служебного характера. Принцип кодирования на основе таблицы сохранился, а таблица (таблица Юникод) была значительно расширена.
Стандарт Юникод предоставляет пользователям таблицу Юникод и способы кодирования символов.
Символы таблицы Юникод являются элементами «универсального набора символов» UCS (Universal Coded Character Set), определенного международным стандартом ISO/IEC 10646. Таблица Юникод каждому символу UCS сопоставляет кодовую точку, которая является номером ячейки таблицы, содержащей символ.
Способы кодирования символов таблицы Юникод, т.е. преобразования номеров ячеек таблицы Юникод в бинарные коды, составляют кодовое пространство, состоящее из трех кодов семейства UTF (Unicode Transformation Format): UTF-8, UTF-16 и UTF-32
UTF-8 – стандарт кодирования, преобразующий номера ячеек таблицы Юникод в бинарные коды с использованием переменного количества бит: 8, 16, 24 или 32.
UTF-16 – стандарт кодирования, преобразующий номера ячеек таблицы Юникод в бинарные коды с использованием переменного количества бит:16 или 32.
Коды UTF-8 и UTF-16 используют разные алгоритмы кодирования набора символов UCS.
Стандарт кодирования UTF-8
Стандарт закреплен в RFC (Request For Comments) 3629. Алгоритм кодирования согласно RFC:
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xx 10xxxxxx 10xxxxxx 10xxxxxx
Старший бит слева. Началом кода является управляющий символ (выделен жирным):
0 – используется 8-битная кодировка,
110 – используется 16-битная кодировка,
1110 – используется 24-битная кодировка,
11110 – используется 32 битная кодировка.
В начале каждого последующего байта – биты 10 – управляющий символ (выделен подчеркиванием), означающий продолжение кодирования.
Первые 128 ячеек таблицы Юникод повторяют таблицу ASCII. Для кодирования заглавных и строчных букв русского алфавита используются ячейки с номерами 1040-1103.
Рассмотрим пример кодирования фразы «Папа Hello».
Код в бинарном виде (старший бит справа):
00001011 11111001 (П) 00001011 00001101 (а) 00001011 11111101 (п) 00001011 00001101 (а) 00000100 (пробел) 00010010 (H) 10100110 (e) 00110110 (l) 00110110 (l) 11110110 (o).
Букве П русского алфавита согласно таблицы Юникод соответствует номер 1055, в бинарном представлении 10000011111 – 11 бит. Соответственно данный символ может быть закодирован двумя байтами с использованием префикса 110 – для первого байта и 10 – для второго байта. Английские буквы слова Hello кодируются 1 байтом, а коды совпадают с кодами в таблице ASCII.
Основными преимуществами способа кодирования UTF-8 являются многообразие символов, которые могут быть закодированы, а также возможность кодирования переменным количеством бит, что позволяет сэкономить количество информации, передаваемое в канале связи.
Стандарт кодирования UTF-16
В феврале 2000 года опубликован документ RFC 2781, в котором закреплен стандарт UTF-16, позволяющий кодировать символы таблицы Юникод с помощью 16 или 32 битных значений. Символы с номерами 0-55295 и 57344-65535 кодируются с помощью 16 бит без изменений (без использования префиксов), а остальные символы, номера которых в двоичном представлении формируются количеством бит больше 16, кодируются 32 битами с использованием специального алгоритма. Рассмотрим пример кодирования фразы «Папа Hello».
Код в бинарном виде (старший бит справа):
11111000 00100000 (П) 00001100 001000000 (а) 11111100 00100000 (п) 00001100 001000000 (а) 00000100 00000000 (пробел) 00010010 00000000 (H) 10100110 00000000 (e) 00110110 00000000 (l) 00110110 00000000 (l) 111110110 00000000 (o).
Номера букв русского и английского алфавитов таблицы Юникод передаются без изменений при помощи 16 бит, старшие незначащие биты принимают нулевое значение.
Рассмотрим подробнее алгоритм кодирования символов, номера которых превышают значение 65535. Для примера в качестве символа используем букву древнетюркского алфавита, представленную на рис.2:
Рис.2. Буква древнетюркского алфавита.
Номер предложенного символа в таблице Юникод – 68620 (0х10COC).
Алгоритм преобразования номера символа в код UTF-16 состоит из нескольких шагов:
Из значения номера символа вычесть число 0х10000. Данная операция позволяет привести размерность бинарного представления номера символа к 20 битам. Для предложенного символа получим: 0х10COC – 0x10000 = 0xC0C.
Для полученного значения выделить старшие 10 бит и младшие 10 бит. В примере число 0хС0С в бинарном виде представляется, как 00000000110000001100, где жирным выделены 10 старших бит, а подчеркиванием – 10 младших.
К шестнадцатеричному значению 0xD800 (11011000 00000000) прибавить значение 0х03 (00000000 00000011), сформированное 10 старшими битами, полученными на предыдущем шаге. 0xD800 + 0х03 = 0хD803 (11011000 00000011) – 16 старших бит кодового слова UTF-16.
К шестнадцатеричному значению 0xDC00 (11011000 00000000) прибавить значение 0х0C (00000000 00001100), сформированное 10 младшими битами, полученными на шаге №2. 0xDС00 + 0х0С = DС0С (11011100 00001100) – 16 младших бит кодового слова UTF-16.
Кодовое слово UTF-16, соответствующее символу в примере, формируется из бит, полученных на шагах 3 и 4: 0хD803DC0C (11011000 00000011 11011100 00001100).
Сравнение стандартов UTF-8 и UTF-16 с точки зрения объема машинной памяти, используемой кодом для представления символов
Результаты сравнения стандартов представлены в таблице 1.
Таблица 1. Результаты сравнения стандартов.
В ячейках таблицы 1 содержится количество бит, требуемое для кодирования одного символа из таблицы Юникод. Видно, что для диапазонов номеров ячеек 128-2047, 65535-1048575 стандарты UTF-8 и UTF-16 используют одинаковое количество бит. Для диапазона 0-127 выгодно использование стандарта UTF-8, например, в случае, если программисту поручили реализовать кодер букв английского алфавита. Для диапазонов 2048-32767 и 32768-65535 выгодно использование стандарта UTF-16, например, в случае, если программисту поручили реализовать кодер иероглифов Бопомофо (занимают в таблице Юникод диапазон ячеек 12549-12589). Кодирование символов таблицы Юникод, расположенных в ячейках, номера которых начинаются от 1048575 возможно только с использованием кодировки UTF-16.
В предыдущих главах приведены примеры кодирования фразы «Папа Hello» стандартами UTF-8 и UTF-16. Кодировкой UTF-8 используются 14 байт, кодировкой UTF-16 20 байт, что связано с избыточностью кодирования англоязычных символов во втором случае из-за использования дополнительного байта 0х00. Можно сделать вывод, что для кодирования текста содержащего набор букв русского и английского алфавитов, предпочтительно использование кодировки UTF-8.
Вывод: в зависимости от языка алфавита может быть выбрана как кодировка UTF-8, так и кодировка UTF-16. Для английского алфавита однозначно более выгодно использование кодировки UTF-8, для русского алфавита буквы представляются одинаковым количеством бит при использовании как одной, так и другой кодировки.
Несколько советов программистам
Допустим, программист решил реализовать текстовый редактор, поддерживающий алфавит языка Бопомофо. Символы данного языка располагаются в таблице Юникод в диапазоне 12549-12589 и, следовательно, программисту необходимо выбрать стандарт UTF-16 для кодирования. Предположим, что для ввода символов решено использовать программную клавиатуру, состоящую из кнопок, каждая из которых соответствует букве алфавита языка. Кнопки – объекты класса button. Нажатие пользователем на какую-либо из кнопок порождает событие, в результате которого приложению становится известен номер ячейки таблицы Юникод. Программисту рекомендуется:
1.Хранить в памяти приложения символы таблицы Юникод и номера ячеек, соответствующие только языкам, поддержка которых планируется в текстовом редакторе. Это уменьшит объем памяти, занимаемой приложением, а также повысит скорость его работы, сузив область поиска номера ячейки.
2. При реализации приложения заранее выполнить преобразование всех номеров ячеек в их бинарные коды. Результат преобразования сохранить в файле, в формализованном виде. При загрузке приложения выполнить считывание в память номеров ячеек и их бинарных кодов UTF-16. Это позволит снизить вычислительную нагрузку приложения в ходе его работы.
3. Для хранения номеров ячеек и их бинарных кодов использовать объект класса, позволяющего осуществить это в виде ключ-значение, где ключ – номер ячейки, а значение – бинарный код. Классы, реализующие в языках программирования данный функционал, организуют работу таким образом, чтобы минимизировать время поиска ключа, используя сортировку ключей или хеширование.
Отметим проблему кодирования составных символов, которая является важным техническим аспектом. Например, символ ü может быть интерпретирован, как самостоятельный символ, которому соответствует номер ячейки 252 или может быть скомпонован из двух символов: u, которому соответствует номер ячейки 117 и символа ¨, которому соответствует номер ячейки 776. Программист должен строго придерживаться одного из вариантов представления таких символов иначе побайтовое сравнение строк будет невозможно. Рекомендуется использование второго варианта, который может облегчить поиск составных символов в тексте. Например, если пользователь осуществляет поиск символа u, то ему может быть выведен в качестве результата, как составной символ ü, так и самостоятельный u.
Представление символов, таблицы кодировок
Содержание
Представление символов в вычислительных машинах [ править ]
В вычислительных машинах символы не могут храниться иначе, как в виде последовательностей бит (как и числа). Для передачи символа и его корректного отображения ему должна соответствовать уникальная последовательность нулей и единиц. Для этого были разработаны таблицы кодировок.
Таблицы кодировок [ править ]
На заре компьютерной эры на каждый символ было отведено по пять бит. Это было связано с малым количеством оперативной памяти на компьютерах тех лет. В эти [math]32[/math] символа входили только управляющие символы и строчные буквы английского алфавита.
С ростом производительности компьютеров стали появляться таблицы кодировок с большим количеством символов. Первой семибитной кодировкой стала ASCII7. В нее уже вошли прописные буквы английского алфавита, арабские цифры, знаки препинания. Затем на ее базе была разработана ASCII8, в которым уже стало возможным хранение [math]256[/math] символов: [math]128[/math] основных и еще столько же расширенных. Первая часть таблицы осталась без изменений, а вторая может иметь различные варианты (каждый имеет свой номер). Эта часть таблицы стала заполняться символами национальных алфавитов.
Но для многих языков (например, арабского, японского, китайского) [math]256[/math] символов недостаточно, поэтому развитие кодировок продолжалось, что привело к появлению UNICODE.
Кодировки стандарта ASCII [ править ]
Определение: |
ASCII — таблицы кодировок, в которых содержатся основные символы (английский алфавит, цифры, знаки препинания, символы национальных алфавитов(свои для каждого региона), служебные символы) и длина кода каждого символа [math]n = 8[/math] бит. |
Кодировки стандарта ASCII ( [math]8[/math] бит):
Структурные свойства таблицы [ править ]
Кодировки стандарта UNICODE [ править ]
Юникод или Уникод (англ. Unicode) — это промышленный стандарт обеспечивающий цифровое представление символов всех письменностей мира, и специальных символов.
Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода» (англ. Unicode Consortium, Unicode Inc.). Применение этого стандарта позволяет закодировать очень большое число символов из разных письменностей. Стандарт состоит из двух основных разделов: универсальный набор символов (англ. UCS, universal character set) и семейство кодировок (англ. UTF, Unicode transformation format). Универсальный набор символов задаёт однозначное соответствие символов кодам — элементам кодового пространства, представляющим неотрицательные целые числа.Семейство кодировок определяет машинное представление последовательности кодов UCS.
Коды в стандарте Unicode разделены на несколько областей. Область с кодами от U+0000 до U+007F содержит символы набора ASCII с соответствующими кодами. Далее расположены области знаков различных письменностей, знаки пунктуации и технические символы. Под символы кириллицы выделены области знаков с кодами от U+0400 до U+052F, от U+2DE0 до U+2DFF, от U+A640 до U+A69F. Часть кодов зарезервирована для использования в будущем.
Кодовое пространство [ править ]
Хотя формы записи UTF-8 и UTF-32 позволяют кодировать до [math]2^<31>[/math] [math](2\ 147\ 483\ 648)[/math] кодовых позиций, было принято решение использовать лишь [math]1\ 112\ 064[/math] для совместимости с UTF-16. Впрочем, даже и этого на текущий момент более чем достаточно — в версии 6.0 используется чуть менее [math]110\ 000[/math] кодовых позиций ( [math]109\ 242[/math] графических и [math]273[/math] прочих символов).
Кодовое пространство разбито на [math]17[/math] плоскостей (англ. planes) по [math]2^<16>[/math] [math](65\ 536)[/math] символов. Нулевая плоскость называется базовой, в ней расположены символы наиболее употребительных письменностей. Первая плоскость используется, в основном, для исторических письменностей, вторая — для для редко используемых иероглифов китайского письма, третья зарезервирована для архаичных китайских иероглифов. Плоскости [math]15[/math] и [math]16[/math] выделены для частного употребления.
Плоскости Юникода | ||
---|---|---|
Плоскость | Название | Диапазон символов |
Plane 0 | Basic multilingual plane (BMP) | U+0000…U+FFFF |
Plane 1 | Supplementary multilingual plane (SMP) | U+10000…U+1FFFF |
Plane 2 | Supplementary ideographic plane (SIP) | U+20000…U+2FFFF |
Planes 3-13 | Unassigned | U+30000…U+DFFFF |
Plane 14 | Supplementary special-purpose plane (SSP) | U+E0000…U+EFFFF |
Planes 15-16 | Supplementary private use area (S PUA A/B) | U+F0000…U+10FFFF |
Модифицирующие символы [ править ]
Графические символы в Юникоде делятся на протяжённые и непротяжённые. Непротяжённые символы при отображении не занимают дополнительного места в строке. К примеру, к ним относятся знак ударения. Протяжённые и непротяжённые символы имеют собственные коды, но последние не могут встречаться самостоятельно. Протяжённые символы называются базовыми (англ. base characters), а непротяженные — модифицирующими (англ. combining characters). Например символ «Й» (U+0419) может быть представлен в виде базового символа «И» (U+0418) и модифицирующего символа « ̆» (U+0306).
Способы представления [ править ]
Юникод имеет несколько форм представления (англ. Unicode Transformation Format, UTF): UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE). Была разработана также форма представления UTF-7 для передачи по семибитным каналам, но из-за несовместимости с ASCII она не получила распространения и не включена в стандарт.
UTF-8 [ править ]
Символы UTF-8 получаются из Unicode cледующим образом:
Unicode | UTF-8 | Представленные символы |
---|---|---|
0x00000000 — 0x0000007F | 0xxxxxxx | ASCII, в том числе английский алфавит, простейшие знаки препинания и арабские цифры |
0x00000080 — 0x000007FF | 110xxxxx 10xxxxxx | кириллица, расширенная латиница, арабский алфавит, армянский алфавит, греческий алфавит, еврейский алфавит и коптский алфавит; сирийское письмо, тана, нко; Международный фонетический алфавит; некоторые знаки препинания |
0x00000800 — 0x0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx | все другие современные формы письменности, в том числе грузинский алфавит, индийское, китайское, корейское и японское письмо; сложные знаки препинания; математические и другие специальные символы |
0x00010000 — 0x001FFFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | музыкальные символы, редкие китайские иероглифы, вымершие формы письменности |
111111xx | служебные символы c, d, e, f |
Несмотря на то, что UTF-8 позволяет указать один и тот же символ несколькими способами, только наиболее короткий из них правильный. Остальные формы, называемые overlong sequence, отвергаются по соображениям безопасности.
Принцип кодирования [ править ]
Правила записи кода одного символа в UTF-8 [ править ]
1. Если размер символа в кодировке UTF-8 = [math]1[/math] байт
Код имеет вид (0aaa aaaa), где «0» — просто ноль, остальные биты «a» — это код символа в кодировке ASCII;
2. Если размер символа в кодировке в UTF-8 [math]\gt 1[/math] байт (то есть от [math]2[/math] до [math]6[/math] ):
2.1 Первый байт содержит количество байт символа, закодированное в единичной системе счисления; 2.2 «0» — бит терминатор, означающий завершение кода размера 2.3 далее идут значащие байты кода, которые имеют вид (10xx xxxx), где «10» — биты признака продолжения, а «x» — значащие биты.
В общем случае варианты представления одного символа в кодировке UTF-8 выглядят так:
Определение длины кода в UTF-8 [ править ]
Количество байт UTF-8 | Количество значащих бит |
---|---|
[math]1[/math] | [math]7[/math] |
[math]2[/math] | [math]11[/math] |
[math]3[/math] | [math]16[/math] |
[math]4[/math] | [math]21[/math] |
[math]5[/math] | [math]26[/math] |
[math]6[/math] | [math]31[/math] |
[math]C = 7[/math] при [math]n=1[/math]
[math]C = n\cdot5+1[/math] при [math]n\gt 1[/math]
UTF-16 [ править ]
UTF-16LE и UTF-16BE [ править ]
Один символ кодировки UTF-16 представлен последовательностью двух байт или двух пар байт. Который из двух байт в словах идёт впереди, старший или младший, зависит от порядка байт. Подробнее об этом будет сказано ниже.
UTF-32 [ править ]
UTF-32 — один из способов кодирования символов из Юникод, использующий для кодирования любого символа ровно [math]32[/math] бита. Остальные кодировки, UTF-8 и UTF-16, используют для представления символов переменное число байт. Символ UTF-32 является прямым представлением его кодовой позиции (англ. code point).
Главный недостаток UTF-32 — это неэффективное использование пространства, так как для хранения символа используется четыре байта. Символы, лежащие за пределами нулевой (базовой) плоскости кодового пространства редко используются в большинстве текстов. Поэтому удвоение, в сравнении с UTF-16, занимаемого строками в UTF-32 пространства не оправдано.
Порядок байт [ править ]
В современной вычислительной технике и цифровых системах связи информация обычно представлена в виде последовательности байт. В том случае, если число не может быть представлено одним байтом, имеет значение в каком порядке байты записываются в памяти компьютера или передаются по линиям связи. Часто выбор порядка записи байт произволен и определяется только соглашениями.
[math]M = \sum_^
Варианты записи [ править ]
Порядок от старшего к младшему [ править ]
В этом же виде (используя представление в десятичной системе счисления) записываются числа индийско-арабскими цифрами в письменностях с порядком знаков слева направо (латиница, кириллица). Для письменностей с обратным порядком (арабская) та же запись числа воспринимается как «от младшего к старшему».
Порядок байт от старшего к младшему применяется во многих форматах файлов — например, PNG, FLV, EBML.
Порядок от младшего к старшему [ править ]
В противоположность порядку big-endian, соглашение little-endian поддерживают меньше кросс-платформенных протоколов и форматов данных; существенные исключения: USB, конфигурация PCI, таблица разделов GUID, рекомендации FidoNet.
Переключаемый порядок [ править ]
Многие процессоры могут работать и в порядке от младшего к старшему, и в обратном, например, ARM, PowerPC (но не PowerPC 970), DEC Alpha, MIPS, PA-RISC и IA-64. Обычно порядок байт выбирается программно во время инициализации операционной системы, но может быть выбран и аппаратно перемычками на материнской плате. В этом случае правильнее говорить о порядке байт операционной системы. Переключаемый порядок байт иногда называют англ. bi-endian.
Смешанный порядок [ править ]
Смешанный порядок байт (англ. middle-endian) иногда используется при работе с числами, длина которых превышает машинное слово. Число представляется последовательностью машинных слов, которые записываются в формате, естественном для данной архитектуры, но сами слова следуют в обратном порядке.
В процессорах VAX и ARM используется смешанное представление для длинных вещественных чисел.
Различия [ править ]
Для записи длинных чисел (чисел, длина которых существенно превышает разрядность машины) обычно предпочтительнее порядок слов в числе little-endian (поскольку арифметические операции над длинными числами производятся от младших разрядов к старшим). Порядок байт в слове — обычный для данной архитектуры.
Маркер последовательности байт [ править ]
Для определения формата представления Юникода в начало текстового файла записывается сигнатура — символ U+FEFF (неразрывный пробел с нулевой шириной), также именуемый маркером последовательности байт (англ. byte order mark (BOM)). Это позволяет различать UTF-16LE и UTF-16BE, поскольку символа U+FFFE не существует.
Кодирование | Представление (Шестнадцатеричное) |
---|---|
UTF-8 | EF BB BF |
UTF-16 (BE) | FE FF |
UTF-16 (LE) | FF FE |
UTF-32 (BE) | 00 00 FE FF |
UTF-32 (LE) | FF FE 00 00 |
В кодировке UTF-8, наличие BOM не является существенным, поскольку, нет альтернативной последовательности байт. Когда BOM используется на страницах или редакторах для контента закодированного в UTF-8, иногда он может представить пробелы или короткие последовательности символов, имеющие странный вид (такие как ). Именно поэтому, при наличии выбора, для совместимости, как правило, лучше упустить BOM в UTF-8 контенте.Однако BOM могут еще встречаться в тексте закодированном в UTF-8, как побочный продукт перекодирования или потому, что он был добавлен редактором. В этом случае BOM часто называют подписью UTF-8.
Когда символ закодирован в UTF-16, его [math]2[/math] или [math]4[/math] байта можно упорядочить двумя разными способами (little-endian или big-endian). Изображение справа показывает это. Byte order mark указывает, какой порядок используется, так что приложения могут немедленно расшифровать контент. UTF-16 контент должен всегда начинатся с BOM.
BOM также используется для текста обозначенного как UTF-32. Аналогично UTF-16 существует два варианта четырёхбайтной кодировки — UTF-32BE и UTF-32LE. К сожалению, этот способ не позволяет надёжно различать UTF-16LE и UTF-32LE, поскольку символ U+0000 допускается Юникодом
Проблемы Юникода [ править ]
В Юникоде английское «a» и польское «a» — один и тот же символ. Точно так же одним символом (но отличающимся от «a» латинского) считаются русское «а» и сербское «а». Такой принцип кодирования не универсален; по-видимому, решения «на все случаи жизни» вообще не может существовать.