Estoy tratando de identificar un personaje extraño que he encontrado en un archivo con el que estoy trabajando:
$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353 \n
0000002
$ od -x file
0000000 0aeb
0000002
El archivo está usando la codificación ISO-8859 y no se puede convertir a 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
Mi pregunta principal es ¿cómo puedo interpretar la salida de od
aquí? Estoy tratando de usar esta página que me permite traducir entre diferentes representaciones de caracteres, pero me dice que 005353
un "punto de código hexadecimal" es 卓
lo que no parece correcto y 0aeb
que un "punto de código hexadecimal" es lo ૫
que, nuevamente, parece incorrecto .
Así que, ¿cómo puedo usar cualquiera de las tres opciones ( 355
, 005353
o 0aeb
) para averiguar qué personaje que se supone que representan?
Y sí, probé con las herramientas Unicode pero tampoco parece ser un carácter 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
Si entiendo la descripción del personaje Unicode U + FFFD, no es un personaje real, sino un marcador de posición para un personaje corrupto. Lo cual tiene sentido ya que el archivo no está realmente codificado en UTF-8.
fuente
iconv
queja porque no especificó el conjunto de caracteres de origen, por lo que utiliza su valor predeterminado que probablemente sea UTF-8.)ë
es lo que veo cuando los datos se usan en otro programa! ¿Pero cómo puedo saber esto? ¿No está en algún lugar de los datos que proporciono? ¿Cómo lo encontraste? Oh, lo había intentadoiconv
con-f ISO-8859
pero se quejó deconversion from
la norma ISO-8859' no se supported`.eb
e ignorar el0x
indicador hexadecimal o lo que sea. Mi ignorancia de este tipo de cosas es profunda. ¿Podría publicar una respuesta explicando que @StephenKitt?iconv
habría tenido éxito; y / o podría haberlo buscado, por ejemplo, en Wikipedia. Para esta codificación muy específica, fileformat.info/info/unicode/char/00eb/index.htm también funciona (Unicode es equivalente a ISO-8859-1 en el rango 128-255, aunque, por supuesto, ninguna codificación UTF es compatible con él )Respuestas:
Su archivo contiene dos bytes, EB y 0A en hexadecimal. Es probable que el archivo esté usando un juego de caracteres con un byte por carácter, como ISO-8859-1 ; en ese conjunto de caracteres, EB es ë:
Otros candidatos serían δ en la página de códigos 437 , Ù en la página de códigos 850 ...
od -x
El resultado es confuso en este caso debido a la resistencia; una mejor opción es la-t x1
que usa bytes individuales:od -x
mapas a losod -t x2
que se leen dos bytes a la vez, y en sistemas little endian emite los bytes en orden inverso.Cuando se encuentra con un archivo como este, que no es válido UTF-8 (o no tiene sentido cuando se interpreta como un archivo UTF-8), no hay una forma infalible de determinar automáticamente su codificación (y conjunto de caracteres). El contexto puede ayudar: si se trata de un archivo producido en una PC occidental en las últimas dos décadas, existe una buena posibilidad de que esté codificado en ISO-8859-1, -15 (la variante del euro) o Windows-1252; si es más antiguo que eso, CP-437 y CP-850 son candidatos probables. Los archivos de sistemas de Europa del Este, o sistemas rusos, o sistemas asiáticos, usarían diferentes conjuntos de caracteres de los que no sé mucho. Luego está EBCDIC ...
iconv -l
enumerará todos los conjuntos de caracteres queiconv
conoce, y puede proceder por ensayo y error desde allí.(En un momento sabía de memoria la mayoría de CP-437 y ATASCII, esos eran los días).
fuente
ë
se describe como00EB
y234
. ¿Qué son esos extra00
? ¿Y por qué no es355
como esperaba de laod
salida? Estoy tratando de obtener una respuesta más general sobre cómo puedo usar laod
salida para identificar el personaje. ¿Podría explicar algo sobre la interpretación de códigos hexadecimales y / o qué información se necesita para poder identificar un carácter desconocido (codificación y cualquier otra cosa)?353
. Entonces el 353 es una representación octal, no decimal. Arghod
significa octal ;-).�
emulador de terminal mostraría el (U + FFFD) como un sustituto de ese byte 0xeb que no forma un carácter válido en UTF-8. No está claro por quéuniprops $(cat file)
(las citas que faltan por cierto) reportarían eso (no sé sobre eseuniprops
comando).unicode "$(cat file)"
en Debian produceSequence '\xeb' is not valid in charset 'UTF-8'
como esperaba.Tenga en cuenta que
od
es la abreviatura de volcado octal , por005353
lo que los dos bytes como palabra octal,od -x
están0aeb
en hexadecimal como palabra, y el contenido real de su archivo son los dos byteseb
y0a
en hexadecimal, en este orden.Entonces ambos
005353
y0aeb
no pueden ser interpretados simplemente como "punto de código hexadecimal".0a
es un avance de línea (LF) yeb
depende de su codificación.file
solo está adivinando la codificación, podría ser cualquier cosa. Sin más información de dónde vino el archivo, etc. será difícil averiguarlo.fuente
od -c
porque eso produce resultados que puedo entender. ¿Cómo podría haber usado el355
que produce para identificar al personaje? ¿Y por qué se imprime en0aeb
lugar deeb0a
si0a
es la nueva línea?Es imposible adivinar con un 100% de precisión el conjunto de caracteres de los archivos de texto.
Las herramientas como chardet , firefox , file -i cuando no se ha definido información explícita de juegos de caracteres (por ejemplo, si un HTML contiene un juego de caracteres meta = ... en la cabeza, las cosas son más fáciles) intentarán usar heurísticas que no son tan malas si El texto es lo suficientemente grande.
A continuación, demuestro la detección de conjunto de caracteres con
chardet
(pip install chardet
/apt-get install python-chardet
si es necesario).Después de tener un buen candidato de juego de caracteres, podemos usar
iconv
,recode
o similar, para cambiar el juego de caracteres del archivo a su juego de caracteres "activo" (en mi caso, utf-8) y ver si adivinó correctamente ...Algunos juegos de caracteres (como iso-8859-3, iso-8859-1) tienen muchos caracteres en común; a veces no es fácil ver si encontramos el juego de caracteres perfecto ...
Por lo tanto, es muy importante tener metadatos asociados con el texto relevante (por ejemplo, XML).
fuente
iconv -f ... -t utf-8
le mostrará los caracteres?iso-8850-1
. iso-8859 es un estándar iso que incluye varias definiciones de chaset. Pruebafile -i ...
iconv -f ISO-8859-1 -t UTF-8 file
Si obtengo un archivo que contiene, por ejemplo, la palabra Begrung, puedo inferir que Begrüßung podría significar. Entonces lo convierto por todos los encodindgs conocidos y miro, si se encuentra uno, lo que lo convierte correctamente.
Por lo general, hay múltiples codificaciones que parecen encajar.
Para archivos más largos, puede cortar un fragmento en lugar de convertir cientos de páginas.
Entonces lo llamaría
y el script prueba, ya sea convirtiéndolo con las codificaciones conocidas, cuál de ellos produce "Begrüßung".
Para encontrar tales personajes, menos suele ser de ayuda, ya que los personajes originales a menudo se destacan. Desde el contexto, generalmente se puede inferir la palabra correcta para buscar. Pero no queremos consultar con un editor hexadecimal, qué byte es este, y luego visitar interminables tablas de codificaciones, para encontrar a nuestro delincuente. :)
fuente