Сравнение кодировок Unicode - Википедия - Comparison of Unicode encodings

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

Проблемы совместимости

А UTF-8 файл, содержащий только ASCII символов идентичен файлу ASCII. Устаревшие программы обычно могут обрабатывать файлы в кодировке UTF-8, даже если они содержат символы, отличные от ASCII. Например, C printf Функция может печатать строку UTF-8, поскольку она ищет только символ ASCII '%' для определения строки форматирования и печатает все остальные байты без изменений, поэтому символы, отличные от ASCII, будут выводиться без изменений.

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

Поэтому даже в большинстве систем UTF-16, таких как Windows и Ява, Текстовые файлы UTF-16 встречаются нечасто; старые 8-битные кодировки, такие как ASCII или ISO-8859-1 все еще используются без поддержки Unicode; или UTF-8 используется для Unicode. Одним из редких контрпримеров является файл "строк", используемый Mac OS X (10.3 и новее) приложения для поиска интернационализированных версий сообщений, которые по умолчанию используют UTF-16, с «файлами, закодированными с использованием UTF-8 ... не гарантируется работа».[1]

XML по умолчанию закодирован как UTF-8, и все процессоры XML должны как минимум поддерживать UTF-8 (включая US-ASCII по определению) и UTF-16.[2]

Эффективность

UTF-8 требует 8, 16, 24 или 32 бит (от одного до четырех байты ) для кодирования символа Unicode, UTF-16 требуется 16 или 32 бита для кодирования символа, и UTF-32 всегда требует 32 бита для кодирования символа. Первый 128 Unicode кодовые точки, От U + 0000 до U + 007F, используется для C0 Controls и базовая латынь символы, которые однозначно соответствуют их эквивалентам в коде ASCII, кодируются с использованием 8 бит в UTF-8, 16 бит в UTF-16 и 32 бит в UTF-32.

Следующие 1920 символов, от U + 0080 до U + 07FF (включая оставшуюся часть почти всех Латинские алфавиты, а также Греческий, Кириллица, Коптский, Армянский, иврит, арабский, Сирийский, Тана и N'Ko ), требуется 16 бит для кодирования в UTF-8 и UTF-16 и 32 бита в UTF-32. Для U + 0800 - U + FFFF, то есть оставшиеся символы в Базовая многоязычная плоскость (BMP, плоскость 0, от U + 0000 до U + FFFF), которая охватывает остальные символы большинства живых языков мира, UTF-8 требует 24 бита для кодирования символа, тогда как UTF-16 требует 16 бит и UTF -32 требуется 32. Кодовые точки от U + 010000 до U + 10FFFF, которые представляют символы в дополнительные самолеты (плоскости 1-16), требуется 32 бита в UTF-8, UTF-16 и UTF-32.

Все печатные символы в UTF-EBCDIC используйте по крайней мере столько же байтов, сколько в UTF-8, и большинство используют больше, поскольку было принято решение разрешить кодирование управляющих кодов C1 как отдельные байты. Для семибитных сред UTF-7 занимает больше места, чем комбинация других кодировок Unicode с цитируемый-печатный или же base64 почти для всех типов текста (см. "Семибитные среды " ниже).

Использование хранилища

Каждый формат имеет свой набор преимуществ и недостатков в отношении эффективности хранения (и, следовательно, времени передачи) и эффективности обработки. Эффективность хранения зависит от местоположения в Unicode. кодовое пространство в котором символы любого заданного текста преимущественно из. Поскольку блоки кодового пространства Unicode организованы по набору символов (то есть по алфавиту / сценарию), эффективность хранения любого заданного текста эффективно зависит от алфавит / сценарий используется для этого текста. Так, например, для UTF-8 требуется на один байт на символ меньше (8 против 16 бит), чем для UTF-16 для 128 кодовых точек между U + 0000 и U + 007F, но для каждого символа требуется на один байт больше (24 против 16 бит ) для 63 488 кодовых точек между U + 0800 и U + FFFF. Следовательно, если в диапазоне от U + 0000 до U + 007F больше символов, чем в диапазоне от U + 0800 до U + FFFF, тогда UTF-8 более эффективен, а если их меньше, то UTF-16 более эффективен. эффективный. Если счетчики равны, значит, они одинакового размера. Удивительным результатом является то, что реальные документы, написанные на языках, которые используют символы только в верхнем диапазоне, все еще часто короче в UTF-8 из-за широкого использования пробелов, цифр, знаков препинания, новой строки, разметки html и встроенных слов и аббревиатуры, написанные латинскими буквами.[нужна цитата ]

Время обработки

Что касается времени обработки, текст с кодировкой переменной длины, такой как UTF-8 или UTF-16, труднее обрабатывать, если есть необходимость найти отдельные единицы кода, в отличие от работы с последовательностями единиц кода. На поиск не влияет то, имеют ли символы переменный размер, поскольку поиск последовательности кодовых единиц не заботится о делениях (он требует, чтобы кодировка была самосинхронизирующейся, что и UTF-8, и UTF-16). Распространенное заблуждение состоит в том, что необходимо «найти п-й символ "и что для этого требуется кодировка фиксированной длины; однако на самом деле число п выводится только из изучения п-1 символов, поэтому в любом случае необходим последовательный доступ.[нужна цитата ] UTF-16BE и UTF-32BE находятся прямой порядок байтов, UTF-16LE и UTF-32LE находятся прямой порядок байтов. Когда последовательности символов в одном порядке байтов загружаются на машину с другим порядком байтов, символы необходимо преобразовать, прежде чем их можно будет эффективно обрабатывать, если только данные не обрабатываются с байтовой гранулярностью (как требуется для UTF-8). Соответственно, рассматриваемая проблема больше относится к протоколу и связи, чем к вычислительной сложности.

Проблемы с обработкой

Для обработки формат должен быть простым для поиска, усечения и в целом безопасной обработки. Все нормальные кодировки Unicode используют некоторую форму кодовой единицы фиксированного размера. В зависимости от формата и кодируемой точки, одна или несколько из этих кодовых единиц будут представлять Unicode. кодовая точка. Чтобы упростить поиск и усечение, последовательность не должна встречаться в более длинной последовательности или на границе двух других последовательностей. UTF-8, UTF-16, UTF-32 и UTF-EBCDIC имеют эти важные свойства, но UTF-7 и ГБ 18030 не.

Символы фиксированного размера могут быть полезны, но даже если существует фиксированное количество байтов на кодовую точку (как в UTF-32), фиксированного количества байтов на отображаемый символ не существует из-за объединение персонажей. Учитывая эти несовместимости и другие причуды между различными схемами кодирования, обработка данных Unicode с использованием одного и того же (или совместимого) протокола во всех интерфейсах и между интерфейсами (например, использование API / библиотеки, обработка символов Unicode в модели клиент / сервер и т. Д.) В целом может упростить весь конвейер, в то же время исключив потенциальный источник ошибок.

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

Если какие-либо сохраненные данные находятся в UTF-8 (например, содержимое или имена файлов), очень сложно написать систему, которая использует UTF-16 или UTF-32 в качестве API. Это связано с тем, что часто упускаемый из виду факт, что массив байтов, используемый UTF-8, может физически содержать недопустимые последовательности. Например, невозможно исправить недопустимое имя файла UTF-8 с помощью API UTF-16, так как никакая возможная строка UTF-16 не будет преобразована в это недопустимое имя файла. Обратное неверно: преобразовать недопустимый UTF-16 в уникальную (хотя технически недопустимую) строку UTF-8 - тривиально, поэтому API UTF-8 может управлять файлами и именами как UTF-8, так и UTF-16, что делает UTF -8 предпочтительнее в любой такой смешанной среде. Прискорбный, но гораздо более распространенный обходной путь, используемый системами UTF-16, - интерпретировать UTF-8 как некоторую другую кодировку, такую ​​как CP-1252 и игнорировать моджибаке для любых данных, отличных от ASCII.

Для связи и хранения

UTF-16 и UTF-32 не имеют порядок байтов определены, поэтому порядок байтов должен быть выбран при их приеме по байтовой сети или чтении из байтовой памяти. Это может быть достигнуто с помощью метка порядка байтов в начале текста или с прямым порядком байтов (RFC 2781 ). UTF-8, UTF-16BE, UTF-32BE, UTF-16LE и UTF-32LE стандартизированы для однобайтового порядка и не имеют этой проблемы.

Если байтовый поток подчиняется коррупция тогда одни кодировки восстанавливаются лучше других. UTF-8 и UTF-EBCDIC являются лучшими в этом отношении, поскольку они всегда могут повторно синхронизироваться после поврежденного или отсутствующего байта в начале следующей кодовой точки; GB 18030 не может быть восстановлен до следующего не числа ASCII. UTF-16 может обрабатывать изменен байтов, но не нечетное количество отсутствующий bytes, что приведет к искажению всего следующего текста (хотя и приведет к появлению необычных и / или неназначенных символов). Если биты могут быть потеряны, все они будут искажать следующий текст, хотя UTF-8 может быть повторно синхронизирован, поскольку неправильные границы байтов приведут к недопустимому UTF-8 в тексте, длина которого превышает несколько байтов.

В деталях

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

N.B. В таблицах ниже указано количество байтов на кодовая точка, нет для каждого пользователя видимый «символ» (или «кластер графемы»). Для описания одного кластера графемы может потребоваться несколько кодовых точек, поэтому даже в UTF-32 необходимо соблюдать осторожность при разделении или объединении строк.

Восьмибитные среды

Кодовый диапазон (шестнадцатеричный)UTF-8UTF-16UTF-32UTF-EBCDICГБ 18030
000000–00007F12411
000080 - 00009F22 для персонажей, унаследованных от
ГБ 2312 /ГБК (например, большинство
Китайские иероглифы) 4 для
все остальное.
0000A0 - 0003FF2
000400 - 0007FF3
000800 - 003FFF3
004000 - 00FFFF4
010000 - 03FFFF444
040000 - 10FFFF5

Семибитные среды

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

Кодовый диапазон (шестнадцатеричный)UTF-7UTF-8 цитируется-
печатный
UTF-8 base64UTF-16 q.-p.UTF-16 base64GB 18030 q.-p.ГБ 18030 base64
ASCII
графические персонажи
(кроме U + 003D "=")
1 для «прямых символов» (зависит от настройки кодировщика для некоторых кодовых точек), 2 для U + 002B «+», в остальном то же, что и для 000080 - 00FFFF11 1342 2311 13
00003D (знак равенства)363
ASCII
управляющие символы:
000000– 00001F
и 00007F
1 или 3 в зависимости от прямоты1 или 3 в зависимости от прямоты
000080 - 0007FF5 для отдельного случая внутри серии однобайтовых символов. Для пробежек2 23 на символ плюс отступ, чтобы сделать его целым числом байтов плюс два для начала и завершения прогона62 232–6 в зависимости от того, нужно ли экранировать байтовые значения4–6 для символов, унаследованных от GB2312 / GBK (например,
большинство китайских иероглифов) 8 для всего остального.
2 23 для символов, унаследованных от GB2312 / GBK (например,
большинство китайских иероглифов)5 13 для всего остального.
000800 - 00FFFF94
010000 - 10FFFF8 для изолированного случая,5 13 на символ плюс дополнение к целому числу плюс 2 для выполнения125 138–12 в зависимости от того, нужно ли экранировать младшие байты суррогатов.5 1385 13

Порядок байтов не влияет на размеры (UTF-16BE и UTF-32BE иметь такой же размер, как UTF-16LE и UTF-32LE Использование UTF-32 в кавычках крайне непрактично, но в случае реализации приведет к 8–12 байтам на кодовую точку (около 10 байтов в среднем), а именно для BMP каждая кодовая точка будет занимать ровно На 6 байт больше, чем тот же код в кавычках / UTF-16. Base64 / UTF-32 получает5 13 байтов для любой кодовая точка.

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

Схемы сжатия

BOCU-1 и ГКГУ есть два способа сжатия данных Unicode. Их кодирование зависит от того, как часто используется текст. В большинстве серий текста используется один и тот же сценарий; Например, латинский, Кириллица, Греческий и так далее. Это нормальное использование позволяет сжать множество строк текста примерно до 1 байта на кодовую точку. Эти кодировки с отслеживанием состояния затрудняют произвольный доступ к тексту в любой позиции строки.

Эти две схемы сжатия не так эффективны, как другие схемы сжатия, например застегивать или же bzip2. Эти схемы сжатия общего назначения могут сжимать более длинные серии байтов всего до нескольких байтов. В ГКГУ и BOCU-1 схемы сжатия не сжимают больше теоретических 25% текста, закодированного как UTF-8, UTF-16 или UTF-32. Другие схемы сжатия общего назначения могут легко сжать до 10% исходного размера текста. Схемы общего назначения требуют более сложных алгоритмов и более длинных фрагментов текста для хорошей степени сжатия.

Техническое примечание Unicode # 14 содержит более подробное сравнение схем сжатия.

Исторический: UTF-5 и UTF-6

Были сделаны предложения для UTF-5 и UTF-6 для интернационализация доменных имен (IDN). Предложение UTF-5 использовало база 32 кодировка, где Punycode является (среди прочего, и не совсем) база 36 кодирование. Название UTF-5 для кодовой единицы из 5 битов объясняется уравнением 25 = 32.[3] Предложение UTF-6 добавило кодировку рабочей длины в UTF-5, здесь 6 просто означает UTF-5 плюс 1.[4]В IETF РГ IDN позже приняла более эффективную Punycode для этого.[5]

Не преследуется серьезно

UTF-1 так и не получил серьезного признания. UTF-8 используется гораздо чаще.

UTF-9 и UTF-18 несмотря на то, что они были функциональными кодировками, были День дурака RFC характеристики анекдота.

Рекомендации

  1. ^ Подключение разработчиков Apple: Программирование на интернационализации. Темы: файлы строк.
  2. ^ «Кодировка символов в объектах». Extensible Markup Language (XML) 1.0 (пятое издание). W3C. 2008.
  3. ^ Сенг, Джеймс, UTF-5, формат преобразования Unicode и ISO 10646, 28 января 2000 г.
  4. ^ Велтер, Марк; Сполярич, Брайан В. (16 ноября 2000 г.). «UTF-6 - еще одна кодировка, совместимая с ASCII для идентификаторов». Инженерная группа Интернета. В архиве из оригинала 23 мая 2016 г.. Получено 9 апреля 2016.
  5. ^ Историческая страница рабочей группы IDN IETF