Могут ли кодировки Unicode UTF-8, UTF-16 и UTF-32 различать количество символов, которые они могут хранить? - программирование
Подтвердить что ты не робот

Могут ли кодировки Unicode UTF-8, UTF-16 и UTF-32 различать количество символов, которые они могут хранить?

Хорошо. Я знаю, что это похоже на типичный "Почему он просто не просто Google или не зашел на сайт www.unicode.org и не посмотрел?" вопрос, но для такого простого вопроса ответ все еще ускользает от меня после проверки обоих источников.

Я уверен, что все три из этих систем кодирования поддерживают все символы Юникода, но мне нужно подтвердить это, прежде чем я сделаю это выражение в презентации.

Бонусный вопрос: отличаются ли эти кодировки количеством символов, которые могут быть расширены для поддержки?

4b9b3361

Ответ 1

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

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

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

UTF-16 использует два байта для большинства символов, четыре байта для необычных.

http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

Ответ 2

Нет символа Unicode, который может быть сохранен в одной кодировке, но не другой. Это просто потому, что действительные символы Юникода были ограничены тем, что можно сохранить в UTF-16 (который имеет наименьшую емкость трех кодировок). Другими словами, UTF-8 и UTF-16 могут использоваться для представления более широкого диапазона символов, чем UTF-16, но это не так. Читайте дальше для более подробной информации.

UTF-8

UTF-8 - это код переменной длины. Для некоторых символов требуется 1 байт, для некоторых требуется 2, некоторые 3 и некоторые 4. Байты для каждого символа просто записываются один за другим как непрерывный поток байтов.

Хотя некоторые символы UTF-8 могут иметь длину 4 байта, UTF-8 не может кодировать 2 ^ 32 символа. Он даже не закрывается. Я попытаюсь объяснить причины этого.

Программное обеспечение, которое считывает поток UTF-8, просто получает последовательность байтов - как это должно решить, будут ли следующие 4 байта одиночным 4-байтовым символом или двумя 2-байтовыми символами или четырьмя 1-байтовыми символов (или какой-либо другой комбинации)? В основном это делается путем принятия решения о том, что некоторые 1-байтовые последовательности не являются допустимыми символами, а некоторые 2-байтовые последовательности не являются допустимыми символами и т.д. Когда появляются эти недопустимые последовательности, предполагается, что они являются частью более длинной последовательности.

Вы видели совсем другой пример этого, я уверен: он вызвал экранирование. Во многих языках программирования принято решение, что символ \ в исходном коде строки не переводится на любой допустимый символ в форме "скомпилированный". Когда a\находится в источнике, предполагается, что он является частью более длинной последовательности, например \n или \xFF. Обратите внимание, что \x является недопустимой 2-символьной последовательностью, а \xF является недопустимой 3-символьной последовательностью, но \xFF является допустимой 4-символьной последовательностью.

В принципе, существует компромисс между наличием множества символов и более короткими символами. Если вам нужно 2 ^ 32 символа, они должны быть в среднем 4 байта. Если вы хотите, чтобы все ваши символы были 2 байта или меньше, вы не можете иметь более 2 ^ 16 символов. UTF-8 дает разумный компромисс: все ASCII символы (ASCII от 0 до 127) получают 1-байтные представления, что отлично подходит для совместимости, но допускается еще много символов.

Как и большинство кодировок переменной длины, включая типы escape-последовательностей, показанные выше, UTF-8 является мгновенным кодом. Это означает, что декодер просто считывает байты по байтам, и как только он достигает последнего байта символа, он знает, что такое символ (и он знает, что это не начало более длинного символа).

Например, символ "A" представлен с использованием байта 65, и нет двух/трех/четырехбайтовых символов, первый байт которого равен 65. В противном случае декодер не сможет отличить эти символы от "A", за которым следует что-то еще.

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

Поскольку UTF-8 имеет 128 разных 1-байтовых символов (значения байтов которых равны 0-127), все 2, 3 и 4-байтовые символы должны состоять только из байтов в диапазоне 128-256. Это большое ограничение. Тем не менее, он позволяет байт-ориентированные строковые функции работать с небольшой или никакой модификацией. Например, функция C strstr() всегда работает так, как ожидалось, если ее входы действительны для строк UTF-8.

UTF-16

UTF-16 также является кодом переменной длины; его символы потребляют либо 2, либо 4 байта. 2-байтовые значения в диапазоне 0xD800-0xDFFF зарезервированы для построения 4-байтовых символов, а все 4-байтовые символы состоят из двух байтов в диапазоне 0xD800-0xDBFF, за которым следуют 2 байта в диапазоне 0xDC00-0xDFFF. По этой причине Unicode не назначает никаких символов в диапазоне U + D800-U + DFFF.

UTF-32

UTF-32 - это код с фиксированной длиной, каждый из которых имеет длину 4 байта. Хотя это позволяет кодировать 2 ^ 32 разных символа, в этой схеме допускаются только значения от 0 до 0x10FFFF.

Сравнение производительности:

  • UTF-8: 2,097,152 (на самом деле 2,166,912, но из-за деталей дизайна некоторые из них относятся к одному и тому же)
  • UTF-16: 1,112,064
  • UTF-32: 4 294 967 296 (но ограничено первым 1,114,112)

Таким образом, самым ограниченным является UTF-16! Формальное определение Unicode ограничивало символы Unicode теми, которые могут быть закодированы с помощью UTF-16 (т.е. Диапазон U + 0000 до U + 10FFFF, за исключением U + D800, U + DFFF). UTF-8 и UTF-32 поддерживают все эти символы.

Система UTF-8 фактически "искусственно" ограничена 4 байтами. Он может быть расширен до 8 байтов, не нарушая ограничений, описанных ранее, и это даст пропускную способность 2 ^ 42. Исходная спецификация UTF-8 фактически допускала до 6 байтов, что дает емкость 2 ^ 31. Но RFC 3629 ограничил это 4 байтами, так как это необходимо, чтобы покрыть все, что делает UTF-16.

Существуют и другие (в основном исторические) схемы кодирования Unicode, в частности UCS-2 (который способен кодировать U + 0000 до U + FFFF).

Ответ 3

UTF-8, UTF-16 и UTF-32 поддерживают полный набор кодов Unicode. Нет символов, которые поддерживаются одним, но не другим.

Что касается вопроса о бонусе "Различаются ли эти кодировки в количестве символов, которые могут быть расширены для поддержки?" Да и нет. Способ кодирования UTF-8 и UTF-16 ограничивает общее количество кодовых точек, которые они могут поддерживать до менее чем 2 ^ 32. Однако Консорциум Unicode не будет добавлять кодовые точки в UTF-32, которые не могут быть представлены в UTF-8 или UTF-16. Это нарушит дух стандартов кодирования и сделает невозможным гарантировать взаимно однозначное отображение от UTF-32 до UTF-8 (или UTF-16).

Ответ 4

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

Ответ 5

Все кодировки UTF-8/16/32 могут отображать все символы Unicode. См. Википедия Сравнение кодировок Unicode.

Эта статья IBM Кодировать ваши документы XML в UTF-8 очень полезно и указывает, есть ли у вас выбор, лучше выбрать UTF-8. Главным образом причины - это широкая поддержка инструмента, и UTF-8 обычно может проходить через системы, которые не знают о unicode.

Из раздела Что говорят спецификации в статья IBM:

Оба W3C и IETF имеют недавно стали более категоричными выбирая UTF-8 первый, последний и иногда только. Символ W3C Модель для World Wide Web 1.0: Основы гласят: "Когда уникальная требуется кодирование символов, кодировка символов ДОЛЖНА быть UTF-8, UTF-16 или UTF-32. US-ASCII - совместим с UTF-8 ( Строка US-ASCII также является UTF-8 строка, см. [RFC 3629]), а UTF-8 - поэтому целесообразно, если совместимость с US-ASCII." В практика, совместимость с US-ASCII настолько полезен, что это почти требование. W3C мудро объясняет, "В других ситуациях, например, для API, UTF-16 или UTF-32 могут быть больше подходящее. Возможные причины выбор одного из них включает эффективности внутренней обработки и совместимость с другими процессы".

Ответ 6

Как все говорили, UTF-8, UTF-16 и UTF-32 могут кодировать все кодовые точки Юникода. Однако вариант UCS-2 (иногда ошибочно называемый UCS-16) не может , и это тот, который вы найдете, например. в Windows XP/Vista​​strike > .

Подробнее см. Wikipedia.

Изменить: Я ошибаюсь в отношении Windows, NT был единственным, кто поддерживал UCS-2. Тем не менее, многие приложения Windows будут использовать одно слово для кодовой точки, как в UCS-2, поэтому вы, вероятно, найдете ошибки. См. еще одна статья в Википедии. (Спасибо JasonTrue)