Отличаются ли UTF-8, UTF-16 и UTF-32 количеством символов, которые они могут хранить?

StackOverflow https://stackoverflow.com/questions/130438

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

Не существует символа Юникода, который мог бы быть сохранен в одной кодировке, но не в другой.Это просто потому, что допустимые символы Юникода были ограничены тем, что может быть сохранено в UTF-16 (который имеет наименьшую емкость из трех кодировок).Другими словами, UTF-8 и UTF-32 мог бы может использоваться для представления более широкого диапазона символов, чем 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.В противном случае декодер не смог бы отличить эти символы от буквы "А", за которой следует что-то еще.

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

Поскольку UTF-8 содержит 128 различных 1-байтовых символов (байтовые значения которых равны 0-127), все 2, 3 и 4-байтовые символы должны состоять исключительно из байтов в диапазоне 128-256.Это большое ограничение.Однако это позволяет байтово-ориентированным строковым функциям работать практически без изменений.Например, C's 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).

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).

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

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

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

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

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

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

Видишь Википедия для получения дополнительной информации.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top