В чем разница между UTF-8 и UTF-8 без спецификации? - PullRequest
735 голосов
/ 08 февраля 2010

Чем отличается UTF-8 от UTF-8 без спецификации ? Что лучше?

Ответы [ 20 ]

695 голосов
/ 08 февраля 2010

Спецификация UTF-8 - это последовательность байтов в начале текстового потока (EF BB BF), которая позволяет читателю более надежно угадывать файл как кодированный в UTF-8.

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

В соответствии со стандартом Unicode , BOM для файлов UTF-8 не рекомендуется :

2.6 Схемы кодирования

... Использование спецификации не требуется и не рекомендуется для UTF-8, но может быть встречаются в тех случаях, когда данные UTF-8 преобразуются из других формы кодирования, которые используют спецификацию или где спецификация используется в качестве UTF-8 подпись. См. Подраздел «Метка порядка следования байтов» в Раздел 16.8, Скидки , для получения дополнительной информации.

213 голосов
/ 08 февраля 2010

Другие отличные ответы уже ответили, что:

  • Официальной разницы между UTF-8 и спецификацией UTF-8
  • Строка UTF-8 с правкой спецификации начинается с трех следующих байтов. EF BB BF
  • Эти байты, если они есть, должны игнорироваться при извлечении строки из файла / потока.

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

Например, данные [EF BB BF 41 42 43] могут быть:

  • Допустимая ISO-8859-1 строка «ï» ¿ABC "
  • Допустимая UTF-8 строка "ABC"

Поэтому, хотя было бы здорово распознать кодировку содержимого файла, посмотрев на первые байты, вы не должны полагаться на это, как показано в примере выше

Кодировки должны быть известны, а не предсказаны.

116 голосов
/ 15 ноября 2012

Существует как минимум три проблемы с размещением спецификации в кодированных файлах UTF-8.

  1. Файлы, которые не содержат текста, больше не являются пустыми, поскольку они всегда содержат спецификацию.
  2. Файлы, содержащие текст, который находится в подмножестве ASCII UTF-8, больше не являются ASCII, поскольку спецификация не является ASCII, что приводит к поломке некоторых существующих инструментов, и пользователи могут не иметь возможности заменить такие устаревшие инструменты.
  3. Невозможно объединить несколько файлов вместе, поскольку каждый файл теперь имеет спецификацию в начале.

И, как уже упоминали другие, недостаточно или необходимо иметь спецификацию, чтобы обнаружить, что что-то является UTF-8:

  • Недостаточно, поскольку произвольная последовательность байтов может начинаться с точной последовательности, составляющей спецификацию.
  • В этом нет необходимости, потому что вы можете просто прочитать байты, как если бы они были UTF-8; если это удастся, это, по определению, действительный UTF-8.
69 голосов
/ 26 июня 2016

Это старый вопрос с множеством хороших ответов, но нужно добавить одну вещь.

Все ответы очень общие. Я хотел бы добавить примеры использования спецификации, которые на самом деле вызывают реальные проблемы, но многие люди об этом не знают.

сценарии разрыва спецификации

Сценарии оболочки, сценарии Perl, сценарии Python, сценарии Ruby, сценарии Node.js или любой другой исполняемый файл, который должен запускаться интерпретатором - все начинается с строки shebang , которая выглядит как одна из этих :

#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node

Сообщает системе, какой интерпретатор должен быть запущен при вызове такого скрипта. Если сценарий закодирован в UTF-8, может возникнуть соблазн включить вначале спецификацию. Но на самом деле "#!" персонажи не просто персонажи. На самом деле это магическое число , состоящее из двух символов ASCII. Если вы поместите что-то (например, спецификацию) перед этими символами, то файл будет выглядеть так, как будто он имеет другое магическое число, и это может привести к проблемам.

См. Википедию, статья: Шебанг, раздел: Магическое число :

Символы Шебанга представлены теми же двумя байтами в расширенные кодировки ASCII, включая UTF-8, который обычно используется для скрипты и другие текстовые файлы в современных Unix-подобных системах. Тем не мение, Файлы UTF-8 могут начинаться с дополнительной метки порядка байтов (BOM); если Функция "exec" специально определяет байты 0x23 и 0x21, затем наличие спецификации (0xEF 0xBB 0xBF) до того, как шебанг предотвратит интерпретатор сценария от исполнения. Некоторые власти рекомендуют против использования метки порядка байтов в сценариях POSIX (Unix-like), [14] по этой причине и для более широкого взаимодействия и философского проблемы. Кроме того, метка порядка следования байтов не требуется в UTF-8, поскольку у этой кодировки нет проблем с порядком байтов; это служит только для идентифицировать кодировку как UTF-8. [выделение добавлено]

Спецификация недопустима в JSON

См. RFC 7159, раздел 8.1 :

Реализации НЕ ДОЛЖНЫ добавлять метку порядка байтов в начало текста JSON.

Спецификация избыточна в JSON

Не только это недопустимо в JSON, но и не нужно для определения кодировки символов, поскольку существуют более надежные способы однозначного определения как кодировки символов, так и порядка байтов, используемого в любой поток JSON (подробности см. в этом ответе ).

спецификация ломает парсеры JSON

Мало того, что недопустимо в JSON и не нужно , на самом деле ломает все программное обеспечение , которое определяет кодировку с использованием метода, представленного в RFC 4627

Определение кодировки и порядкового номера JSON, проверка первых 4 байтов для байта NUL:

00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8

Теперь, если файл начинается с спецификации, он будет выглядеть так:

00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8

Обратите внимание, что:

  1. UTF-32BE не запускается с тремя NUL, поэтому он не будет распознаваться
  2. UTF-32LE, за первым байтом не следуют 3 NUL, поэтому он не будет распознан
  3. UTF-16BE имеет только 1 NUL в первых 4 байтах, поэтому он не будет распознан
  4. UTF-16LE имеет только 1 NUL в первых 4 байтах, поэтому он не будет распознан

В зависимости от реализации, все они могут быть неправильно интерпретированы как UTF-8, а затем неверно истолкованы или отклонены как недействительные UTF-8, или не распознаны вообще.

Кроме того, если реализация проверяет действительный JSON, как я рекомендую, он отклонит даже ввод, который действительно закодирован как UTF-8, потому что он не начинается с символа ASCII <128, как это должно быть в соответствии с RFC. </p>

Другие форматы данных

Спецификация в JSON не нужна, является незаконной и нарушает работу программного обеспечения, которое работает в соответствии с RFC. Это должен быть нобрейнер, чтобы просто не использовать его тогда, и тем не менее, всегда есть люди, которые настаивают на нарушении JSON, используя спецификации, комментарии, разные правила цитирования или разные типы данных. Конечно, любой может свободно использовать такие вещи, как спецификации или что-то еще, если вам это нужно - просто не называйте это JSON.

Для других форматов данных, кроме JSON, посмотрите, как они на самом деле выглядят. Если единственными кодировками являются UTF- * и первый символ должен быть символом ASCII ниже 128, то у вас уже есть вся информация, необходимая для определения как кодировки, так и порядкового номера ваших данных. Добавление спецификаций даже в качестве дополнительной функции сделает ее более сложной и подверженной ошибкам.

Другое использование спецификации

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

48 голосов
/ 01 августа 2010

Чем отличается UTF-8 от UTF-8 без спецификации?

Краткий ответ: в UTF-8 спецификация кодируется как байты EF BB BF в начале файла.

Длинный ответ:

Первоначально ожидалось, что Unicode будет закодирован в UTF-16 / UCS-2. Спецификация была разработана для этой формы кодирования. Когда у вас есть 2-байтовые единицы кода, необходимо указать, в каком порядке находятся эти два байта, и общее соглашение для этого заключается в том, чтобы включить символ U + FEFF в качестве «метки порядка байтов» в начале данных. Символ U + FFFE постоянно не назначен, поэтому его присутствие можно использовать для обнаружения неправильного порядка байтов.

UTF-8 имеет один и тот же порядок байтов независимо от порядкового номера платформы, поэтому знак порядка байтов не требуется. Однако это может произойти (как последовательность байтов EF BB FF) в данных, которые были преобразованы в UTF-8 из UTF-16, или как «подпись», чтобы указать, что данные являются UTF-8.

Что лучше?

Без. Как ответил Мартин Кот, стандарт Unicode не рекомендует его. Это вызывает проблемы с программным обеспечением, не поддерживающим спецификации.

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

29 голосов
/ 28 июня 2012

UTF-8 с спецификацией лучше определен. Я пришел к такому выводу трудным путем. Я работаю над проектом, в котором одним из результатов является файл CSV , включая символы Юникода.

Если файл CSV сохранен без спецификации, Excel считает, что это ANSI, и выдает бессмысленный текст. После добавления «EF BB BF» на передней панели (например, путем повторного сохранения его с помощью Блокнота с UTF-8; или Блокнота ++ с UTF-8 с спецификацией) Excel прекрасно его открывает.

В RFC 3629 рекомендуется добавлять символ BOM к текстовым файлам Unicode: «UTF-8, формат преобразования ISO 10646», ноябрь 2003 г. в http://tools.ietf.org/html/rfc3629 (эта последняя информация найдена в: http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html)

17 голосов
/ 11 июля 2011

Спецификация имеет тенденцию бум (не каламбур (sic)) где-то, где-нибудь. И когда он гремит (например, не распознается браузерами, редакторами и т. Д.), Он отображается как странные символы  в начале документа (например, файл HTML, JSON *). 1003 * ответ, RSS и т. Д.) И вызывает такие затруднения, как недавняя проблема с кодировкой, возникшая во время разговора Обамы в Twitter .

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

16 голосов
/ 03 октября 2014

Вопрос: Чем отличается UTF-8 от UTF-8 без спецификации? Что лучше?

Вот некоторые выдержки из статьи в Википедии о метке порядка следования байтов (BOM) , которая, как мне кажется, дает солидный ответ на этот вопрос.

О значении спецификации и UTF-8:

Стандарт Unicode разрешает BOM в UTF-8 , но не требует или порекомендуйте его использование. Порядок байтов не имеет значения в UTF-8, поэтому его Единственное использование в UTF-8 - сигнализировать в начале, что текстовый поток закодировано в UTF-8.

Аргумент для НЕ с использованием спецификации:

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

Аргумент FOR с использованием спецификации:

Аргумент в пользу использования спецификации состоит в том, что без нее эвристический анализ Требуется определить, какую кодировку символов использует файл. Исторически такой анализ, чтобы различать различные 8-битные кодировки, сложный, подверженный ошибкам, а иногда и медленный. Ряд библиотек доступны для облегчения задачи, такие как Mozilla Universal Charset Детектор и международные компоненты для Unicode.

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

В частности, Microsoft компиляторы и интерпретаторы, и многие части программного обеспечения в Microsoft Windows, такие как Блокнот, не будут правильно читать текст UTF-8, если в нем нет только символов ASCII или начинается с спецификации и добавит спецификацию в начало при сохранении текста как UTF-8. Документы Google добавят спецификацию, когда документ Microsoft Word загружается в виде простого текстового файла.

На что лучше, С или БЕЗ спецификация:

IETF рекомендует, чтобы, если протокол (а) всегда использовал UTF-8, или (b) имеет какой-либо другой способ указать, какая кодировка используется, тогда «СЛЕДУЕТ запрещать использование U + FEFF в качестве подписи».

Мой вывод:

Используйте спецификацию только , если совместимость с программным приложением абсолютно необходима.

Также обратите внимание, что хотя указанная статья в Википедии указывает на то, что многие приложения Microsoft используют BOM для правильного определения UTF-8, это не относится к всем приложениям Microsoft. Например, как указано @ barlop , при использовании командной строки Windows с UTF-8 & dagger; такие команды, как type и more, не ожидают, что спецификация присутствовать. Если спецификация присутствует, это может быть проблематично, как и для других приложений.


& крестик; Команда chcp предлагает поддержку UTF-8 ( без спецификации) через кодовую страницу 65001 .

7 голосов
/ 01 февраля 2015

Следует отметить, что для некоторых файлов у не должно быть спецификации даже в Windows. Примерами являются SQL*plus или VBScript файлы. Если такие файлы содержат спецификацию, вы получаете сообщение об ошибке при попытке их выполнить.

7 голосов
/ 08 февраля 2010

Цитируется внизу страницы Википедии в спецификации: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2

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

...