Сравнение кодировок Unicode
![]() | Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( Июль 2019 г. ) |
В этой статье сравниваются кодировки Unicode . Рассматриваются две ситуации: 8-битные чистые среды (что можно предположить) и среды, которые запрещают использование байтовых значений, у которых установлен старший бит. Первоначально такие запреты должны были разрешать ссылки, которые использовали только семь бит данных, но они остаются в некоторых стандартах, и поэтому некоторое программное обеспечение, соответствующее стандартам, должно генерировать сообщения, соответствующие ограничениям. Стандартная схема сжатия для Юникода и двоичное упорядоченное сжатие для Юникода исключены из сравнительных таблиц, поскольку их размер сложно просто определить количественно.
Проблемы совместимости [ править ]
Файл 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 используется для Юникода. Одним из редких контрпримеров является «строчный» файл, используемый приложениями macOS ( Mac OS X 10.3 Panther и более поздних версий) для поиска интернационализированных версий сообщений, которые по умолчанию используют UTF-16, с «файлами, закодированными с использованием UTF-8... не гарантированно сработает». [1]
XML , по соглашению , кодируется как UTF-8, и все процессоры XML должны поддерживать как минимум UTF-8 (включая US-ASCII по определению) и UTF-16. [2]
Эффективность [ править ]
UTF-8 требует 8, 16, 24 или 32 бита (от одного до четырех байтов ) для кодирования символа Юникода, UTF-16 требует 16 или 32 бита для кодирования символа, а UTF-32 всегда требует 32 бита для кодирования символа. . Первые 128 кодовых точек Юникода , от U+0000 до U+007F, которые используются для элементов управления C0 и символов базовой латиницы и которые взаимно однозначно соответствуют их эквивалентам в коде ASCII, кодируются с использованием 8 бит в UTF-8, 16. бит в UTF-16 и 32 бита в UTF-32.
Следующие 1920 символов, от U+0080 до U+07FF (охватывающие остаток почти всех латинских алфавитов , а также греческий , кириллический , коптский , армянский , иврит , арабский , сирийский , тана и нко ), требуют 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-8 короче, чем в UTF-16, если кодовых точек ASCII больше, чем кодовых точек в диапазоне от U+0800 до U+FFFF. Удивительным результатом является то, что реальные документы, написанные на языках, которые используют символы только в верхнем диапазоне, по-прежнему часто короче в UTF-8 из-за широкого использования пробелов, цифр, знаков препинания, символов новой строки, HTML-разметки и встроенных слов. аббревиатуры, написанные латинскими буквами. [3] UTF-32 всегда длиннее, если нет кодовых точек меньше U+10000.
Все печатаемые символы в UTF-EBCDIC используют по крайней мере столько же байтов, сколько и в UTF-8, а большинство из них используют больше из-за принятого решения разрешить кодирование управляющих кодов C1 в виде отдельных байтов. Для семибитных сред UTF-7 более эффективно использует пространство, чем комбинация других кодировок Unicode с Quote-printable или Base64 почти для всех типов текста (см. « Семибитные среды » ниже).
Время обработки [ править ]
Текст с кодировкой переменной длины, например UTF-8 или UTF-16, сложнее обрабатывать, если необходимо работать с отдельными единицами кода, а не с последовательностями единиц кода. На поиск не влияет то, имеют ли символы переменный размер, поскольку при поиске последовательности кодовых единиц не учитываются деления (для этого требуется, чтобы кодировка была самосинхронизирующейся , как и UTF-8, и UTF-16). Распространенным заблуждением является то, что необходимо «найти n -й символ» и что для этого требуется кодирование фиксированной длины; однако в реальном использовании число n получается только в результате проверки n-1 символов, поэтому в любом случае необходим последовательный доступ. [ нужна ссылка ]
Когда последовательности символов с одним порядком байтов загружаются на машину с другим порядком байтов, символы необходимо преобразовать, прежде чем их можно будет эффективно обработать (или необходимы два процессора). Байтовые кодировки, такие как UTF-8, не имеют этой проблемы. UTF-16BE и UTF-32BE — с прямым порядком байтов , UTF-16LE и UTF-32LE — с прямым порядком байтов .
Проблемы с обработкой [ править ]
Для обработки формат должен быть простым для поиска, усечения и, как правило, безопасным для обработки. Все обычные кодировки Unicode используют ту или иную форму кодовой единицы фиксированного размера. В зависимости от формата и кодовой точки, подлежащей кодированию, одна или несколько этих кодовых единиц будут представлять кодовую точку Юникода . Чтобы облегчить поиск и усечение, последовательность не должна встречаться внутри более длинной последовательности или пересекать границу двух других последовательностей. UTF-8, UTF-16, UTF-32 и UTF-EBCDIC обладают этими важными свойствами, а UTF-7 и GB 18030 — нет.
Символы фиксированного размера могут быть полезны, но даже если существует фиксированное количество байтов на одну кодовую точку (как в UTF-32), фиксированное количество байтов на отображаемый символ не существует из-за комбинирования символов . Учитывая эти несовместимости и другие особенности различных схем кодирования, обработка данных Юникода с помощью одного и того же (или совместимого) протокола во всех интерфейсах (например, использование API/библиотеки, обработка символов Юникода в модели клиент/сервер и т. д.) в целом может упростить весь конвейер, одновременно устраняя потенциальный источник ошибок.
UTF-16 популярен, потому что многие API появились в то время, когда Unicode имел 16-битную фиксированную ширину (так называемую UCS-2). Однако использование 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 может обрабатывать измененные байты, но не нечетное количество пропущенных байтов, которые искажают весь следующий текст (хотя и создают необычные и/или неназначенные символы). [б] Если биты могут быть потеряны, все они исказят следующий текст, хотя UTF-8 можно повторно синхронизировать, поскольку неправильные границы байтов приведут к недопустимому UTF-8 почти во всем тексте длиной более нескольких байт.
Подробно [ править ]
В таблицах ниже указано количество байтов на кодовую точку для разных диапазонов Юникода. Любые дополнительные комментарии включены в таблицу. На рисунках предполагается, что накладные расходы в начале и конце блока текста незначительны.
NB. В таблицах ниже указано количество байтов на кодовую точку , а не на видимый пользователем «символ» (или «кластер графем»). Для описания одного кластера графем может потребоваться несколько кодовых точек, поэтому даже в UTF-32 необходимо соблюдать осторожность при разделении или объединении строк.
Восьмибитные среды [ править ]
Диапазон кода (шестнадцатеричный) | UTF-8 | UTF-16 | UTF-32 | UTF-EBCDIC | ГБ 18030 |
---|---|---|---|---|---|
000000 – 00007F | 1 | 2 | 4 | 1 | 1 |
000080 – 00009F | 2 | 2 для персонажей, унаследованных от ГБ 2312 / ГБК (например, сейчас китайские иероглифы) 4 для все остальное. | |||
0000A0 – 0003FF | 2 | ||||
000400 – 0007FF | 3 | ||||
000800 – 003FFF | 3 | ||||
004000 – 00FFFF | 4 | ||||
010000 – 03FFFF | 4 | 4 | 4 | ||
040000 – 10FFFF | 5 |
Семибитные среды [ править ]
Эта таблица не может охватывать все особые случаи, поэтому ее следует использовать только для оценки и сравнения. Чтобы точно определить размер текста в кодировке, смотрите актуальные характеристики.
Диапазон кода (шестнадцатеричный) | UTF-7 | UTF-8 цитируется- для печати | UTF-8 базовый64 | UTF-16 q.-p. | UTF-16 (база64) | ГБ 18030 кв.-п. | ГБ 18030 база64 |
---|---|---|---|---|---|---|---|
ASCII графические персонажи (кроме U+003D "=") | 1 для «прямых символов» (зависит от настроек кодировщика для некоторых кодовых точек), 2 для U+002B «+», в остальном то же, что и для 000080 – 00FFFF | 1 | 1 + 1 ⁄ 3 | 4 | 2 + 2 ⁄ 3 | 1 | 1 + 1 ⁄ 3 |
00003D (знак равенства) | 3 | 6 | 3 | ||||
ASCII управляющие символы : 000000 – 00001F и 00007F | 1 или 3 в зависимости от направленности | 1 или 3 в зависимости от направленности | |||||
000080 – 0007FF | 5 для единичного случая внутри серии однобайтовых символов. Для пробежек 2 + 2 ⁄ 3 на символ плюс заполнение, чтобы получить целое число байтов плюс два для начала и завершения выполнения. | 6 | 2 + 2 ⁄ 3 | 2–6 в зависимости от того, нужно ли экранировать значения байтов | 4–6 для символов, унаследованных от GB2312/GBK (например, большинство китайских иероглифов) 8 для всего остального. | 2 + 2 ⁄ 3 для символов, унаследованных от GB2312/GBK (например, большинство китайских иероглифов) 5 + 1 / 3 на все остальное. | |
000800 – 00FFFF | 9 | 4 | |||||
010000 – 10FFFF | 8 для единичного случая, 5 + 1 ⁄ 3 на символ плюс заполнение до целого числа плюс 2 для запуска | 12 | 5 + 1 ⁄ 3 | 8–12 в зависимости от того, нужно ли экранировать младшие байты суррогатов. | 5 + 1 ⁄ 3 | 8 | 5 + 1 ⁄ 3 |
Порядок байтов не влияет на размеры ( UTF-16BE и UTF-32BE имеют тот же размер, что и UTF-16LE и UTF-32LE соответственно).Использование UTF-32 под quote-printable крайне непрактично, но в случае реализации приведет к тому, что на одну кодовую точку будет приходиться 8–12 байт (в среднем около 10 байт), а именно для BMP каждая кодовая точка будет занимать ровно на 6 байт больше, чем тот же код в Quote-printable/UTF-16. Base64/UTF-32 получает 5 + 1/3 кодовой байта для любой точки.
Управляющий символ ASCII в формате Quote-printable или 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 5 = 32. [4] Предложение UTF-6 добавило кодировку длины к UTF-5, здесь 6 просто означает UTF-5 плюс 1 . [5] Позже рабочая группа IETF по IDN приняла для этой цели более эффективный Punycode . [6]
Не подвергается серьезному преследованию [ править ]
UTF-1 так и не получил серьезного признания. UTF-8 используется гораздо чаще.
Нонет - кодировки UTF-9 и UTF-18 являются первоапрельскими спецификациями RFC, хотя UTF-9 — это действующий формат преобразования Unicode для нонетов, а UTF-18 — это действующая нонет-кодировка для всех кодовых точек, не предназначенных для частного использования. Unicode 12 и более поздних версий, но не для дополнительных областей частного использования или частей Unicode 13 и более поздних версий .
Примечания [ править ]
- ^ Программное обеспечение ASCII, не использующее нулевые символы для завершения строк, будет правильно обрабатывать файлы в кодировке UTF-16 и UTF-32 (такие файлы, если они содержат только символы подмножества ASCII, будут выглядеть как обычные ASCII, дополненные нулевыми символами ), но такое программное обеспечение не является общий.
- ^ количество пропущенных байтов в UTF-16 приведет к искажению не более одного символа. четное Напротив,
Ссылки [ править ]
- ^ «Apple Developer Connection: темы интернационализации программирования: строковые файлы» .
- ^ «Кодировка символов в сущностях» . Расширяемый язык разметки (XML) 1.0 (пятое издание) . Консорциум Всемирной паутины . 2008.
- ^ «UTF-8 везде» . utf8everwhere.org . Проверено 28 августа 2022 г.
- ^ Сенг, Джеймс, UTF-5, формат преобразования Unicode и ISO 10646 , 28 января 2000 г.
- ^ Велтер, Марк; Споларич, Брайан В. (16 ноября 2000 г.). «UTF-6 — еще одна ASCII-совместимая кодировка для идентификаторов» . Ietf Datatracker . Архивировано из оригинала 23 мая 2016 года . Проверено 9 апреля 2016 г.
- ^ «Интернационализированное доменное имя (idn)» . Рабочая группа по интернет-инжинирингу . Проверено 20 марта 2023 г.