iconv генератор UTF-16 с спецификацией

11

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

Команда 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генерирует UTF-16 с прямым порядком байтов без спецификации.

Это:

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

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

Я всегда могу использовать utf-16beили utf-16leи предварительно добавить спецификацию вручную, но я ищу решение, которое просто использует 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не поддерживает это.

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

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

echo hello | iconv -f ascii -t utf-16 | od -x
Кит Томпсон
источник
1
Спецификация снижает переносимость данных, но вы можете добавить их таким образом
RedGrittyBrick
@RedGrittyBrick: Как это уменьшает переносимость (особенно для UtF-16)? Я знаю, что могу генерировать спецификацию явно; Я ищу способ сделать это, просто используя iconv- и удивляясь, почему -t utf-16кажется, что порядок байтов не указан.
Кит Томпсон
Я предполагаю, что iconv предполагает текущее упорядочение байтов платформы, если вы не укажете это явно. На некоторых платформах, кроме Windows, некоторые инструменты для обработки текста не ожидают спецификации и поэтому делают неправильные вещи. Примером может служить конкатенация текстовых файлов или использование шаблонов на основе файлов для создания содержимого. «Для зарегистрированных в IANA кодировок UTF-16BE и UTF-16LE знак порядка байтов не должен использоваться, поскольку имена этих наборов символов уже определяют порядок байтов»
RedGrittyBrick
Этот вопрос показывает iconv -f UTF-8 -t UTF-16, что в системе с прямым порядком байтов (MacOS) генерируется UTF-16 с прямым порядком байтов и спецификацией, что выглядит очень странно.
Кит Томпсон

Ответы:

9

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

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

Q: Как я должен иметь дело с спецификациями?

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

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

(мой акцент)

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


Обновить.

Отступление

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

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

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

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

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

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

Однако ответ на вопрос « могу ли я использовать команду iconv для генерации вывода UTF-16 с спецификацией и указанным порядком байтов » в настоящее время « Нет ».

RedGrittyBrick
источник
1
А как насчет первого руководства, А.1? Если я хочу создать текстовый файл Unicode, который можно использовать в системе Windows x86, это должен быть файл UTF16 с прямым порядком байтов и спецификацией .
Кит Томпсон
@KeithThompson: системы должны принимать как UTF16LE, так и UTF16BE. По крайней мере, Windows Notepad принимает и то и другое, если .txtв файле есть спецификация.
user1686
@KeithThompson: Я согласен с тем, что рекомендация 1 должна иметь приоритет, однако iconv не позволяет указать спецификацию. Ответ на ваш оригинальный вопрос просто «Нет».
RedGrittyBrick
Не тот ответ, на который я надеялся, а ответ, причем тщательный!
Кит Томпсон
2
Этот ответ помог мне - помог мне узнать, почему я облажался. Стандартная программа Windows для экспорта / импорта из реестра C:\Windows\System32\reg.exeэкспортирует UTF-16 LE с спецификацией и будет читать только UTF-16 LE с спецификацией - не будет читать UTF-16 LE без спецификации и не будет читать UTF-16 BE с спецификацией - Другими словами, он требует спецификации при чтении, но, черт побери, лучше быть правильным! (К счастью, это читается как UTF-8.)
Давидбак