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

时间:2009-11-04 23:54:03

标签: java encoding utf-8 character-encoding

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

值得注意的是:

  • 没有其他元数据可用。字节数组实际上是唯一可用的输入。
  • 检测算法显然不会100%正确。如果算法在80%以上的情况下是正确的,那就足够了。

7 个答案:

答案 0 :(得分:31)

以下方法使用juniversalchardet解决了这个问题,juniversalchardet-1.0.3.jar是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;
}

上面的代码已经过测试并按预期运行。只需将juniversalchardet添加到类路径中即可。

我测试了jchardet和{{3}}。我的总体印象是,juniversalchardet提供了更好的检测准确性和两个库的更好的API。

答案 1 :(得分:4)

这是我最喜欢的:https://github.com/codehaus/guessencoding

它的工作原理如下:

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

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

答案 2 :(得分:4)

还有Apache Tika - a content analysis toolkit。它可以猜测mime类型,它可以猜测编码。通常猜测是正确的,概率非常高。

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:0)

查看jchardet

答案 5 :(得分:-1)

应该是已有的东西

谷歌搜索出现了icu4j

http://jchardet.sourceforge.net/

答案 6 :(得分:-1)

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

How to determine if a String contains invalid encoded characters

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