Сравнение кодировок Unicode

редактировать

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

Содержание

  • 1 Проблемы совместимости
  • 2 Эффективность
  • 3 Проблемы с обработкой
  • 4 Для связи и хранения
  • 5 Подробно
    • 5.1 Восьмиразрядные среды
    • 5.2 Семибитные среды
    • 5.3 Схемы сжатия
    • 5.4 Исторические данные: UTF-5 и UTF-6
    • 5.5 Не рассматривается серьезно
  • 6 Ссылки

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

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

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

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

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

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

UTF-8 требует 8, 16, 24 или 32 бита (от одного до четырех байтов ) для кодирования символа Unicode, UTF-16 требует 16 или 32 бита для кодирования символа, а UTF-32 всегда требует 32 бита для кодирования символа. Первые 128 кодовых точек Unicode , от U + 0000 до U + 007F, используемых для элементов управления C0 и символов Basic Latin, которые взаимно однозначно соответствуют их эквивалентам в коде ASCII, кодируются с использованием 8 бит в UTF-8, 16 бит в UTF-16 и 32 бит в UTF-32. Следующие 1920 символов, от U + 0080 до U + 07FF (включая остаток почти всех алфавитов латинского алфавита, а также греческий, кириллица, Коптский, армянский, иврит, арабский, сирийский, тана и северный '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 с quoted-printable или 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). Распространенное заблуждение состоит в том, что существует необходимость «найти n-й символ» и что для этого требуется кодирование фиксированной длины; однако на практике число n получается только из проверки n − 1 символов, поэтому в любом случае необходим последовательный доступ. UTF-16BE и UTF-32BE - большие -endian, UTF-16LE и UTF-32LE - это little-endian. Когда последовательности символов в одном порядке байтов загружаются на машину с другим порядком байтов, символы необходимо преобразовать, прежде чем их можно будет эффективно обрабатывать, если только данные не обрабатываются с байтовой гранулярностью (как требуется для UTF-8). Соответственно, рассматриваемая проблема больше относится к протоколу и связи, чем к вычислительной сложности.

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

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

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

UTF-16 популярен, потому что многие API относятся ко времени, когда Unicode был 16-битной фиксированной шириной. Однако использование UTF-16 делает символы за пределами Basic Multilingual Plane особым случаем, что увеличивает риск упущений, связанных с их обработкой. Тем не менее, программы, которые неправильно обрабатывают суррогатные пары, вероятно, также имеют проблемы с объединением последовательностей, поэтому использование 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, и игнорировать mojibake для любых не-ASCII данные.

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

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

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

Подробно

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

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

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

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

Семибитовые среды

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

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

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

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

Схемы сжатия

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

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

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

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

Были сделаны предложения по UTF-5 и UTF-6 для интернационализации доменных имен (IDN). В предложении UTF-5 использовалась кодировка base 32, где Punycode является (среди прочего, но не совсем точной) кодировкой base 36. Имя UTF-5 для 5-битной кодовой единицы объясняется уравнением 2 = 32. Предложение UTF-6 добавило кодировку текущей длины в UTF-5, здесь 6 просто означает UTF-5. плюс 1. IETF IDN WG позже приняла более эффективный Punycode для этой цели.

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

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

UTF-9 и UTF-18, несмотря на то, что они были функциональными кодировками, были спецификациями шутки April Fools 'Day RFC.

Ссылки

Последняя правка сделана 2021-05-15 08:02:20
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте