【发布时间】:2009-11-04 23:54:03
【问题描述】:
给定一个以某种未知编码(通常为 UTF-8 或 ISO-8859-1,但不一定如此)表示文本的字节数组,猜测最可能使用的编码的最佳方法是什么(在 Java )?
值得注意的是:
- 没有额外的元数据可用。字节数组实际上是唯一可用的输入。
- 检测算法显然不会 100% 正确。如果算法在 80% 以上的情况下是正确的,那就足够了。
【问题讨论】:
标签: java encoding utf-8 character-encoding
给定一个以某种未知编码(通常为 UTF-8 或 ISO-8859-1,但不一定如此)表示文本的字节数组,猜测最可能使用的编码的最佳方法是什么(在 Java )?
值得注意的是:
【问题讨论】:
标签: java encoding utf-8 character-encoding
以下方法使用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;
}
上面的代码已经过测试,可以按预期工作。只需将juniversalchardet-1.0.3.jar 添加到类路径即可。
我已经测试了juniversalchardet 和jchardet。我的总体印象是,juniversalchardet 提供了两个库中更好的检测精度和更好的 API。
【讨论】:
new String(bytes, guessedEncoding).getBytes("utf-8")。
还有Apache Tika - a content analysis toolkit。它可以猜测 mime 类型,也可以猜测编码。通常猜测是正确的概率非常高。
【讨论】:
这是我最喜欢的:https://github.com/codehaus/guessencoding
它是这样工作的:
这听起来可能过于简单,但在我的日常工作中,它的准确率远远超过 90%。
【讨论】:
Chi 的答案似乎最有希望用于实际使用。我只想补充一点,根据 Joel Spolsky 的说法,Internet Explorer 在当时使用了一种基于频率的猜测算法:
http://www.joelonsoftware.com/articles/Unicode.html
粗略地说,所有假定的文本都被复制,并以可以想象的每种编码进行解析。无论哪种解析最适合一种语言的平均单词(和字母?)频率分布,都会获胜。我不能很快看出 jchardet 是否使用相同的方法,所以我想我会提到这一点以防万一。
【讨论】:
查看jchardet
【讨论】:
【讨论】:
如果没有编码指示符,您将永远无法确定。但是,您可以做出一些明智的猜测。请参阅我对这个问题的回答,
How to determine if a String contains invalid encoded characters
使用有效的UTF8() 方法。如果返回 true,则将其视为 UTF8,否则视为 Latin-1。
【讨论】: