Estou tentando identificar um caractere estranho que encontrei em um arquivo com o qual estou trabalhando:
$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353 \n
0000002
$ od -x file
0000000 0aeb
0000002
O arquivo está usando a codificação ISO-8859 e não pode ser convertido em UTF-8:
$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text
Minha principal pergunta é como posso interpretar a saída od
daqui? Estou tentando usar esta página que me permite traduzir entre diferentes representações de caracteres, mas ele me diz que 005353
como um "ponto de código hexadecimal" é o 卓
que não parece certo e 0aeb
como um "ponto de código hexadecimal" é o ૫
que, novamente, parece errado .
Então, como posso usar qualquer uma das três opções ( 355
, 005353
ou 0aeb
) para descobrir qual personagem eles devem representar?
E sim, tentei com ferramentas Unicode, mas também não parece ser um caractere UTF válido:
$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
\pS \p{So}
All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode
se eu entendo a descrição do caractere Unicode U + FFFD, ele não é um caractere real, mas um espaço reservado para um caractere corrompido. O que faz sentido, já que o arquivo não é realmente codificado em UTF-8.
fonte
iconv
Reclama porque você não especificar o conjunto de caracteres de origem, para que ele usa o padrão que provavelmente é UTF-8.)ë
é o que vejo quando os dados são usados em outro programa! Mas como eu sei disso? Não está em algum lugar nos dados que forneço? Como você encontrou isso? Oh eu tinha tentadoiconv
com-f ISO-8859
mas reclamouconversion from
ISO-8859' não é supported`.eb
e ignorar o0x
indicador hexadecimal ou o que quer que seja. Minha ignorância desse tipo de coisa é profunda. Você poderia postar uma resposta explicando que @StephenKitt?iconv
teria conseguido; e / ou você poderia ter procurado, por exemplo, na Wikipedia. Para essa codificação muito específica, fileformat.info/info/unicode/char/00eb/index.htm também funciona (o Unicode é equivalente à ISO-8859-1 no intervalo 128-255, embora, obviamente, nenhuma codificação UTF seja compatível com ela. )Respostas:
Seu arquivo contém dois bytes, EB e 0A em hexadecimal. É provável que o arquivo esteja usando um conjunto de caracteres com um byte por caractere, como ISO-8859-1 ; nesse conjunto de caracteres, EB é ë:
Outros candidatos seriam δ na página de código 437 , Ù na página de código 850 ...
od -x
a saída de é confusa neste caso por causa de endianness; uma opção melhor é-t x1
usar bytes únicos:od -x
mapas para osod -t x2
quais lê dois bytes de cada vez, e em sistemas little-endian emite os bytes na ordem inversa.Quando você se deparar com um arquivo como este, que não é válido UTF-8 (ou não faz sentido quando interpretado como um arquivo UTF-8), não há maneira infalível de determinar automaticamente sua codificação (e conjunto de caracteres). O contexto pode ajudar: se for um arquivo produzido em um PC ocidental nas últimas duas décadas, é bem provável que ele seja codificado nas normas ISO-8859-1, -15 (a variante Euro) ou Windows-1252; se for mais antigo, CP-437 e CP-850 provavelmente serão candidatos. Arquivos de sistemas da Europa Oriental ou russos ou asiáticos usariam diferentes conjuntos de caracteres que eu não conheço muito. Depois, há o EBCDIC ...
iconv -l
listará todos os conjuntos de caracteres que vocêiconv
conhece e você pode prosseguir por tentativa e erro a partir daí.(A certa altura, eu sabia a maior parte do CP-437 e ATASCII de cor, eram os dias.)
fonte
ë
é descrito como00EB
e234
. Quais são esses extras00
? E por que não é355
como eu esperava daod
saída? Estou tentando obter uma resposta mais geral sobre como posso usar aod
saída para identificar o personagem. Você poderia explicar algo sobre a interpretação de códigos hexadecimais e / ou quais informações são necessárias para poder identificar um caractere desconhecido (codificação e qualquer outra coisa)?353
. Portanto, o 353 é uma representação octal, não decimal. Argh.od
significa octal ;-).�
(U + FFFD) seria exibido pelo emulador de terminal como um substituto para o byte de 0xeb que não forma um caractere válido no UTF-8. Não está claro por queuniprops $(cat file)
(aspas ausentes) reportaria isso (não sei sobre esseuniprops
comando).unicode "$(cat file)"
no Debian saiSequence '\xeb' is not valid in charset 'UTF-8'
como eu esperaria.Observe que
od
é abreviação de despejo octal , assim005353
como os dois bytes como palavra octal,od -x
está0aeb
em hexadecimal como palavra e o conteúdo real do seu arquivo são os dois byteseb
e0a
em hexadecimal, nesta ordem.Portanto, ambos
005353
e0aeb
não podem ser interpretados como "ponto de código hexadecimal".0a
é um feed de linha (LF) eeb
depende da sua codificação.file
é apenas adivinhar a codificação, poderia ser qualquer coisa. Sem mais informações de onde o arquivo veio, etc., será difícil descobrir.fonte
od -c
desde que produz saída que eu possa entender. Como eu poderia ter usado o355
que produz para identificar o personagem? E por que está imprimindo em0aeb
vez deeb0a
se0a
é a nova linha?É impossível adivinhar com 100% de precisão o conjunto de arquivos de texto.
Ferramentas como chardet , firefox , file -i quando não há informações explícitas sobre charset definidas (por exemplo, se um HTML contém um meta charset = ... na cabeça, as coisas são mais fáceis) tentarão usar heurísticas que não são tão ruins se o texto é grande o suficiente.
A seguir, demonstro a detecção de conjunto de caracteres com
chardet
(pip install chardet
/apt-get install python-chardet
se necessário).Depois de ter um bom candidato a charset, podemos usar
iconv
,recode
ou similar, para alterar o charset de arquivo para o seu charset "ativo" (no meu caso, utf-8) e ver se ele adivinhou corretamente ...Alguns charset (como iso-8859-3, iso-8859-1) têm muitos caracteres em comum - às vezes não é fácil ver se encontramos o charset perfeito ...
Portanto, é muito importante ter metadados associados ao texto relevante (por exemplo, XML).
fonte
iconv -f ... -t utf-8
mostrará os caracteres?iso-8850-1
. iso-8859 é um padrão iso que inclui várias definições de chaset. Tentefile -i ...
iconv -f ISO-8859-1 -t UTF-8 file
Se eu receber um arquivo, que contém, para Instância, o Word Begrung, posso deduzir que Begrüßung pode estar relacionado. Então, eu o converto por todas as codificações conhecidas e veja se um deles foi encontrado, o que o converte corretamente.
Geralmente, existem várias codificações que parecem se encaixar.
Para arquivos mais longos, você pode cortar um trecho em vez de converter centenas de páginas.
Então eu chamaria isso
e o script testa, convertendo-o com as codificações conhecidas, quais delas produzem "Begrüßung".
Para encontrar esses personagens, geralmente menos ajuda, já que os personagens descolados geralmente se destacam. No contexto, a palavra certa a ser pesquisada geralmente pode ser inferida. Mas não queremos verificar com um hexeditor qual é o byte e visitar inúmeras tabelas de codificações para encontrar nosso ofensor. :)
fonte