Pregunta Adivinar la codificación del texto representado como byte [] en Java


Dado un conjunto de bytes que representa texto en una codificación desconocida (normalmente UTF-8 o ISO-8859-1, pero no necesariamente), ¿cuál es la mejor manera de obtener una estimación de la codificación más utilizada (en Java)?

Digno de notar:

  • No hay metadatos adicionales disponibles. La matriz de bytes es literalmente la única entrada disponible.
  • El algoritmo de detección obviamente no será 100% correcto. Si el algoritmo es correcto en más del 80% de los casos, eso es suficiente.

32
2017-11-04 23:54


origen


Respuestas:


El siguiente método soluciona el problema usando juniversalchardet, que es un puerto Java de la biblioteca de detección de codificación de Mozilla.

public static String guessEncoding(byte[] bytes) {
    String DEFAULT_ENCODING = "UTF-8";
    org.mozilla.universalchardet.UniversalDetector detector =
        new org.mozilla.universalchardet.UniversalDetector(null);
    detector.handleData(bytes, 0, bytes.length);
    detector.dataEnd();
    String encoding = detector.getDetectedCharset();
    detector.reset();
    if (encoding == null) {
        encoding = DEFAULT_ENCODING;
    }
    return encoding;
}

El código anterior ha sido probado y funciona como intentado. Simplemente agregue juniversalchardet-1.0.3.jar a la ruta de clases

He probado ambos juniversalchardet y jchardet. Mi impresión general es que juniversalchardet proporciona la mejor precisión de detección y la mejor API de las dos bibliotecas.


29
2017-11-05 07:04



También hay Apache Tika - un kit de herramientas de análisis de contenido. Puede adivinar el tipo de mimo, y puede adivinar la codificación. Por lo general, la suposición es correcta con una probabilidad muy alta.


4
2017-09-20 12:38



Aquí está mi favorito: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

Funciona así:

  • Si hay una lista de materiales UTF-8 o UTF-16, devuelva esa codificación.
  • Si ninguno de los bytes tiene el bit de orden alto establecido, devuelva ASCII (o puede forzarlo a devolver una codificación predeterminada de 8 bits en su lugar).
  • Si hay bytes con el conjunto de bits alto pero están dispuestos en los patrones correctos para UTF-8, devuelva UTF-8.
  • De lo contrario, devuelva la codificación predeterminada de la plataforma (por ejemplo, windows-1252 en un sistema Windows de configuración regional en inglés).

Puede sonar demasiado simplista, pero en mi trabajo diario es más del 90% de precisión.


3
2017-11-05 12:46



La respuesta de Chi parece más prometedora para el uso real. Solo quiero agregar que, de acuerdo con Joel Spolsky, Internet Explorer usó un algoritmo de adivinación basado en frecuencia en su día:

http://www.joelonsoftware.com/articles/Unicode.html

Hablando en términos generales, todo el supuesto texto es copiado y analizado en cada codificación imaginable. Cualquiera que sea el parse que mejor se ajuste al perfil de frecuencia de una palabra (y una letra) de un idioma, gana. No puedo ver rápidamente si jchardet usa el mismo tipo de enfoque, así que pensé en mencionarlo por si acaso.


1
2017-11-05 01:01



Revisa jchardet


0
2017-11-05 00:24



Debería haber cosas ya disponibles

Búsqueda en google apareció icu4j

o

http://jchardet.sourceforge.net/


-1
2017-11-05 01:00



Sin indicador de codificación, nunca lo sabrás con certeza. Sin embargo, puedes hacer algunas conjeturas inteligentes. Ver mi respuesta a esta pregunta,

Cómo determinar si una cadena contiene caracteres codificados no válidos

Use los métodos validUTF8 (). Si devuelve verdadero, trátelo como UTF8, de lo contrario como Latin-1.


-1
2017-11-05 01:28