Знак порядка байтов - Byte order mark

В метка порядка байтов (Спецификация) является частным использованием специального Unicode персонаж, U + FEFF МАРКА ЗАКАЗА БАЙТА, чей вид как магическое число в начале текстового потока может сигнализировать о нескольких вещах программа чтение текста:[1]

  • Порядок байтов, или порядок байтов, текстового потока в случаях 16-битной и 32-битной кодировок;
  • Тот факт, что кодировка текстового потока - Unicode, с высокой степенью достоверности;
  • Какая кодировка символов Unicode используется.

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

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

Последовательность байтов спецификации различается в зависимости от кодировки Unicode (включая те, которые не соответствуют стандарту Unicode, например UTF-7, видеть Таблица ниже ), и ни одна из последовательностей вряд ли появится в начале текстовых потоков, хранящихся в других кодировках. Следовательно, размещение закодированной спецификации в начале текстового потока может указывать на то, что текст является Unicode, и идентифицировать используемую схему кодирования. Такое использование символа спецификации называется «подписью Unicode».[2]

использование

Если символ спецификации появляется в середине потока данных, Unicode говорит, что его следует интерпретировать как "неразрывный пробел нулевой ширины "(запрещает перенос строки между глифами слов). В Unicode 3.2 это использование не рекомендуется в пользу"Word Joiner "персонаж, U + 2060.[1] Это позволяет использовать U + FEFF только в качестве спецификации.

UTF-8

В UTF-8 представление спецификации - это (шестнадцатеричный ) байтовая последовательность 0xEF, 0xBB, 0xBF.

Стандарт Unicode разрешает спецификацию в UTF-8,[3] но не требует и не рекомендует его использование.[4] Порядок байтов не имеет значения в UTF-8,[5] поэтому его единственное использование в UTF-8 - это сначала сигнализировать, что текстовый поток закодирован в UTF-8 или что он был преобразован в UTF-8 из потока, который содержал необязательную спецификацию. Стандарт также не рекомендует удалять спецификацию, когда она есть, чтобы при циклическом переключении между кодировками информация не терялась, и чтобы код, который на нее полагается, продолжал работать.[6][7] IETF рекомендует, чтобы если протокол либо (а) всегда использует UTF-8, либо (б) имеет другой способ указать, какая кодировка используется, то ему «СЛЕДУЕТ запретить использование U + FEFF в качестве подписи».[8]

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

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

Microsoft компиляторы[9] и интерпретаторы, а также множество программ на Майкрософт Виндоус Такие как Блокнот рассматривать спецификацию как обязательную магическое число вместо использования эвристики. Эти инструменты добавляют спецификацию при сохранении текста как UTF-8 и не могут интерпретировать UTF-8, если только спецификация не присутствует или файл не содержит только ASCII. Windows PowerShell (до 5.1) добавит спецификацию при сохранении XML-документов UTF-8. Однако PowerShell Core 6 добавил переключатель -Encoding для некоторых командлетов, называемых utf8NoBOM, чтобы документ можно было сохранить без спецификации. Гугл документы также добавляет спецификацию при преобразовании документа в простой текст файл для скачивания.

UTF-16

В UTF-16, спецификация (U + FEFF) может быть помещен в качестве первого символа файла или потока символов, чтобы указать порядок байтов (порядок байтов) всех 16-битных единиц кода файла или потока. Если будет сделана попытка прочитать этот поток с неправильным порядком байтов, байты будут переставлены местами, таким образом доставляя символ U + FFFE, который определено Unicode как «несимвол», который никогда не должен появляться в тексте.

  • Если 16-битные единицы представлены в прямой порядок байтов порядок байтов, спецификация будет отображаться в последовательности байтов как 0x FE 0xFF
  • Если 16-битные устройства используют прямой порядок байтов порядок, спецификация будет отображаться в последовательности байтов как 0xFF 0xFE

Ни одна из этих последовательностей не является допустимой UTF-8, поэтому их наличие указывает на то, что файл не закодирован в UTF-8.

Для IANA зарегистрированные наборы символов UTF-16BE и UTF-16LE, знак порядка байтов использовать не следует, поскольку имена этих наборов символов уже определяют порядок байтов. Если он встречается где-нибудь в таком текстовом потоке, U + FEFF следует интерпретировать как «неразрывный пробел нулевой ширины».

Если нет спецификации, можно угадать, является ли текст UTF-16 и его порядок байтов, путем поиска символов ASCII (т. Е. Байта 0, смежного с байтом в диапазоне 0x20-0x7E, также 0x0A и 0x0D для CR и LF). Большое число (т.е. намного большее, чем случайный шанс) в одном и том же порядке является очень хорошим показателем UTF-16, а то, находится ли 0 в четных или нечетных байтах, указывает порядок байтов. Однако это может привести к обе ложные срабатывания и ложные отрицания.

Пункт D98 о соответствии (раздел 3.10) стандарта Unicode гласит: «Схема кодирования UTF-16 может начинаться или не начинаться с спецификации. Однако, когда нет спецификации и в отсутствие протокола более высокого уровня, порядок байтов в схеме кодирования UTF-16 - обратный порядок байтов ". Вопрос о том, действует ли протокол более высокого уровня, открыт для интерпретации. Файлы, локальные для компьютера, для которых собственный порядок байтов является прямым порядком байтов, например, можно утверждать, что они неявно закодированы как UTF-16LE. Следовательно, презумпция прямого порядка байтов широко игнорируется. В W3C /WHATWG стандарт кодирования, используемый в HTML5, указывает, что контент с меткой «utf-16» или «utf-16le» должен интерпретироваться как little-endian «для работы с развернутым контентом».[10] Однако, если присутствует метка порядка байтов, то эта спецификация должна рассматриваться как «более авторитетная, чем что-либо еще».[11]

Программы, которые интерпретируют UTF-16 как байтовую кодировку, могут отображать искаженный беспорядок символов, но символы ASCII будут распознаваться, потому что младший байт представления UTF-16 совпадает с кодом ASCII и, следовательно, будет отображаться так же . Старший байт 0 может отображаться как ничего, пробел, точка или какой-либо другой неизменный глиф.

UTF-32

Хотя спецификацию можно использовать с UTF-32, это кодирование редко используется для передачи. В остальном те же правила, что и для UTF-16 применимы.

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

Отметки порядка байтов по кодировке

В этой таблице показано, как символ спецификации представлен как последовательность байтов в различных кодировках и как эти последовательности могут отображаться в текстовом редакторе, интерпретирующем каждый байт как устаревшую кодировку (CP1252 и обозначение каретки для C0 контролирует ):

КодированиеПредставление (шестнадцатеричный )Представление (десятичный )Байты как символы CP1252
UTF-8[а]EF BB BF239 187 191я"
UTF-16 (БЫТЬ )FE FF254 255þÿ
UTF-16 (LE )FF FE255 254ÿþ
UTF-32 (БЫТЬ)00 00 FE FF0 0 254 255^ @ ^ @ þÿ (^@ это нулевой символ )
UTF-32 (LE)FF FE 00 00255 254 0 0ÿþ ^ @ ^ @ (^@ это нулевой символ)
UTF-7[а]2Б 2Ф 76[b]43 47 118+ / v
UTF-1[а]F7 64 4C247 100 76÷ dL
UTF-EBCDIC[а]ДД 73 66 73221 115 102 115Ýsfs
ГКГУ[а]0E FE FF[c]14 254 255^ Nþÿ (^ N это "сдвигать" характер )
BOCU-1[а]FB EE 28251 238 40î (
ГБ-18030[а]84 31 95 33132 49 149 51„1•3
  1. ^ а б c d е ж грамм Это буквально не метка «порядка байтов», поскольку единица кода в этих кодировках составляет один байт и, следовательно, не может иметь байты в «неправильном» порядке. Тем не менее, спецификацию можно использовать для указания кодировки текста, который следует за ней.[5][12]
  2. ^ С последующим 38, 39, , или же 3B (ASCII 8, 9, : или же ;), в зависимости от того, какой следующий символ.
  3. ^ SCSU допускает другие кодировки U + FEFF, показанная форма является подписью, рекомендованной в UTR # 6.[13]

Смотрите также

Рекомендации

  1. ^ а б «Часто задаваемые вопросы - UTF-8, UTF-16, UTF-32 и BOM». Unicode.org. Получено 2017-01-28.
  2. ^ «Стандартная версия Unicode® 9.0» (PDF). Консорциум Unicode.
  3. ^ «Стандарт Unicode 5.0, Глава 2: Общая структура» (PDF). п. 36. Получено 2009-03-29. Таблица 2-4. Семь схем кодирования Unicode
  4. ^ «Стандарт Unicode 5.0, Глава 2: Общая структура» (PDF). п. 36. Получено 2008-11-30. Использование спецификации не требуется и не рекомендуется для UTF-8, но может встречаться в контекстах, где данные UTF-8 преобразуются из других форм кодирования, которые используют спецификацию, или где спецификация используется в качестве подписи UTF-8.
  5. ^ а б «Часто задаваемые вопросы - UTF-8, UTF-16, UTF-32 и спецификация: может ли поток данных UTF-8 содержать символ спецификации (в форме UTF-8)? Если да, могу ли я предположить, что оставшиеся байты UTF-8 в порядке прямого байта? ". Unicode.org. Получено 2009-01-04.
  6. ^ "Re: pre-HTML5 и спецификация от Асмуса Фрейтага от 13 июля 2012 г. (Архив почтового списка Unicode)". Unicode.org. Получено 2012-07-14.
  7. ^ "Идентификатор ошибки: JDK-6378911 Декодер UTF-8 обрабатывает метку порядка байтов изменена". Bugs.sun.com. Получено 2017-01-28.
  8. ^ Йерго, Франсуа (ноябрь 2003 г.). UTF-8, формат преобразования ISO 10646. IETF. Дои:10.17487 / RFC3629. RFC 3629. Получено 15 мая, 2014.
  9. ^ Альф П. Штайнбах (2011). «Юникод, часть 1: подходы к вводу-выводу консоли Windows». Получено 24 марта 2012. Однако, поскольку исходный код C ++ был закодирован как UTF-8 без спецификации (как обычно в Linux), компилятор Visual C ++ ошибочно предположил, что исходный код был закодирован как Windows ANSI.
  10. ^ "UTF-16LE". Стандарт кодирования. WHATWG.
  11. ^ «Расшифровать». Стандарт кодирования. WHATWG.
  12. ^ «RFC 3629 - UTF-8, формат преобразования ISO 10646». Tools.ietf.org. 2003-11-08. Получено 2017-01-28.
  13. ^ Маркус Шерер. «UTS # 6: Схема сжатия для Unicode». Unicode.org. Получено 2017-01-28.

внешняя ссылка