Чем отличаются UTF-8 и UTF-8 без спецификации ? Что лучше?
Чем отличаются UTF-8 и UTF-8 без спецификации ? Что лучше?
Ответы:
Спецификация UTF-8 представляет собой последовательность байтов в начале текстового потока ( 0xEF, 0xBB, 0xBF
), которая позволяет читателю более надежно угадывать файл как кодированный в UTF-8.
Обычно, спецификация используется для сигнализации о порядке байтов кодирования, но, поскольку порядок байтов не имеет отношения к UTF-8, эта спецификация не нужна.
В соответствии со стандартом Unicode , спецификация для файлов UTF-8 не рекомендуется :
2.6 Схемы кодирования
... Использование спецификации не требуется и не рекомендуется для UTF-8, но может встречаться в случаях, когда данные UTF-8 преобразуются из других форм кодирования, в которых используется спецификация, или когда спецификация используется в качестве сигнатуры UTF-8. , См. Подраздел «Порядок следования байтов» в разделе 16.8, «Специальные» , для получения дополнительной информации.
Другие отличные ответы уже ответили, что:
EF BB BF
Но, в качестве дополнительной информации к этому, спецификация для UTF-8 может быть хорошим способом «понюхать», если строка была закодирована в UTF-8 ... Или это может быть допустимая строка в любой другой кодировке ...
Например, данные [EF BB BF 41 42 43] могут быть:
Поэтому, хотя было бы здорово распознать кодировку содержимого файла, посмотрев на первые байты, вы не должны полагаться на это, как показано в примере выше.
Кодировки должны быть известны, а не предсказаны.
Существует как минимум три проблемы с размещением спецификации в кодированных файлах UTF-8.
И, как уже упоминали другие, недостаточно или необходимо иметь спецификацию, чтобы обнаружить, что что-то является UTF-8:
cat
не даст вам чистого результата, результата, который имеет спецификацию только на старте. Если вы это имели в виду, то это потому, что cat
работает на уровне байтов, а не на уровне интерпретируемого содержимого, и cat
, например, не может работать с фотографиями. Тем не менее это не приносит большого вреда. Это потому, что спецификация кодирует неразрывный пробел нулевой ширины.
Вот примеры использования спецификации, которые на самом деле вызывают реальные проблемы, и все же многие люди не знают об этом.
Сценарии оболочки, сценарии 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. [выделение добавлено]
См. RFC 7159, раздел 8.1 :
Реализации НЕ ДОЛЖНЫ добавлять метку порядка байтов в начало текста JSON.
Это не только недопустимо в JSON, но и не нужно определять кодировку символов, поскольку существуют более надежные способы однозначного определения как кодировки символов, так и порядка байтов, используемого в любом потоке JSON (подробности см. В этом ответе ).
Он не только недопустим в JSON и не нужен , он фактически ломает все программное обеспечение, которое определяет кодировку с использованием метода, представленного в RFC 4627 :
Определим кодировку и порядковый номер JSON, изучив первые четыре байта для байта 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-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 не рекомендует его. Это вызывает проблемы с программным обеспечением, не поддерживающим спецификацию.
Лучший способ определить, является ли файл UTF-8, - выполнить проверку достоверности. UTF-8 имеет строгие правила относительно того, какие последовательности байтов действительны, поэтому вероятность ложного срабатывания незначительна. Если последовательность байтов выглядит как UTF-8, вероятно, так оно и есть.
sh
, perl
, g++
и многим другим бесплатным и мощных инструментов. Хотите, чтобы все работало? Просто купите версии MS. MS создала проблему, специфичную для платформы, так же, как бедствие их диапазона \ x80- \ x95.
UTF-8 с спецификацией лучше идентифицирован. Я пришел к такому выводу трудным путем. Я работаю над проектом, одним из результатов которого является CSV файл , включая символы Unicode.
Если файл 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 )
Спецификация имеет тенденцию бум (не каламбур (так)) где-то, где-то. И когда он гремит (например, не распознается браузерами, редакторами и т. Д.), Он отображается как странные символы 
в начале документа (например, файл HTML, ответ JSON , RSS и т. Д.) и вызывает такие неудобства, как недавняя проблема с кодировкой, возникшая во время разговора Обамы в Twitter .
Это очень раздражает, когда появляется в местах, которые трудно отладить, или когда пренебрегают тестированием. Так что лучше избегать этого, если только вы не должны его использовать.
Вопрос: Чем отличаются UTF-8 и UTF-8 без спецификации? Что лучше?
Вот некоторые выдержки из статьи Википедии о метке порядка байтов (BOM) которая, как я считаю, дает солидный ответ на этот вопрос.
По смыслу спецификации и UTF-8:
Стандарт Unicode разрешает спецификацию в UTF-8 , но не требует и не рекомендует ее использование. Порядок байтов не имеет значения в UTF-8, поэтому его использование только в UTF-8 заключается в том, чтобы в начале сигнализировать о том, что текстовый поток кодируется в UTF-8.
Аргумент за НЕ использование спецификации:
Основной мотивацией для отказа от использования спецификации является обратная совместимость с программным обеспечением, не поддерживающим Unicode ... Другой мотивацией для отказа от использования спецификации является поощрение UTF-8 в качестве кодировки по умолчанию.
Аргумент ЗА использование спецификации:
Аргумент в пользу использования спецификации заключается в том, что без нее требуется эвристический анализ, чтобы определить, какую кодировку символов использует файл. Исторически такой анализ, чтобы различать различные 8-битные кодировки, сложен, подвержен ошибкам, а иногда и медленен. Для облегчения этой задачи доступно несколько библиотек, таких как Mozilla Universal Charset Detector и Международные компоненты для Unicode.
Программисты ошибочно полагают, что обнаружение UTF-8 одинаково сложно (это не потому, что подавляющее большинство байтовых последовательностей являются недействительными UTF-8, тогда как кодировки, которые эти библиотеки пытаются различить, разрешают все возможные байтовые последовательности). Поэтому не все программы, поддерживающие Unicode, выполняют такой анализ и вместо этого полагаются на спецификацию.
В частности, компиляторы и интерпретаторы Microsoft , а также многие программные продукты в Microsoft Windows, такие как «Блокнот», не будут правильно читать текст UTF-8, если в нем нет только символов ASCII или он начинается с спецификации, и добавит спецификацию в начало при сохранении. текст как UTF-8. Документы Google добавят спецификацию при загрузке документа Microsoft Word в виде простого текстового файла.
На что лучше, С или БЕЗ спецификации
IETF рекомендует , если протокол либо (а) всегда использует UTF-8, или (б) имеет какой - то другой способ , чтобы указать , что используется кодировка, то «следует запретить использование U + FEFF в качестве подписи.»
Мой вывод:
Используйте только спецификацию если совместимость с программным приложением абсолютно необходима.
Также обратите внимание, что хотя указанная статья в Википедии указывает на то, что многие приложения Microsoft полагаются на спецификацию для правильного определения UTF-8, это относится не ко всем приложениям Microsoft. Например, как отметил @barlop , при использовании командной строки в Windows с UTF-8 † , таких командами, type
и more
не ожидает , что BOM присутствовать. Если спецификация находится присутствует, она может быть проблематичной, так и для других применений.
† Команда chcp
предлагает поддержку UTF-8 ( без спецификации) через кодовую страницу 65001 .
.htaccess
и gzip compression
в сочетании с UTF-8 BOM выдает ошибку кодирования. Замените кодировку в UTF-8 без BOM, следуйте предложению,
На этот вопрос уже есть миллион ответов, и многие из них довольно хороши, но я хотел попытаться уточнить, когда спецификацию следует или не следует использовать.
Как уже упоминалось, любое использование спецификации UTF (метки порядка байтов) при определении того, является ли строка UTF-8 или нет, является догадкой. Если есть доступные метаданные (например,charset="utf-8"
), то вы уже знаете, что должны использовать, но в противном случае вам нужно будет проверить и сделать некоторые предположения. Это включает проверку, начинается ли файл с строки, начинается с шестнадцатеричного байтового кода, EF BB BF.
Если найден байт-код, соответствующий спецификации UTF-8, вероятность достаточно высока, чтобы предположить, что это UTF-8, и вы можете перейти оттуда. Однако, если сделать такое предположение, дополнительная проверка ошибок во время чтения все равно будет хорошей идеей на случай, если что-то искажается. Вы должны только предполагать, что спецификация не UTF-8 (т. Е. Латинская-1 или ANSI), если ввод определенно не должен быть UTF-8 на основе его источника. Однако, если спецификации нет, вы можете просто определить, должен ли это быть UTF-8, проверив соответствие кодировке.
Если вы не можете записать метаданные каким-либо другим способом (с помощью тега charset или мета файловой системы) и программ, используемых как спецификации, вам следует кодировать с помощью спецификации. Это особенно верно в Windows, где обычно предполагается, что что-либо без спецификации использует устаревшую кодовую страницу. Спецификация сообщает таким программам, как Office, что да, текст в этом файле - Unicode; вот используемая кодировка
Когда дело доходит до этого, единственные файлы, с которыми я когда-либо действительно имею проблемы, - это CSV. В зависимости от программы, она должна или не должна иметь спецификацию. Например, если вы используете Excel 2007+ в Windows, он должен быть закодирован с помощью спецификации, если вы хотите открыть ее плавно и не прибегать к импорту данных.
Следует отметить, что для некоторых файлов у вас не должно быть спецификации даже в Windows. Примеры есть SQL*plus
или VBScript
файлы. Если такие файлы содержат спецификацию, вы получаете сообщение об ошибке при попытке их выполнить.
UTF-8 с спецификацией помогает только в том случае, если файл на самом деле содержит символы не ASCII. Если он включен и его нет, он, возможно, сломает старые приложения, которые иначе интерпретировали бы файл как простой ASCII. Эти приложения определенно потерпят неудачу, когда столкнутся с не ASCII-символом, поэтому, по моему мнению, спецификацию следует добавлять только тогда, когда файл может и не должен больше интерпретироваться как простой ASCII.
Я хочу прояснить, что я предпочитаю вообще не иметь спецификации. Добавьте его, если какой-то старый мусор сломается без него, и заменить это устаревшее приложение невозможно.
Не заставляйте ничего ожидать спецификации для UTF-8.
Цитируется внизу страницы Википедии в спецификации: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2
«Использование спецификации не требуется и не рекомендуется для UTF-8, но может встречаться в случаях, когда данные UTF-8 преобразуются из других форм кодирования, в которых используется спецификация, или когда спецификация используется в качестве сигнатуры UTF-8»
UTF-8 без спецификации не имеет спецификации, что не делает ее лучше, чем UTF-8 с спецификацией, за исключением случаев, когда пользователь файла должен знать (или выиграл бы от знания), закодирован ли файл в кодировке UTF-8 или нет.
Спецификация обычно полезна для определения порядкового номера кодирования, что не требуется для большинства случаев использования.
Кроме того, спецификация может быть ненужным шумом / болью для тех потребителей, которые не знают или не заботятся об этом, и могут привести к путанице среди пользователей.
Я смотрю на это с другой точки зрения. Я думаю, что UTF-8 с спецификацией лучше так как предоставляет больше информации о файле. Я использую UTF-8 без спецификации, только если сталкиваюсь с проблемами.
Я использую несколько языков (даже кириллицу ) на своих страницах в течение длительного времени, и когда файлы сохраняются без BOM, и я снова открываю их для редактирования в редакторе (как также отметил cherouvim ), некоторые символы повреждены.
Обратите внимание, что классический блокнот Windows автоматически сохраняет файлы с спецификацией при попытке сохранить вновь созданный файл с кодировкой UTF-8.
Я лично сохраняю файлы сценариев на стороне сервера (.asp, .ini, .aspx) с BOM и .html файлами без BOM .
chcp 65001
для поддержки utf8, это utf8 без bom. Если вы это сделаете, type myfile
он будет отображаться правильно только при отсутствии бомбы. Если вы делаете echo aaa>a.a
или echo אאא>a.a
выводите символы в файл aa, и у вас есть chcp 65001, он будет выводиться без спецификации.
Если вы хотите отобразить информацию, закодированную в 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.
Одно практическое отличие состоит в том, что если вы напишите сценарий оболочки для Mac OS X и сохраните его как обычный UTF-8, вы получите ответ:
#!/bin/bash: No such file or directory
в ответ на строку shebang, указывающую, какую оболочку вы хотите использовать:
#!/bin/bash
Если вы сохраните как UTF-8, без спецификации (скажем, в BBEdit ) все будет хорошо.
Как упоминалось выше, UTF-8 с BOM может вызвать проблемы с программным обеспечением, не поддерживающим BOM (или совместимым). Однажды я отредактировал HTML-файлы в кодировке UTF-8 + BOM с помощью KompoZer на основе Mozilla , поскольку клиенту требовалась программа WYSIWYG .
Неизменно макет будет уничтожен при сохранении. Мне потребовалось некоторое время, чтобы возиться с этим. Затем эти файлы хорошо работали в Firefox, но в Internet Explorer обнаружил причуду CSS, снова разрушающую макет. После нескольких часов бесполезной работы со связанными CSS-файлами я обнаружил, что Internet Explorer не нравится HTML-файл BOMfed. Больше никогда.
Кроме того, я только что нашел это в Википедии:
Символы shebang представлены теми же двумя байтами в расширенных кодировках ASCII, включая UTF-8, который обычно используется для сценариев и других текстовых файлов в современных Unix-подобных системах. Однако файлы UTF-8 могут начинаться с дополнительной метки порядка байтов (BOM); если функция "exec" определенно обнаруживает байты 0x23 0x21, то присутствие спецификации (0xEF 0xBB 0xBF) перед shebang будет препятствовать выполнению интерпретатора сценария. Некоторые авторитеты рекомендуют не использовать метку порядка байтов в сценариях POSIX (Unix-like) [15] по этой причине и для более широкой функциональной совместимости и философских соображений.
Часто задаваемые вопросы по метке порядка байтов в Юникоде дают краткий ответ:
Q: Как я должен иметь дело с спецификациями?
A: Вот несколько рекомендаций, которым нужно следовать:
Конкретный протокол (например, соглашения Microsoft для файлов .txt) может потребовать использования спецификации для определенных потоков данных Unicode, таких как файлы. Когда вам нужно соответствовать такому протоколу, используйте спецификацию.
Некоторые протоколы допускают использование дополнительных спецификаций в случае нетегированного текста. В этих случаях
Если известно, что поток текстовых данных представляет собой простой текст, но неизвестной кодировки, в качестве подписи может использоваться спецификация. Если спецификации нет, кодировка может быть любой.
Если известно, что поток текстовых данных представляет собой простой текст в Юникоде (но не с прямым порядком байтов), то в качестве подписи может использоваться спецификация. Если спецификация отсутствует, текст следует интерпретировать как big-endian.
Некоторые байтовые протоколы ожидают символы ASCII в начале файла. Если UTF-8 используется с этими протоколами, следует избегать использования спецификации в качестве подписи формы кодирования.
Если известен точный тип потока данных (например, Unicode с прямым порядком байтов или Unicode с прямым порядком байтов), спецификация не должна использоваться. В частности, всякий раз, когда поток данных объявляется UTF-16BE, UTF-16LE, UTF-32BE или UTF-32LE, BOM не должен использоваться.
От http://en.wikipedia.org/wiki/Byte-order_mark :
Метка порядка байтов (BOM) - это символ Unicode, используемый для обозначения порядка байтов (порядка байтов) текстового файла или потока. Кодовая точка U + FEFF. Использование спецификации является необязательным и, если используется, должно отображаться в начале текстового потока. Помимо его конкретного использования в качестве индикатора порядка байтов, символ спецификации может также указывать, в каком из нескольких представлений Unicode кодируется текст.
Всегда использование спецификации в вашем файле гарантирует, что она всегда правильно открывается в редакторе, который поддерживает UTF-8 и BOM.
Моя настоящая проблема с отсутствием спецификации заключается в следующем. Предположим, у нас есть файл, который содержит:
abc
Без спецификации это открывается как ANSI в большинстве редакторов. Таким образом, другой пользователь этого файла открывает его и добавляет некоторые нативные символы, например:
abg-αβγ
Упс ... Теперь файл все еще находится в ANSI и угадайте, что, "αβγ" не занимает 6 байтов, но 3. Это не UTF-8, и это вызывает другие проблемы позже в цепочке разработки.
Вот мой опыт работы с Visual Studio, Sourcetree запросами извлечения и Bitbucket, который вызывает у меня некоторые проблемы:
Таким образом, оказывается, что спецификация с подписью будет включать символ красной точки в каждом файле при просмотре запроса на извлечение (это может быть довольно раздражающим).
Если вы наведите на него курсор, он покажет символ, подобный «ufeff», но оказывается, что Sourcetree не показывает эти типы байт-меток, поэтому он, скорее всего, закончится вашими запросами на получение, что должно быть в порядке, поскольку Visual Studio 2017 теперь кодирует новые файлы, поэтому, возможно, Bitbucket должен проигнорировать это или заставить его показывать по-другому, больше информации здесь:
UTF с спецификацией лучше, если вы используете UTF-8 в файлах HTML и если вы используете сербскую кириллицу, сербскую латиницу, немецкий, венгерский или какой-либо другой экзотический язык на той же странице.
Это мое мнение (30 лет компьютерной и IT индустрии).