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

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

+674
источник поделиться
20 ответов

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

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

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

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

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

+639
источник

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

  • Официальная разница между 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 строка "ABC"

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

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

+200
источник

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

В JSON не только незаконно, но и не требуется, чтобы определить кодировку символов, потому что есть более надежные способы однозначного определения как кодировки символов, так и endianness используемый в любом потоке 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

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

  • UTF-32BE не запускается с тремя NUL, поэтому он не будет распознан
  • UTF-32LE, первый байт не следует 3 NUL, поэтому он не будет распознан
  • UTF-16BE имеет только 1 NUL в первых 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 или скриптов, я думаю, что здесь есть очень хорошие ответы. Я хотел бы добавить более подробную информацию о скриптах и ​​сериализации, потому что это пример символов спецификации, вызывающих реальные проблемы.

+59
источник

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

+46
источник

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

Если файл CSV сохраняется без спецификации, Excel считает это ANSI и показывает тарабарщину. После добавления "EF BB BF" на передней панели (например, путем повторного сохранения его с помощью Notepad с UTF-8 или Notepad ++ с UTF-8 с спецификацией) 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)

+29
источник

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

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

+15
источник

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

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

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

Стандарт Unicode разрешает спецификацию в 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, такие как Notepad, не будут правильно читать текст UTF-8, если он не имеет только символы ASCII или он начинается с спецификации и добавит спецификацию к началу при сохранении текста как UTF-8. Документы Google добавят спецификацию, когда документ Microsoft Word загружается как обычный текстовый файл.

В чем лучше, WITH или БЕЗ спецификации:

IETF рекомендует, чтобы, если протокол (а) всегда использует UTF-8, или (b) имеет другой способ указать, какая кодировка используется, то он "ДОЛЖЕН запретить использование U + FEFF в качестве подписи".

Мой вывод:

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

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


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

+12
источник

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

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

+7
источник

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

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

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

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

+7
источник

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

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

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

+6
источник

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

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

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

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

<?xml version="1.0" encoding="UTF-8"?>

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

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

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

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

+6
источник

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

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

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

+6
источник

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

+6
источник

Одно практическое отличие состоит в том, что если вы напишете оболочку script для Mac OS X и сохраните ее как обычный UTF-8, вы получите ответ:

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

в ответ на строку shebang, указывающую, какую оболочку вы хотите использовать:

#!/bin/bash

Если вы сохраните как UTF-8, никаких спецификаций (скажем, в BBEdit) все будет хорошо.

+5
источник

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

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

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

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

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

Когда вы должны кодировать спецификацию?

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

Когда дело доходит до этого, единственными файлами, с которыми я когда-либо сталкивался, являются CSV. В зависимости от программы он должен либо иметь, либо не иметь спецификацию. Например, если вы используете Excel 2007+ в Windows, он должен быть закодирован с помощью спецификации, если вы хотите открыть его плавно и не прибегать к импорту данных.

+5
источник

Как упоминалось выше, UTF-8 с спецификацией может вызвать проблемы с программным обеспечением, не поддерживающим BOM (или совместимым). Я однажды редактировал HTML файлы, закодированные как UTF-8 + BOM с помощью KompoZer на основе Mozilla, так как клиенту требовалось, чтобы WYSIWYG.

Неизменно макет будет уничтожен при сохранении. Мне потребовалось некоторое время, чтобы поиграть с этим. Эти файлы затем хорошо зарекомендовали себя в Firefox, но снова продемонстрировали причуду CSS в Internet Explorer, разрушающую макет. После долгой работы с связанными файлами CSS я обнаружил, что Internet Explorer не понравился HTML файл BOMfed. Никогда больше.

Кроме того, я просто нашел это в Википедии:

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

+3
источник

От http://en.wikipedia.org/wiki/Byte-order_mark:

Знак порядка байтов (BOM) - это Unicode символ, используемый для endianness (порядок байтов) текстового файла или поток. Его кодовая точка U + FEFF. Использование спецификации необязательно, и, если используется, должен появиться в начале текста поток. Помимо его конкретного использования в качестве байт-указатель, спецификация символ может также указывать, какой из несколько представлений Unicode текст закодирован.

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

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

abc

Без спецификации это открывается как ANSI в большинстве редакторов. Таким образом, другой пользователь этого файла открывает его и добавляет некоторые собственные символы, например:

abg-αβγ

Упс... Теперь файл по-прежнему находится в ANSI и догадывается, что "αβγ" не занимает 6 байтов, а 3. Это не UTF-8, и это вызывает другие проблемы позже в цепочке разработки.

+2
источник

Юникод Часто задаваемые вопросы по порядку байтов (BOM) дает краткий ответ:

В: Как мне работать со спецификациями?

A: Ниже приведены некоторые рекомендации:

  • Конкретный протокол (например, соглашения Microsoft для файлов .txt) может потребовать использования спецификации в некоторых потоках данных Unicode, таких как файлы. Если вам необходимо соответствовать такому протоколу, используйте спецификацию.

  • Некоторые протоколы допускают дополнительные спецификации в случае непомеченного текста. В этих случаях

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

    • Если поток текстовых данных, как известно, является простым текстом Unicode (но не каким конечным), тогда спецификация может использоваться как подпись. Если здесь не является спецификацией, текст следует интерпретировать как big-endian.

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

  • Если известен точный тип потока данных (например, Unicode big-endian или Unicode little-endian), спецификация не должна использоваться. В в частности, когда объявлен поток данных UTF-16BE, UTF-16LE, UTF-32BE или UTF-32LE нельзя использовать спецификацию.

+2
источник

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

-3
источник

Посмотрите другие вопросы по меткам или Задайте вопрос