Какие проблемы возникнут при обработке UTF-16 как фиксированной 16-битной кодировки? - PullRequest
4 голосов
/ 21 февраля 2011

Я читал несколько вопросов о SO по поводу Unicode, и были некоторые комментарии, которые я не до конца понял, как этот:

Дин Хардинг : UTF-8 является кодирование переменной длины, которое сложнее обрабатывать, чем кодирование фиксированной длины. Кроме того, см. Мой комментирует ответ Гамбо: в основном, объединяющие символы существуют во всех кодировки (UTF-8, UTF-16 и UTF-32) и они требуют особого обращения. Вы можете использовать ту же специальную обработку, которую вы использовать для объединения символов, чтобы также обрабатывать суррогатные пары в UTF-16, поэтому по большей части вы можете игнорировать суррогаты и относиться к UTF-16 так же, как фиксированная кодировка.

Я немного смущен последней частью ("по большей части"). Если UTF-16 рассматривается как фиксированное 16-битное кодирование, какие проблемы это может вызвать? Каковы шансы, что есть персонажи за пределами BMP? Если есть, какие проблемы это может вызвать, если вы предполагаете двухбайтовые символы?

Я прочитал информацию из Википедии на Суррогаты , но это не очень-то мне помогло!

Редактировать: Я думаю, что на самом деле я имею в виду "Почему кто-то предложил бы рассматривать UTF-16 как фиксированное кодирование, когда оно кажется поддельным?"

Edit2:

Я нашел еще один комментарий в " Есть ли какая-либо причина, чтобы предпочесть UTF-16, а не UTF-8? ", что, я думаю, объясняет это немного лучше:

Эндрю Рассел : Для исполнения: UTF-8 гораздо сложнее декодировать, чем UTF-16. В UTF-16 символы либо базовая многоязычная плоскость символ (2 байта) или суррогат Пара (4 байта). UTF-8 символов может быть где-то между 1 и 4 байтами

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

Ответы [ 4 ]

3 голосов
/ 21 февраля 2011

UTF-16 включает все символы "базовой плоскости" .BMP охватывает большинство современных систем письма и включает в себя множество старых символов, с которыми можно практически столкнуться.Посмотрите на них и решите, действительно ли вы столкнетесь с какими-либо персонажами из расширенных плоскостей: клинописью, алхимическими символами и т. Д. Мало кто действительно будет по ним скучать.

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

Таким образом, проблемы, возникающие из-за того, что обработка UTF-16 эффективна в отношении ОСК-2, минимальны, за исключением того факта, что вы надеваетене обрабатывать расширенные символы.

РЕДАКТИРОВАТЬ: Юникод использует «комбинирующие метки», которые визуализируются в пространстве предыдущего символа, такие как акценты, тильда, окружность и т. д. Иногда комбинациядиакритический знак с буквой может быть представлен в виде отдельной кодовой точки, например, может быть представлен как один \u00e1 вместо простого 'a' + акцента, равного \u0061\u0301.Тем не менее, вы не можете представлять необычные комбинации, такие как как одну кодовую точку.Это делает алгоритмы поиска и разбиения немного сложнее.Если вы каким-либо образом сделаете ваши строковые данные единообразными (например, только с использованием простых букв и комбинирующих меток), поиск и разбиение снова станут простыми, но в любом случае вы потеряете свойство 'одна позиция - один символ' .Симметричная проблема возникает, если вы серьезно занимаетесь набором текста и хотите явно хранить лигатуры, например if или , где одна кодовая точка соответствует 2 или 3 символам.Это не проблема UTF, это проблема Unicode в целом, AFAICT.

3 голосов
/ 21 февраля 2011

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

Чтобы ответить на ваш вопрос - наиболее очевидная проблема, связанная с обработкой UTF-16 как формы кодирования фиксированной длины, заключается в разрыве строки в середине суррогатной пары, чтобы вы получили две недопустимые кодовые точки. Все зависит от того, что вы делаете с текстом.

2 голосов
/ 22 февраля 2011

Полагаю, что я на самом деле имею в виду: «Почему кто-то предложил бы рассматривать UTF-16 как фиксированную кодировку, когда она кажется фиктивной?»

Два слова: Обратная совместимость.

Изначально Unicode предназначался для использования 16-разрядного кодирования фиксированной ширины (UCS-2), поэтому первые пользователи Unicode (например, Sun с Java и Microsoft с Windows NT) использовали16-битный тип символов.Когда выяснилось, что 65 536 символов недостаточно для всех, был разработан UTF-16, чтобы позволить этим 16-битным системам символов представлять 16 новых «плоскостей».

Это означало, что символы не былибольше фиксированной ширины, поэтому люди создали рационализацию, что «все в порядке, потому что UTF-16 имеет почти фиксированную ширину».

Но я все еще не уверен, что это немного отличаетсяПредполагая, что UTF-8 является однобайтовыми символами!

Строго говоря, это , а не .Вы получите неверные результаты для таких вещей, как "\uD801\uDC00".lower().

Однако, если предположить, что UTF-16 является фиксированной шириной, вероятность ее поломки будет меньше, чем при условии, что UTF-8 является фиксированной шириной.Символы, не входящие в ASCII, очень распространены на других языках, кроме английского, но символы, отличные от BMP, очень редки.

Вы можете использовать ту же специальную обработку, которую вы используете для объединения символов, чтобы обрабатывать суррогатные пары вUTF-16

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

В частности, символы в последовательности объединения могут быть преобразованы в другую форму кодированиясимволов за раз.

>>> 'a'.encode('UTF-8') + '\u0301'.encode('UTF-8')
b'a\xcc\x81'

Но не суррогаты:

>>> '\uD801'.encode('UTF-8') + '\uDC00'.encode('UTF-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode character '\ud801' in position 0: surrogates not allowed
0 голосов
/ 21 февраля 2011

UTF-16 - кодировка переменной длины.Старшего UCS-2 нет.Если вы рассматриваете кодирование переменной длины как фиксированное (постоянная длина), вы рискуете ввести ошибку всякий раз, когда вы используете «число 16-битных чисел» для обозначения «количества символов», поскольку число символов может фактически быть меньше числа16-битные величины.

...