В чем разница между UTF-8 и UTF-8 без спецификации?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

BOM разбивает скрипты

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

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

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

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

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

Спецификация незаконна в JSON

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

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

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

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

BOM разрывает парсер 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.

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

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

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

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

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

В чем разница между 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 не рекомендует. Это вызывает проблемы с программным обеспечением, отличным от BOM.

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

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

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

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

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

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

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

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

По значению спецификации и UTF-8:

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

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

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

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

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

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

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

На чем лучше, WITH или без спецификации:

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

Мой вывод:

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

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


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

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

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

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

Я использую несколько языков (даже кириллицу ) на своих страницах в течение длительного времени, и когда файлы сохраняются без спецификации, и я повторно открываю их для редактирования с помощью редактора (как отметил cherouvim ), некоторые символы повреждены.

Обратите внимание, что classический « Блокнот» Windows автоматически сохраняет файлы с помощью спецификации при попытке сохранить только что созданный файл с кодировкой UTF-8.

Я лично сохраняю файлы сценариев на стороне сервера (.asp, .ini, .aspx) с BOM и .html файлами без спецификации .

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

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

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

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

Но это не тот случай, когда у нас есть текстовые, CSV и XML-файлы, как в Windows, так и в Linux.

Например, текстовый файл в Windows или Linux, один из самых простых вещей, который можно себе представить, не является (обычно) UTF-8.

Сохраните его как XML и объявите его как UTF-8:

  

Он не будет отображаться (он не будет считан) правильно, даже если он объявлен как UTF-8.

У меня была строка данных, содержащих французские буквы, которые нужно было сохранить как XML для синдикации. Без создания файла UTF-8 с самого начала (изменение параметров в IDE и «Создать новый файл») или добавление спецификации в начале файла

 $file="\xEF\xBB\xBF".$string; 

Я не смог сохранить французские буквы в XML-файле.

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

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

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

Не делайте ничего ожидаемого спецификации для UTF8.

У этого вопроса уже есть ответы на миллион и один, и многие из них довольно хороши, но я хотел попытаться уточнить, когда спецификация должна или не должна использоваться.

Как уже упоминалось, любое использование спецификации UTF (знак порядка байтов) при определении того, является ли строка UTF-8 или нет, является просвещенным догадкой. Если имеются доступные метаданные (например, charset="utf-8" ), то вы уже знаете, что вы должны использовать, но в противном случае вам нужно будет протестировать и сделать некоторые предположения. Это включает в себя проверку того, начинается ли файл, с которого начинается строка, с шестнадцатеричным байтовым кодом EF BB BF.

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

Почему спецификация не рекомендуется?

  1. Non-Unicode-aware or poorly compliant software may assume it’s latin-1 or ANSI and won’t strip the BOM from the string, which can obviously cause issues.
  2. It’s not really needed (just check if the contents are compliant and always use UTF-8 as the fallback when no compliant encoding can be found)

When should you encode with a BOM?

If you’re unable to record the metadata in any other way (through a charset tag or file system meta), and the programs being used like BOMs, you should encode with a BOM. This is especially true on Windows where anything without a BOM is generally assumed to be using a legacy code page. The BOM tells programs like Office that, yes, the text in this file is Unicode; here’s the encoding used.

When it comes down to it, the only files I ever really have problems with are CSV. Depending on the program, it either must, or must not have a BOM. For example, if you’re using Excel 2007+ on Windows, it must be encoded with a BOM if you want to open it smoothly and not have to resort to importing the data.

One practical difference is that if you write a shell script for Mac OS X and save it as plain UTF-8, you will get the response:

 #!/bin/bash: No such file or directory 

in response to the shebang line specifying which shell you wish to use:

 #!/bin/bash 

If you save as UTF-8, no BOM (say in BBEdit ) all will be well.

As mentioned above, UTF-8 with BOM may cause problems with non-BOM-aware (or compatible) software. I once edited HTML files encoded as UTF-8 + BOM with the Mozilla-based KompoZer , as a client required that WYSIWYG program.

Invariably the layout would get destroyed when saving. It took my some time to fiddle my way around this. These files then worked well in Firefox, but showed a CSS quirk in Internet Explorer destroying the layout, again. After fiddling with the linked CSS files for hours to no avail I discovered that Internet Explorer didn’t like the BOMfed HTML file. Never again.

Also, I just found this in Wikipedia:

The shebang characters are represented by the same two bytes in extended ASCII encodings, including UTF-8, which is commonly used for scripts and other text files on current Unix-like systems. However, UTF-8 files may begin with the optional byte order mark (BOM); if the “exec” function specifically detects the bytes 0x23 0x21, then the presence of the BOM (0xEF 0xBB 0xBF) before the shebang will prevent the script interpreter from being executed. Some authorities recommend against using the byte order mark in POSIX (Unix-like) scripts,[15] for this reason and for wider interoperability and philosophical concerns

From http://en.wikipedia.org/wiki/Byte-order_mark :

The byte order mark (BOM) is a Unicode character used to signal the endianness (byte order) of a text file or stream. Its code point is U+FEFF. BOM use is optional, and, if used, should appear at the start of the text stream. Beyond its specific use as a byte-order indicator, the BOM character may also indicate which of the several Unicode representations the text is encoded in.

Always using a BOM in your file will ensure that it always opens correctly in an editor which supports UTF-8 and BOM.

My real problem with the absence of BOM is the following. Suppose we’ve got a file which contains:

 abc 

Without BOM this opens as ANSI in most editors. So another user of this file opens it and appends some native characters, for example:

 abg-αβγ 

Oops… Now the file is still in ANSI and guess what, “αβγ” does not occupy 6 bytes, but 3. This is not UTF-8 and this causes other problems later on in the development chain.

The Unicode Byte Order Mark (BOM) FAQ provides a concise answer:

Q: How I should deal with BOMs?

A: Here are some guidelines to follow:

  1. A particular protocol (eg Microsoft conventions for .txt files) may require use of the BOM on certain Unicode data streams, such as files. When you need to conform to such a protocol, use a BOM.

  2. Some protocols allow optional BOMs in the case of untagged text. In those cases,

    • Where a text data stream is known to be plain text, but of unknown encoding, BOM can be used as a signature. If there is no BOM, the encoding could be anything.

    • Where a text data stream is known to be plain Unicode text (but not which endian), then BOM can be used as a signature. If there is no BOM, the text should be interpreted as big-endian.

  3. Some byte oriented protocols expect ASCII characters at the beginning of a file. If UTF-8 is used with these protocols, use of the BOM as encoding form signature should be avoided.

  4. Where the precise type of the data stream is known (eg Unicode big-endian or Unicode little-endian), the BOM should not be used. In particular, whenever a data stream is declared to be UTF-16BE, UTF-16LE, UTF-32BE or UTF-32LE a BOM must not be used.

UTF with BOM is better if you use UTF-8 in HTML files, if you use Serbian Cyrillic, Serbian Latin, German, Hungarian or something exotic language in the same page. That is my opinion (30 years of computing and IT industry).

  • request.getQueryString (), похоже, нуждается в некоторой кодировке
  • Как найти кодировку по умолчанию или кодировку в Java?
  • Проблема кодирования экспорта ASP.NET Excel
  • Есть ли известная проблема, связанная с символами ядра Windows 7?
  • Что такое кодировка символов и почему я должен ее беспокоить?
  • Interesting Posts
    Давайте будем гением компьютера.