iconv gerando UTF-16 com BOM

11

Inspirado por esta pergunta , posso usar o iconvcomando para gerar saída UTF-16 com uma BOM e com endianness especificado?

O iconvcomando converte texto de uma codificação para outra.

Por exemplo:

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

gera uma representação UTF-16 de "hello\n".

Os arquivos UTF-16 geralmente iniciam com uma BOM (Byte Order Mark), que é uma codificação de 2 bytes do caractere Unicode U+FEFF. Você pode determinar a resistência de um arquivo UTF-16 com a BOM, verificando se os dois primeiros bytes são FE FFou FF FE.

O iconvcomando possui várias opções para gerar a saída UTF-16:

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

Este comando:

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

gera UTF-16 big-endian sem BOM ; parece supor que, se você especificou o endianness, não precisa indicá-lo na saída. Da mesma forma, utf-16legera UTF-16 little-endian sem BOM.

Este:

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

gera (no meu sistema x86 Ubuntu) o UTF-16 little-endian com uma BOM - mas eu vi um relatório de um comando semelhante ao gerar UTF-16 big-endian com uma BOM, mesmo em um sistema little-endian.

Sempre posso usar utf-16beou utf-16lepreceder a lista técnica manualmente, mas estou procurando uma solução que apenas use o iconvcomando.

Outra solução alternativa, se você souber o que -t utf-16gera endianness , é:

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

O que eu gostaria de usar é algo como:

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

mas iconvnão suporta isso.

EDIT:

Alguém com acesso a um sistema Mac OSX x86 pode postar um comentário mostrando a saída (copiada e colada) do seguinte comando?

echo hello | iconv -f ascii -t utf-16 | od -x
Keith Thompson
fonte
1
Um BOM reduz a portabilidade dos dados, mas você pode adicioná-lo desta forma
RedGrittyBrick
@RedGrittyBrick: Como reduz a portabilidade (especificamente para o UtF-16)? Eu sei que posso gerar a lista técnica de maneira simples; Estou procurando uma maneira de fazê-lo apenas usando iconv- e me perguntando por que -t utf-16parece deixar o endianness não especificado.
Keith Thompson
Acho que o iconv assume a ordem de bytes da plataforma atual se você não a especificar explicitamente. Em algumas plataformas que não sejam o Windows, algumas ferramentas de processamento de texto não esperam BOMs e fazem o que está errado. Um exemplo pode ser ao concatenar arquivos de texto ou ao usar modelos baseados em arquivos para construir conteúdo. "Para os conjuntos de caracteres registrados IANA UTF-16BE e UTF-16LE, uma marca de ordem de bytes não deve ser usada porque os nomes desses conjuntos de caracteres já determinam a ordem de bytes"
RedGrittyBrick
Esta pergunta mostra iconv -f UTF-8 -t UTF-16, executada em um sistema little-endian (MacOS), gerando UTF-16 big-endian com uma BOM, o que parece muito estranho.
22412 Keith Thompson

Respostas:

9

Não , se você especificar a ordem dos bytes, iconvnão insere uma BOM.

Isto é do consórcio Unicode

P: Como devo lidar com listas técnicas?

A: Aqui estão algumas diretrizes a seguir:

  1. Um protocolo específico (por exemplo, convenções da Microsoft para arquivos .txt) pode exigir o uso da BOM em determinados fluxos de dados Unicode, como arquivos. Quando você precisar estar em conformidade com esse protocolo, use uma BOM.
  2. Alguns protocolos permitem listas técnicas opcionais no caso de texto não marcado. Nesses casos,
    • Onde um fluxo de dados de texto é conhecido por texto sem formatação, mas de codificação desconhecida, a BOM pode ser usada como uma assinatura. Se não houver BOM, a codificação pode ser qualquer coisa.
    • Onde se sabe que um fluxo de dados de texto é um texto Unicode simples (mas não qual endian), a BOM pode ser usada como uma assinatura. Se não houver BOM, o texto deve ser interpretado como big endian.
  3. Alguns protocolos orientados a bytes esperam caracteres ASCII no início de um arquivo. Se UTF-8 for usado com esses protocolos, o uso da BOM como assinatura do formulário de codificação deve ser evitado.
  4. Onde o tipo exato do fluxo de dados é conhecido (por exemplo, Unicode big endian ou Unicode little endian), a lista técnica não deve ser usada. Em particular, sempre que um fluxo de dados é declarado como UTF-16BE, UTF-16LE, UTF-32BE ou UTF-32LE, uma BOM não deve ser usada.

(minha ênfase)

Espero que iconvesteja tentando ser fiel à última dessas diretrizes.


Atualizar.

Uma digressão

Na minha opinião:

  1. Uma opção para especificar uma lista técnica certamente seria um recurso adicional útil para o iconv.

  2. Um arquivo UTF-16LE sem uma BOM é utilizável no Windows, embora com esforço adicional algumas vezes. Por exemplo, a caixa de diálogo Abrir arquivo do bloco de notas permite selecionar "Unicode", que é o nome da Microsoft para "UTF-16LE" e (sem surpresa) parece funcionar em arquivos sem uma lista técnica.

  3. Posso abrir um arquivo de teste UTF-16LE (sem BOM) ou um arquivo de teste UTF-8 (sem BOM) no Windows Notepad (XP) da maneira usual, por exemplo, clicando duas vezes no nome do arquivo no explorer. Isso me parece útil. Estou ciente de que, algumas vezes, o Windows adivinhará a codificação incorretamente - nesse caso, você precisará informar a codificação do Bloco de notas ao abrir o arquivo. Esse inconveniente significa que a inclusão de uma lista técnica é preferível para arquivos de texto destinados ao uso no Windows.

  4. Se um aplicativo específico não funcionar com nada além de um arquivo UTF-16LE com BOM, eu concordaria que um arquivo UTF-16LE sem BOM não é utilizável para esse aplicativo específico.

  5. Eu suspeito que, se você puder fazer tudo funcionar com UTF-8 (sem BOM), essa é a melhor solução a longo prazo.

No entanto, a resposta para a pergunta " posso usar o comando iconv para gerar saída UTF-16 com uma BOM e com endianness especificado " é atualmente " Não ".

RedGrittyBrick
fonte
1
E a primeira diretriz, A.1? Se eu quiser gerar um arquivo de texto Unicode que possa ser usado em um sistema Windows x86, ele deverá ser um arquivo UTF16 pouco endian com uma BOM .
22412 Keith Thompson
@KeithThompson: Sistemas deve aceitar tanto UTF16LE e UTF16BE. Pelo menos o Windows Notepad aceita os dois, quando se trata de .txt- desde que o arquivo tenha uma BOM.
usar o seguinte comando
@ KeithThompson: Concordo que a diretriz 1 deve ter prioridade, no entanto, iconv não fornece uma maneira de especificar uma lista técnica. A resposta para sua pergunta original é simplesmente "Não".
RedGrittyBrick
Não é a resposta que eu esperava, mas uma resposta e completa!
21312 Keith Thompson
2
Esta resposta me ajudou - me ajudou a aprender por que eu estava ferrado. O programa padrão do Windows para exportar / importar do registro C:\Windows\System32\reg.exeexporta UTF-16 LE WITH BOM e só lê UTF-16 LE WITH BOM - não lê UTF-16 LE sem BOM e não lê UTF-16 LE sem BOM e não lê UTF-16 BE com BOM - em outras palavras, exige a lista técnica ao ler, mas é melhor que seja a certa! (Felizmente, ele lê UTF-8.)
davidbak