猜测在Java中表示为byte 的文本的编码

给定一些代表某些未知编码(通常是UTF-8或ISO-8859-1,但不一定如此)的文本的字节数组,最好的方法是获得最可能使用的编码(在Java中)的猜测?

值得注意:

  • 没有额外的元数据可用。 字节数组实际上是唯一可用的input。
  • 检测algorithm显然不是100%正确的。 如果algorithm在80%以上的情况下是正确的,那就足够了。

下面的方法使用juniversalchardet来解决这个问题,它是Mozilla编码检测库的Java端口。

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; } 

上面的代码已经过testing,并按照预期工作。 只需将juniversalchardet-1.0.3.jar添加到类path即可。

我已经testing了juniversalchardet和jchardet 。 我的一般印象是juniversalchardet提供了更好的检测精度和更好的API两个库。

还有Apache Tika–一个内容分析工具包 。 它可以猜测的MIMEtypes,它可以猜测编码。 通常这个猜测是正确的,而且可能性很高。

这是我的最爱: http : //glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

它是这样工作的:

  • 如果有UTF-8或UTF-16 BOM,则返回该编码。
  • 如果没有任何字节设置了高位,则返回ASCII(或者强制它返回默认的8位编码)。
  • 如果有高位设置的字节,但是它们以正确的UTF-8模式排列,则返回UTF-8。
  • 否则,返回平台的默认编码(例如,在英语区域Windows系统上的windows-1252)。

这听起来可能过于简单,但在我的日常工作中,精确度超过了90%。

智的答案似乎最有希望的实际使用。 我只想补充一点,根据Joel Spolsky的说法,Internet Explorer在当天使用了基于频率的猜测algorithm:

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

粗略地说,所有假设的文本被复制,并在每个可以想象的编码中被parsing。 无论哪种parsing都适合一种语言的平均单词(和字母?)频率概况最好,胜。 我不能很快看到jchardet是否使用了同样的方法,所以我想我会提到这一点,以防万一。

看看jchardet

应该是可用的东西

谷歌search变成了icu4j

要么

http://jchardet.sourceforge.net/

没有编码指标,你永远不会知道。 但是,你可以做一些聪明的猜测。 看到我对这个问题的回答,

如何确定一个string是否包含无效的编码字符

使用validUTF8()方法。 如果它返回true,则将其视为UTF8,否则视为Latin-1。