В UTF-16, UTF-16BE, UTF-16LE, является ли порядок байтов UTF-16 порядком байтов компьютера?

UTF-16 - это двухбайтовая кодировка символов. Если поменять местами адреса двух байтов, получим UTF-16BE и UTF-16LE.

Но я обнаружил, что кодировка имени UTF-16 существует в текстовом редакторе Ubuntu gedit, а также в UTF-16BE и UTF-16LE. С помощью тестовой программы C я обнаружил, что мой компьютер работает с прямым порядком байтов, а UTF-16 подтвержден как такая же кодировка UTF-16LE.

Также: на компьютерах с прямым и обратным порядком байтов значения имеют два порядка байтов (например, целое число). Компьютеры с прямым порядком байтов будут производить аппаратные значения с прямым порядком байтов (за исключением значения, создаваемого Java, которое всегда образует прямой порядок байтов).

Хотя на моем маленьком компьютере с прямым порядком байтов текст может быть сохранен как UTF-16LE, а также как UTF-16BE, это символы, создаваемые по одному байту (например, строка ASCII, ссылка на [3] и порядок байтов UTF-16, только что определенный человеком - не в результате явления, что машины с прямым порядком байтов пишут UTF-16 с прямым порядком байтов, а машины с обратным порядком байтов пишут UTF-16 с прямым порядком байтов?

  1. http://www.ibm.com/developerworks/aix/library/au-endianc/
  2. http://teaching.idallen.com/cst8281/10w/notes/110_byte_order_endian.html
  3. Строки ASCII и порядок байтов
  4. Это правда, что порядок байтов влияет только на расположение в памяти чисел, но не на строку? Это сообщение о связи между порядком байтов строки и машины.

person hao.zhou    schedule 11.04.2016    source источник
comment
UTF-16 без уточнения по умолчанию является Big Endian, но это не означает, что все приложения работают в соответствии со спецификацией.   -  person 一二三    schedule 11.04.2016
comment
@ 一 二三 Спасибо! Я обращаю внимание на разницу между символом и значением. В тесте программы C # целое число, сохраненное на машине с прямым порядком байтов, имеет обратный порядок байтов. И его нельзя правильно прочитать при копировании на машину с прямым порядком байтов, потому что байтовый адрес перевернут. Но для многобайтовых символов в C # происходит ли реверсирование байтового адреса после копирования с одной машины на другую?   -  person hao.zhou    schedule 11.04.2016
comment
@ 一 二三: Это не совсем так. UTF-16 без спецификации по умолчанию является прямым порядком байтов, но обычно у него будет спецификация, определяющая порядок байтов.   -  person rici    schedule 11.04.2016


Ответы (3)


"Порядок байтов в UTF-16 - порядок байтов компьютера?"

Влияние обратного порядка байтов на вашем компьютере можно посмотреть с точки зрения писателя или читателя файла.

Если вы читаете файл в стандартном формате, то тип машинного чтения не имеет значения. Формат должен быть достаточно четко определен, чтобы независимо от порядка байтов считывающей машины данные могли быть правильно прочитаны.

Это не значит, что формат не может быть гибким. С «UTF-16» (когда в названии формата не используется значение «BE» или «LE») определение позволяет помечать файлы как либо с прямым порядком байтов, либо с прямым порядком байтов. Это делается с помощью так называемой «метки порядка байтов» (BOM) в первых двух байтах файла:

https://en.wikipedia.org/wiki/Byte_order_mark

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

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

... что, если спецификации нет?

Здесь все становится немного туманно.

С одной стороны, Unicode RFC 2781 и FAQ по Unicode ясны. Они говорят, что файл в формате «UTF-16», который не начинается ни с 0xFF 0xFE, ни с 0xFE 0xFF, должен быть интерпретироваться с прямым порядком байтов:

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

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

Рассмотрим что-то вроде этого от Рэймонда Чена (2007):

Вы можете решить, что программы, которые генерируют файлы UTF-16 без спецификации, не работают, но это не значит, что они не существуют. Например,

cmd /u /c dir >results.txt

Это создает файл UTF-16LE без спецификации.

Это допустимый файл UTF-16LE, но где будет храниться мета-метка «UTF-16LE»? Каковы шансы, что кто-то выдаст это, просто назвав его файлом UTF-16?

Эмпирически есть предупреждения по поводу этого термина. На странице для UTF-16 говорится:

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

И unicode.readthedocs.org говорит:

Названия кодировок «UTF-16» и «UTF-32» неточны: в зависимости от контекста, формата или протокола это означает UTF-16 и UTF-32 с маркерами спецификации или UTF-16 и UTF-32 в порядке порядка байтов узла. без спецификации. В Windows «UTF-16» обычно означает UTF-16-LE.

И далее, статья Википедии Byte-Order-Mark говорит:

Пункт D98 соответствия (раздел 3.10) стандарта Unicode гласит: «Схема кодирования UTF-16 может начинаться или не начинаться с спецификации. Однако, когда нет спецификации и в отсутствие протокола более высокого уровня, порядок байтов в схеме кодирования UTF-16 - прямой порядок байтов ".

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

С другой стороны, когда те же самые файлы доступны в Интернете, такое предположение невозможно. Поиск 16-битных символов в диапазоне ASCII или просто символа пробела (U + 0020) - это метод определения порядка байтов UTF-16.

Таким образом, несмотря на однозначность стандарта, на практике контекст может иметь значение.

Как указывает @rici, стандарт существует уже некоторое время. Тем не менее, перепроверка файлов, заявленных как "UTF-16", может окупиться. Или даже подумайте, хотите ли вы избежать многих из этих проблем и принять UTF-8 ...

"Следует ли считать UTF-16 вредоносным?"

person HostileFork says dont trust SE    schedule 11.04.2016
comment
UTF-16 точно определен в стандарте Unicode (на unicode.org), который imho является источником информации о Unicode по умолчанию. . - person rici; 11.04.2016
comment
@rici, если обычная практика противоречит спецификации, было бы глупо игнорировать этот факт. Я думаю, что этот ответ в достаточной степени обходит проблему. - person Mark Ransom; 11.04.2016
comment
@MarkRansom Я отредактировал, чтобы включить бит-стандарт-говорит (о котором я не говорил изначально). Но кажется, что, когда несколько источников сочли важным упомянуть, что интерпретации изменчивы, ответ, основанный на спецификации, в котором не упоминаются различия, является неполным. - person HostileFork says dont trust SE; 11.04.2016
comment
@markRansom: Насколько я понимаю, утилиты MS используют префикс спецификации (конечно, Notedpad), и MS настоятельно рекомендует эту практику. Это соответствовало бы стандарту UTF-16; в противном случае это был бы файл UTF-16LE. (Конечно, это может быть неправильная маркировка. Но обычно Windows описывает свои файлы довольно неформально как Unicode, который на самом деле не делает никаких заявлений о схеме кодирования.) - person rici; 11.04.2016
comment
@rici, Windows описывает свои файлы как Unicode, поскольку на момент начала их поддержки UTF-16 (фактически его предшественник UCS-2) был единственной кодировкой Unicode. Вы правы относительно их последовательности в использовании спецификации, даже для UTF-8, где она не требуется и снова идет вразрез со стандартом. - person Mark Ransom; 11.04.2016
comment
@mark: текущий стандарт разрешает спецификацию в utf-8, что означает, что если объект начинается с U + FEFF, этот символ игнорируется. Окна соответствует; более новые приложения Unix, как правило, соответствуют, но некоторые не игнорируют спецификации. - person rici; 11.04.2016
comment
@rici Можно ли получить связь между порядком байтов utf-16 (не BE или LE) и порядком байтов машины? В программе на C двухбайтовое целое число имеет проблему порядка байтов, которая зависит от порядка байтов машины. В то время как ASCII в C не-endianness, это deat с одним байтом, символ всегда сохраняется по младшему адресу памяти. Однако где-то можно найти аргумент, что UTF-16 зависит от endianness машины, и причина в том, что UTF-16 является многобайтовый символ (Ссылка [1]), но без какого-либо программного теста, в отличие от целого числа (Ссылка [2]). - person hao.zhou; 14.04.2016
comment
@ hao.zhou: если поток имеет формат UTF-16, он либо начинается с спецификации, либо с прямым порядком байтов. Вот что означает UTF-16. Люди могут неправильно называть свои файлы UTF-16, имея в виду UTF-16LE. Это было бы ошибкой. Если файл помечен как UTF-16, он должен соответствовать стандарту. Как строка хранится внутри компьютера, не имеет значения; внутренне (как и целые числа) он, вероятно, имеет собственный порядок байтов. Форматы UTF - это схемы для обмена (передачи, откуда берется буква T) данных между компьютерами. - person rici; 14.04.2016
comment
@HostileFork: я полностью за использование UTF-8, но я не знаю, что разработчик приложения может избежать этих проблем и принять UTF-8, кроме как отклонением любых данных, которые они получают в других форматах. . Это, конечно, привилегия разработчика приложения, но это может быть сочтено недружелюбным для тех, чьи данные находятся в другом формате. Я склонен требовать правильной маркировки данных (хотя я мог бы сделать отметку в документации о последствиях неправильной маркировки). - person rici; 14.04.2016

Нет. Разве вы не видите, что компьютеры с прямым порядком байтов все время получают пакеты из Интернета, что является прямым порядком байтов?

Кодировка зависит от того, как вы записываете в память, а не от вашей архитектуры.

person phuclv    schedule 11.04.2016
comment
Cound поможет с вопросом, что если я напрямую создаю строку UTF-16 в C, порядок байтов строки будет зависеть от порядка байтов машины. Строка ASCII сохраняется по одному байту, потому что это однобайтовый символ, но как насчет Строка UTF-16 (не UTF-16BE или UTF-16LE, ссылка на ответ rici). Меня смущает, что порядок байтов целого числа в программе C зависит от порядка байтов машины, в то время как UTF-16BE, UTF-16LE и UTF-16 могут быть напрямую Созданный на Python, каким-то образом ограничение на порядок байтов удалено (могут быть созданы как UTF-16BE, так и LE), а ограничение порядка байтов в UTF-16 все еще существует. - person hao.zhou; 14.04.2016
comment
порядок байтов строки не зависит от порядка байтов машины. Вы всегда можете изменить порядок байтов на любом компьютере, поэтому всегда можно создать файл с прямым порядком байтов на машине с прямым порядком байтов. - person phuclv; 14.04.2016

Схемы кодирования Unicode определены в разделе 3.10 стандарта Unicode. Стандарт определяет семь схем кодирования:

  • 8 бит: UTF-8
  • 16 бит: UTF-16BE, UTF-16LE и UTF-16
  • 32-разрядная версия: UTF-32BE, UTF-32LE и UTF-32

В случае 16- и 32-битных кодировок три варианта различаются порядком байтов, который может быть явным или обозначаться началом строки с Знак порядка байтов (BOM), U + FEFF:

  • Вариант LE определенно является прямым порядком байтов; младший байт кодируется первым. Спецификация не разрешена, поэтому начальный символ U + FEFF представляет собой неразрывный пробел нулевой ширины.
  • Вариант BE определенно имеет прямой порядок байтов; сначала кодируется старший байт. Как и в случае с вариантом LE, спецификация не разрешена, поэтому начальный символ U + FEFF является безразрывным пробелом нулевой ширины.
  • Вариант без знака обратного порядка может быть прямым или обратным. Обычно он начинается со спецификации, которая определяет порядок байтов. Если нет спецификации, то предполагается обратное кодирование.

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

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

person rici    schedule 11.04.2016
comment
Согласно Википедии: Если спецификация отсутствует, RFC 2781 говорит, что следует использовать кодировку с прямым порядком байтов. (На практике, из-за того, что Windows по умолчанию использует прямой порядок байтов, многие приложения аналогичным образом предполагают обратный порядок байтов по умолчанию.) - person HostileFork says dont trust SE; 11.04.2016
comment
@HostileFork: Если бы я был википедистом, я бы пометил эту цитату (где бы она ни находилась; ее нет в статье спецификации) необходимой цитатой. Что это за приложения? RFC2781 был написан в 2000 году, когда Unicode был в версии 3.0; время идет, и приложения гораздо больше осведомлены о стандартах, чем раньше. - person rici; 12.04.2016
comment
@HostileFork Я проверяю документы, сохраненные как UTF-16 UTF-16LE UTF-16BE в Ubuntu gedit - открывать файлы как двоичные и читать по одному байту в python. Точно, UTF-16 имеет U + FFFE (прямой порядок байтов такой же, как и моя машина) сначала два байта в файле, а UTF-16BE или LE - нет. Этот ответ такой же, как и то, что я вижу до сих пор. Хауэрвер, вопрос в том, что нужно больше подумать, кажется, что моя маленькая конечная машина производит little endian utf-16 с маленькой endian спецификацией, если я создаю строки в Python, закодированные в utf16, endianness зависит от машины? - person hao.zhou; 12.04.2016
comment
@ hao.zhou Я расширил свой ответ, чтобы попытаться ответить на ваш вопрос и включить больше вопросов, поднятых здесь. - person HostileFork says dont trust SE; 12.04.2016