¿Cómo puedo adivinar mejor la encoding cuando falta la lista de ordenes de bytes (BOM)?

Mi progtwig tiene que leer archivos que usan varias codificaciones. Pueden ser ANSI, UTF-8 o UTF-16 (endian grande o pequeño).

Cuando la BOM (Marca de orden de bytes) está allí, no tengo ningún problema. Sé si el archivo es UTF-8 o UTF-16 BE o LE.

Quería suponer que cuando no había una lista de materiales, el archivo era ANSI. Pero he descubierto que los archivos con los que trato a menudo pierden su lista de materiales. Por lo tanto, ninguna lista de materiales puede significar que el archivo es ANSI, UTF-8, UTF-16 BE o LE.

Cuando el archivo no tiene lista de materiales, ¿cuál sería la mejor manera de escanear parte del archivo y adivinar de forma más precisa el tipo de encoding? Me gustaría estar cerca del 100% del tiempo si el archivo es ANSI y en los 90 altos si es un formato UTF.

Estoy buscando una forma algorítmica genérica para determinar esto. Pero en realidad uso Delphi 2009, que conoce Unicode y tiene una clase TEncoding, por lo que algo específico sería una ventaja.


Responder:

La respuesta de ShreevatsaR me llevó a buscar en Google un “detector de encoding universal delphi” que me sorprendió al tener esta publicación listada en la posición # 1 después de estar viva por solo unos 45 minutos. Eso es rápido googlebotting !! Y también es sorprendente que Stackoverflow llegue al 1er lugar tan rápido.

La segunda entrada en Google fue una entrada de blog de Fred Eaker sobre Detección de encoding de caracteres que enumeraba algoritmos en varios idiomas.

Encontré la mención de Delphi en esa página, y me condujo directamente al Detector de Chasetes ChsDet Free OpenSource en SourceForge escrito en Delphi y basado en el componente i18n de Mozilla.

¡Fantástico! Gracias a todos los que respondieron (todos +1), gracias ShreevatsaR, y gracias de nuevo Stackoverflow, por ayudarme a encontrar mi respuesta en menos de una hora.

Tal vez pueda pagar un script de Python que use Chardet: Universal Encoding Detector . Es una reimplementación de la detección de encoding de caracteres que usa Firefox, y es utilizada por muchas aplicaciones diferentes . Enlaces útiles: el código de Mozilla , el documento de investigación en el que se basa (irónicamente, mi Firefox no detecta correctamente la encoding de esa página), explicación breve , explicación detallada .

Así es como el bloc de notas hace eso

También está el Detector de Codificación Universal de Python el cual puedes verificar.

Mi suposicion es:

  • En primer lugar, compruebe si el archivo tiene valores de bytes menores que 32 (a excepción de tab / nuevas líneas). Si lo hace, no puede ser ANSI o UTF-8. Por lo tanto, UTF-16. Solo tengo que descubrir el endianismo. Para esto, probablemente debas usar alguna tabla de códigos de caracteres Unicode válidos. Si encuentras códigos inválidos, prueba con el otro endianness si eso te sirve. Si encaja (o no), compruebe cuál tiene un mayor porcentaje de códigos alfanuméricos. También puede probar searchung para los saltos de línea y determinar endianness de ellos. Aparte de eso, no tengo idea de cómo verificar el endianness.
  • Si el archivo no contiene valores inferiores a 32 (aparte de dicho espacio en blanco), probablemente sea ANSI o UTF-8. Intente analizarlo como UTF-8 y vea si obtiene algún carácter Unicode inválido. Si lo haces, es probable que sea ANSI.
  • Si espera documentos en codificaciones que no sean Unicode de un solo byte o multibyte no inglesas, entonces no tiene suerte. Lo mejor que puede hacer es algo así como Internet Explorer que hace un histogtwig de valores de caracteres y lo compara con histogtwigs de idiomas conocidos. Funciona muy a menudo, pero a veces también falla. Y tendrá que tener una gran biblioteca de histogtwigs de letras para cada idioma.

ASCII? Ningún sistema operativo moderno usa ASCII nunca más. Todos usan códigos de 8 bits, al menos, lo que significa que es UTF-8, ISOLatinX, WinLatinX, MacRoman, Shift-JIS o cualquier otra cosa que exista.

La única prueba que conozco es comprobar si hay caracteres UTF-8 no válidos. Si encuentra alguno, entonces sabe que no puede ser UTF-8. Lo mismo es posible para UTF-16. Pero cuando no se establece Unicode, será difícil saber qué página de códigos de Windows podría ser.

La mayoría de los editores que conozco tratan esto al permitir que el usuario elija un valor predeterminado de la lista de todas las codificaciones posibles.

Hay un código para verificar la validez de los caracteres UTF.