iconv генерирует UTF-16 с BOM

iconv генерирует UTF-16 с BOM

Вдохновленэтот вопрос, можно ли использовать iconvкоманду для генерации выходных данных UTF-16 с BOM и указанным порядком байтов?

Команда iconvпреобразует текст из одной кодировки в другую.

Например:

echo hello | iconv -f ascii -t utf-16

генерирует представление UTF-16 "hello\n".

Файлы UTF-16 часто, но не всегда, начинаются с метки порядка байтов (BOM), которая представляет собой 2-байтовую кодировку символа Unicode U+FEFF. Вы можете определить порядок байтов файла UTF-16 с BOM, проверив, являются ли первые два байта FE FFили FF FE.

Команда iconvимеет несколько опций для генерации выходных данных в формате UTF-16:

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//

Эта команда:

echo hello | iconv -f ascii -t utf-16be

генерирует обратный порядок байтов UTF-16без спецификации; похоже, предполагается, что если вы указали порядок байтов, вам не нужно указывать его в выводе. Аналогично, utf-16leгенерирует little-endian UTF-16 без BOM.

Этот:

echo hello | iconv -f ascii -t utf-16

генерирует (на моей системе x86 Ubuntu) little-endian UTF-16сBOM, но я видел отчет о похожей команде, генерирующей big-endian UTF-16 с BOM, даже в системе с little-endian.

Я всегда могу использовать utf-16beили utf-16leи добавить BOM вручную, но я ищу решение, которое просто использует команду iconv.

Другой обходной путь,еслиВы знаете, что -t utf-16порождает порядок байтов:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

Что бы я хотелнравитьсяиспользовать что-то вроде:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

но iconvне поддерживает это.

РЕДАКТИРОВАТЬ :

Может ли кто-нибудь, имеющий доступ к системе x86 Mac OSX, опубликовать комментарий, демонстрирующий (скопированный и вставленный) вывод следующей команды?

echo hello | iconv -f ascii -t utf-16 | od -x

решение1

Нет, если указан порядок байтов, iconvне вставляет BOM.

Это изКонсорциум Unicode

В: Как мне следует поступать с техническими условиями?

О: Вот несколько рекомендаций, которым следует следовать:

  1. Конкретный протокол (например, соглашения Microsoft для файлов .txt) может потребовать использования BOM для определенных потоков данных Unicode, таких как файлы. Если вам нужно соответствовать такому протоколу, используйте BOM.
  2. Некоторые протоколы допускают необязательные BOM в случае неразмеченного текста. В таких случаях
    • Если известно, что поток текстовых данных является обычным текстом, но имеет неизвестную кодировку, BOM может использоваться в качестве подписи. Если BOM отсутствует, кодировка может быть любой.
    • Если поток текстовых данных известен как обычный текст Unicode (но неизвестно, какой порядок байтов), то в качестве подписи можно использовать BOM. Если BOM отсутствует, текст следует интерпретировать как big-endian.
  3. Некоторые байт-ориентированные протоколы ожидают символы ASCII в начале файла. Если с этими протоколами используется UTF-8, следует избегать использования BOM в качестве подписи формы кодировки.
  4. Если известен точный тип потока данных (например, Unicode big-endian или Unicode little-endian), BOM использовать не следует. В частности, всякий раз, когда поток данных объявлен как UTF-16BE, UTF-16LE, UTF-32BE или UTF-32LE BOMне должениспользоваться.

(выделено мной)

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


Обновлять.

Отступление

По моему мнению:

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

  2. Файл UTF-16LE без BOMявляетсяможно использовать в Windows, хотя иногда и с дополнительными усилиями. Например, диалоговое окно «Открыть файл» в Блокноте позволяет выбрать «Unicode», что является названием Microsoft для «UTF-16LE» и (что неудивительно) похоже, работает с файлами без BOM.

  3. Я могу открыть тестовый файл UTF-16LE (без BOM) или тестовый файл UTF-8 (без BOM) в Блокноте Windows (XP) обычным способом, например, дважды щелкнув имя файла в проводнике. Мне это кажется удобным. Я знаю, что иногда Windows неправильно угадывает кодировку - в этом случае вам придется указать Блокноту кодировку при открытии файла. Это неудобство означает, что включение BOM предпочтительнее для текстовых файлов, предназначенных для использования в Windows.

  4. Если конкретное приложение не будет работать ни с чем, кроме файла UTF-16LE с BOM, то я согласен, что файл UTF-16LE без BOM непригоден для этого конкретного приложения.

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

Однако ответ на вопрос "можно ли использовать команду iconv для генерации выходных данных UTF-16 с BOM и указанным порядком байтов?" В настоящее время "Нет".

решение2

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

Для UTF-8 BOM (EF BB BF)

file='main.cpp'
printf '\xEF\xBB\xBF' > $file.utf8
iconv -f ASCII -t UTF-8 $file >> $file.utf8
mv -v $file.utf8 "converted-$file"

Для UTF-16BE BOM(FE FF)

file='main.cpp'
printf '\xFE\xFF' > $file.utf16be
iconv -f ASCII -t UTF-16BE $file >> $file.utf16be
mv -v $file.utf16be "converted-$file"

Для спецификации UTF-16LE (FF FE)

file='main.cpp'
printf '\xFF\xFE' > $file.utf16le
iconv -f ASCII -t UTF-16LE $file >> $file.utf16le
mv -v $file.utf16le "converted-$file"

Примечание:

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

Связанный контент