Unicode — Какая разница между UTF-8 и UTF-8 без спецификации?

Чем отличается UTF-8 от UTF-8 без BOM? Что лучше?

+691

Решение

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

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

Согласно Стандарт Юникод, Спецификация для файлов UTF-8 не рекомендуется:

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

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

655

Другие решения

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

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

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

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

  • Законный ISO-8859-1 строка «ï» ¿ABC «
  • Законный UTF-8, Строка «Азбука»

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

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

204

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

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

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

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

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

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

BOM ломает скрипты

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

#!/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 (см. этот ответ для деталей).

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 или сценариев, я думаю, что здесь уже есть очень хорошие ответы. Я хотел добавить более подробную информацию, в частности, о сценариях и сериализации, потому что это пример символов спецификации, вызывающих реальные проблемы.

61

Чем отличаются 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, вероятно, так оно и есть.

47

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

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

В RFC 3629 рекомендуется добавлять символ спецификации к текстовым файлам 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)

30

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

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

16

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

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

По смыслу спецификации и UTF-8:

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

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

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

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

Аргумент в пользу использования спецификации заключается в том, что без нее эвристический анализ
Требуется определить, какую кодировку символов использует файл.
Исторически такой анализ, чтобы различать различные 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 полагаются на спецификацию для правильного определения UTF-8, это не относится к все Приложения Microsoft. Например, как указано @barlop, при использовании командной строки Windows с UTF-8, команды такие type а также more не ожидайте присутствия спецификации. Если спецификация является В настоящее время это может быть проблематично, как и для других приложений.


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

13