Что такое лучший UTF

Я действительно запутался в UTF в Unicode.

имеются UTF-8, UTF-16 и UTF-32.

мой вопрос:

  • что UTF поддерживает все блоки Unicode?

  • Каков наилучший UTF (производительность, размер и т.д.) и почему?

  • Чем отличаются эти три UTF?

  • Что такое символы окончания и байтов (BOM)?

Спасибо

Ответ 1

что UTF поддерживает все блоки Unicode?

Все кодировки UTF поддерживают все блоки Unicode - нет кодировки UTF, которая не может представлять код Unicode. Однако некоторые не кодированные UTF кодировки, такие как UCS-2 (которые похожи на UTF-16, но не имеют суррогатных пар и, следовательно, не имеют возможности кодировать кодовые точки выше 65535/U + FFFF), не могут.

Каков наилучший UTF (производительность, размер и т.д.) и почему?

Для текстовых данных, которые в основном являются английским и/или просто ASCII, UTF-8 на сегодняшний день является наиболее эффективным с точки зрения пространства. Однако UTF-8 иногда менее эффективен по площади, чем UTF-16 и UTF-32, где большая часть используемых кодовых точек является высокой (например, большие тела текста CJK).

Чем отличаются эти три UTF?

UTF-8 кодирует каждый код Unicode от одного до четырех байтов. Значения Unicode от 0 до 127, которые совпадают с ASCII, кодируются так же, как и в ASCII. Байты со значениями от 128 до 255 используются для многобайтовых кодовых точек.

UTF-16 кодирует каждый код Unicode в двух байтах (одно значение UTF-16) или четыре байта (два значения UTF-16). Все, что содержится в базовой многоязычной плоскости (коды Unicode от 0 до 65535 или U + 0000 до U + FFFF) кодируются с одним значением UTF-16. Codepoints из более высоких равнин используют два значения UTF-16, используя метод, называемый суррогатными парами.

UTF-32 не является кодировкой переменной длины для Unicode; все кодовые значения Unicode кодируются как есть. Это означает, что U+10FFFF кодируется как 0x0010FFFF.

что обозначают суффикс и байты (BOM)?

Endianness - это то, как часть данных, определенная архитектура ЦП или количество заказов на протоколы многобайтовых типов данных. Маленькие системы (например, процессоры x86-32 и x86-64) сначала помещают наименее значимый байт, а системы с большими номерами (такие как ARM, PowerPC и многие сетевые протоколы) сначала помещают наиболее значительный байт.

В кодировке или системе с маленьким концом 32-битное значение 0x12345678 сохраняется или передается как 0x78 0x56 0x34 0x12. В кодировке или системе большого конца она сохраняется или передается как 0x12 0x34 0x56 0x78.

Значок байтового байта используется в UTF-16 и UTF-32, чтобы сигнализировать о том, какой текст должен интерпретироваться. Unicode делает это умным способом - U + FEFF является допустимым кодом, используемым для знака порядка байтов, тогда как U + FFFE - нет. Поэтому, если файл начинается с 0xFF 0xFE, можно предположить, что остальная часть файла хранится в порядке порядка байтов байтов.

Знак байтового байта в UTF-8 технически возможен, но по понятным причинам он не имеет смысла в контексте утверждения. Однако поток, который начинается с кодированной UTF-8 спецификации, почти наверняка подразумевает, что это UTF-8, и поэтому может быть использован для идентификации из-за этого.

Преимущества UTF-8

  • ASCII - это подмножество кодировки UTF-8 и поэтому является отличным способом введения текста ASCII в "мир Unicode" без необходимости выполнять преобразование данных.
  • Текст UTF-8 - это самый компактный формат для текста ASCII.
  • Действительный UTF-8 можно сортировать по байтовым значениям и приводить к отсортированным кодовым точкам

Преимущества UTF-16

  • UTF-16 проще декодировать UTF-8, хотя это кодирование с переменной длиной
  • UTF-16 более экономичен по площади, чем UTF-8 для символов в BMP, но вне ASCII

Преимущества UTF-32

  • UTF-32 не является переменной длиной, поэтому для декодирования не требуется специальной логики

Ответ 2

"Ответьте мне на эти вопросы четыре, поскольку все ответы были даны задолго до этого".

Вы действительно должны были задать один вопрос, а не четыре. Но вот ответы.

  • Все преобразования UTF по определению поддерживают все кодовые точки Юникода. Это то, о чем вам не нужно беспокоиться. Единственная проблема заключается в том, что некоторые системы действительно являются UCS-2, но утверждают, что они UTF-16, а UCS-2 сильно разбит несколькими фундаментальными способами:

    • UCS-2 не является допустимой кодировкой Unicode.
    • UCS-2 поддерживает только ¹/₁₇ᵗʰ Unicode. То есть, только плоскость 0, а не самолеты 1-16.
    • UCS-2 разрешает кодовые точки, которые гарантируют Unicode Standard никогда не будут в действительном Unicode-потоке. К ним относятся
      • все 2048 UTF-16 суррогатов, кодовые точки U + D800 через U + DFFF
      • 32 несимвольных кода между U + FDD0 и U + FDEF
      • оба часовых в U + FFEF и U + FFFF

    Для какой кодировки используется семь разных языков программирования, см. слайд 7 в разделе "Поддержка функций" в моем разговоре OSCON с прошлой недели под названием "Unicode Support Shootout" . Это сильно отличается.

  • UTF-8 - лучшее преобразование сериализации потока логических кодовых точек Unicode, поскольку в определенном порядке:

    • UTF-8 является стандартным стандартным кодированием Unicode в Интернете.
    • UTF-8 может быть сохранен в строке с нулевым завершением.
    • UTF-8 не имеет проблем с выпуском спецификации.
    • UTF-8 не мешает UCS-2 против UTF-16.
    • UTF-8 довольно компактно компилирует в основном текст ASCII, так что даже азиатские тексты, которые находятся в XML или HTML, часто заканчиваются меньшими байтами, чем UTF-16. Это важно знать, потому что это противоречивый и неожиданный результат. Теги разметки ASCII часто составляют дополнительный байт. Если вы действительно обеспокоены хранением, вы должны использовать надлежащее сжатие текста, например LZW и связанные с ним алгоритмы. Просто bzip.
    • Если это необходимо, его можно использовать для транс-юникодианных точек сколь угодно большой величины. Например, MAXINT на 64-битной машине становится 13 байтами, используя оригинальный алгоритм UTF-8. Однако это свойство имеет редкую полезность и должно использоваться с большой осторожностью, чтобы оно не ошибочно принималось за законный поток UTF-8.

    Я использую UTF-8 всякий раз, когда мне это удается.

  • Я уже дал свойства UTF-8, так что вот некоторые из них для двух других:

    • UTF-32 имеет исключительное преимущество для внутреннего хранилища: O (1) доступ к кодовой точке N. То есть, постоянный доступ к времени, когда вам нужен произвольный доступ. Помните, что мы всегда жили с O (N) доступом в функции Cs strlen, поэтому я не уверен, насколько это важно. У меня сложилось впечатление, что мы почти всегда обрабатываем наши строки в последовательном неслучайном порядке, и в этом случае это перестает быть проблемой. Да, это занимает больше памяти, но лишь незначительно в конечном итоге.
    • UTF-16 - ужасный формат, имеющий все недостатки UTF-8 и UTF-32, но ни одно из преимуществ этого.. С неохотой верно, что при правильной обработке UTF-16 безусловно, можно заставить работать, но это требует реальных усилий, и ваш язык может быть не там, чтобы помочь вам. Действительно, ваш язык, вероятно, будет работать против вас. Я работал с UTF-16 достаточно, чтобы узнать, что это за королевская боль. Я остался бы в стороне от обоих этих, особенно UTF-16, если у вас есть выбор в этом вопросе. Языковой поддержки почти никогда не бывает, потому что есть массивные стручки истерических морских свиней, которые все борются за внимание. Даже если существует правильная кодовая точка, а не механизмы доступа к кодовому блоку, они обычно неудобны для использования и длительной для ввода, и они не являются стандартными. Это слишком легко приводит к ошибкам, которые вы не можете поймать до развертывания; Поверьте мне в этом, потому что я был там.

    Вот почему я пришел поговорить о том, что есть проклятие UTF-16. Единственное, что хуже, чем проклятие UTF-16 - это проклятие UCS-2.

  • Endianness и вся спецификация BOM - это проблемы, которые проклинают как UTF-16, так и UTF-32. Если вы используете UTF-8, вам никогда не придется беспокоиться об этом.

Я уверен, что надеюсь, что вы используете логические (то есть абстрактные) коды внутри себя со всеми вашими API-интерфейсами и беспокоитесь о сериализации только для внешних обменов. Все, что заставляет вас получать коды кода вместо кодовых точек, гораздо более затруднительно, чем его ценность, независимо от того, имеют ли эти кодовые блоки ширину 8 бит или ширину 16 бит. Вам нужен интерфейс кодовой точки, а не интерфейс кода. Теперь, когда ваш API использует кодовые точки вместо блоков кода, фактическое базовое представление больше не имеет значения. Важно, чтобы это было скрыто.


Ошибки категории

Позвольте мне добавить, что все, кто говорит о ASCII и Unicode, делают ошибку категории. Unicode очень сильно НЕ, как ASCII, но с большим количеством символов. " Это может означать ISO 10646, но не описывает Unicode. Unicode - это не просто конкретный репертуар, а правила для их обработки. Не только больше символов, но и более персонажей, которые имеют особые правила, сопровождающие их. Юникод-символы без правил Юникода больше не являются символами Юникода.

Если вы используете мышью ASCII для обработки текста Юникода, вы снова и снова будете получать всевозможные нарушения. Это не работает. Как один из примеров этого, из-за этого недоразумения, что библиотека соответствия шаблону Python, re, делает неправильную вещь полностью, если вы не учитываете регистр без учета регистра. Он слепо предполагает, что две кодовые точки считаются одинаковыми, если оба имеют один и тот же строчный регистр. Это мышление ASCII, поэтому он терпит неудачу. Вы просто не можете рассматривать Unicode таким образом, потому что если вы нарушаете правила и больше не Unicode. Это просто беспорядок.

Например, Unicode определяет U + 03C3 GREEK SMALL LETTER SIGMA и U + 03C2 GREEK SMALL LETTER FINAL SIGMA как нечувствительные к регистру версии друг друга. (Это называется Unicode casefolding.) Но так как они не меняются, когда слепо отображаются в нижнем регистре и сравниваются, это сравнение терпит неудачу. Вы просто не можете это сделать. Вы не можете исправить это в общем случае, переключив сравнение в нижнем регистре в верхний регистр. Использование casemapping, когда вам нужно использовать casefolding, противоречит трепетному пониманию всех работ.

(И ничего не значит: Python 2 сломан еще хуже. Я рекомендую не использовать Python 2 для Unicode, использовать Python 3, если вы хотите делать Unicode в Python. Для Pythonistas я рекомендую решение для Python бесчисленное множество проблем с регулярным выражением Unicode является чудесной библиотекой regex Мэтью Барнетса для Python 2 и Python 3. Это действительно довольно аккуратно, и на самом деле это делает правильную реализацию Unicode правильной - среди многих других юникодовых вещей, которые стандартный re становится ужасно неправильным.)

ЗАПОМНИТЕ: Юникод - это не просто больше символов: Юникод - это правила обработки большего количества символов. Один из них учится работать с Unicode, иначе он работает против него, и если кто-то работает против него, то он действует против вас.

Ответ 3

  • Все они поддерживают все кодовые точки Unicode.

  • У них разные характеристики производительности - например, UTF-8 более компактен для символов ASCII, тогда как UTF-32 упрощает работу со всем Unicode, включая значения за пределами базовой многоязычной плоскости (т.е. выше U + FFFF). Из-за своей переменной ширины на символ строки UTF-8 трудно использовать для получения определенного символьного индекса в двоичном кодировании - вы просматриваете. То же самое верно для UTF-16, если вы не знаете, что нет символов без BMP.

  • Вероятно, проще всего просмотреть статьи wikipedia для UTF-8, UTF-16 и UTF-32

  • Endianness определяет (для UTF-16 и UTF-32), является ли самый старший байт первым, и младший байт приходит последним, или наоборот. Например, если вы хотите представить U + 1234 в UTF-16, это может быть либо {0x12, 0x34}, либо {0x34, 0x12}. Значок порядка байтов указывает, к какой цели вы имеете дело. UTF-8 не имеет разных понятий, но просмотр спецификации UTF-8 в начале файла является хорошим индикатором того, что это UTF-8.

Ответ 4

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

  • Как сказано ранее, все три охватывают полный набор возможных кодовых точек U + 0000 до U + 10FFFF.

  • Зависит от текста, но вот некоторые детали, которые могут представлять интерес. UTF-8 использует от 1 до 4 байт за char; UTF-16 использует 2 или 4; UTF-32 всегда использует 4. Полезно отметить это. Если вы используете UTF-8, тогда текст на английском языке будет закодирован с подавляющим большинством символов по одному байту каждый, но китайцам нужно 3 байта каждый. Использование UTF-16, английского и китайского будет требовать 2. Таким образом, в основном UTF-8 является победой для английского языка; UTF-16 - победа для китайцев.

  • Основное различие упоминается в ответе на № 2 выше, или, как говорит Джон Скит, см. статьи в Википедии.

  • Endianness: для UTF-16 и UTF-32 это относится к порядку, в котором появляются байты; например, в UTF-16, символ U + 1234 может быть закодирован либо как 12 34 (большой конец), либо 34 12 (маленький конец). Интересна спецификация BOM или байтового порядка. Скажем, у вас есть файл, закодированный в UTF-16, но вы не знаете, большой или маленький он, но вы заметили, что первые два байта файла FE FE. Если бы это было big-endian, то символ был бы U + FEFF; если бы немного endian, это означало бы U + FFFE. Но вот что: в Юникоде кодовая точка FFFE постоянно не назначена: там нет персонажа! Поэтому мы можем сказать, что кодировка должна быть большой. Характер FEFF здесь безвреден; это ZERO-WIDTH NO BREAK SPACE (невидимое, в основном). Точно так же, если файл начался с FF FE, мы знаем, что он немного аргументирован.

Не уверен, что я добавил что-либо к другим ответам, но я нашел конкретный анализ на английском и китайском, полезный для объяснения этого другим в прошлом.

Ответ 5

Один из способов взглянуть на него - это размер по сложности. Как правило, они увеличивают количество байтов, необходимых для кодирования текста, но уменьшают сложность декодирования схемы, которую они используют для представления символов. Поэтому UTF-8 обычно мал, но может быть сложным для декодирования, тогда как UTF-32 занимает больше байтов, но легко декодируется (но редко используется, UTF-16 является более распространенным).

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

Спецификации предназначены как информация в начале файлов, которая описывает, какая кодировка была использована. Эта информация часто отсутствует.