19个版本

0.1.17 2021年12月23日
0.1.15 2021年10月17日
0.1.13 2021年6月15日
0.1.10 2020年11月26日
0.0.1 2019年6月12日

#30 in 文本处理

Download history 5516/week @ 2024-04-23 5811/week @ 2024-04-30 5145/week @ 2024-05-07 5878/week @ 2024-05-14 5694/week @ 2024-05-21 5832/week @ 2024-05-28 6052/week @ 2024-06-04 5458/week @ 2024-06-11 5055/week @ 2024-06-18 7032/week @ 2024-06-25 6823/week @ 2024-07-02 6690/week @ 2024-07-09 7941/week @ 2024-07-16 6478/week @ 2024-07-23 7868/week @ 2024-07-30 8386/week @ 2024-08-06

每月 32,054 次下载
用于 60 Crates (直接使用26个)

Apache-2.0 OR MIT

330KB
5K SLoC

chardetng

docs.rs Apache 2 / MIT dual-licensed

为旧版Web内容提供字符编码检测器。

许可

请参阅命名为 COPYRIGHT 的文件。

文档

在线可用的API文档已生成。

一篇关于设计动机的详细介绍

目的

该检测器的目的是通过确保旧Web内容在Chrome中使用不如Firefox方便,从而提高Firefox的用户保留率。(Chrome部署了ced,这使得Firefox的使用不那么方便,直到部署了此检测器。)

关于名称

chardet 是Mozilla旧编码检测器的名称。我将这个名字改为 chardetng,因为这是Firefox中下一代编码检测器。与旧 chardet 没有代码重用。

优化目标

本库的目标是比ICU更准确,比 chardet 更全面,比 compact_enc_det(即ced)更可解释和可修改,并且在依赖于 encoding_rs 的应用程序中,比 compact_enc_det 的二进制占用空间更小。

Rayon支持

启用可选功能 multithreading 使得 chardetng 并行运行单个编码的检测器。遗憾的是,性能并不会随着CPU核心数的增加而线性增长,但如果只有一个 chardetng 实例运行,其墙钟时间性能仍然优于单线程。就CPU核心使用率而言,multithreading 模式比单线程模式差得多,所以如果您能在某些高级任务中找到一个并行化点,以便可以并行运行多个 chardetng 实例,每个实例在一个单独的线程上运行,您将得到更好的结果。

no_std 支持

chardetng 在没有分配器的 no_std 环境中运行。

工作原理

一般来说,chardetng 更喜欢进行否定匹配(从可能的编码集合中排除可能性)而不是进行肯定匹配。由于否定匹配不足,也存在肯定匹配。

  • 除了 ISO-2022-JP 外,ASCII 字节的成对永远不会对检测做出贡献,这相当于在不具备 HTML 识别状态机的情况下忽略 HTML 语法。
  • 单个编码错误会使编码从可能的输出集合中淘汰。值得注意的是,随着输入长度的增加,输入在作为 CJK 旧编码有效的情况下,未经有意作为此类编码,其可能性越来越小。此外,还有单字节编码,在由其他编码积极使用的区域具有未映射的字节,因此这些字节非常有效地缩小了可能性集。
  • 单个 C1 控制字符的出现会使编码从可能的输出中淘汰。
  • 第一个非 ASCII 字符是半角片假名字符会使编码失效。(这对于决定 Shift_JIS 和 EUC-JP 非常有效。)
  • 对于单字节编码,根据其在适用维基百科中的相对频率对字符对给出评分。
  • 还有一些较小的惩罚规则,例如
    • 对于双字母表脚本编码,大写字母跟在小写字母后面会受到惩罚。
    • 对于拉丁字母编码,连续三个非 ASCII 字母会受到轻微惩罚,而连续四个或更多会受到严重惩罚。
    • 对于非拉丁字母编码,非拉丁字母紧挨着拉丁字母会受到惩罚。
    • 对于单字节编码,如果字符对(不包括两个字符都是 ASCII 的对)在适用语言的相关维基百科中从未出现,会受到严重惩罚。
    • 土耳其语 I 与类似空格的字符配对不会得到评分,以避免检测到英语是土耳其语。
    • 有一个专门的状态机用于为 windows-1252 序列指示符评分,否则很难评分而不破坏 windows-1250 罗马尼亚检测。
    • 0xA0 在大多数单字节编码中是非间断空格,在 IBM866 和 CJK 编码中被特殊处理以避免误检测。

关于编码的注意事项

UTF-8
仅在 `guess` 方法的参数显式允许的情况下检测。在没有要求用户操作(例如选择菜单项)的情况下,Web 浏览器检测 UTF-8 是有害的,因为 Web 开发人员将开始依赖检测。
UTF-16[BE|LE]
未检测到:检测这些属于 BOM 层。
x-user-defined
未检测到:此编码用于 XHR。HTML 中的 <meta charset=x-user-defined> 没有标签,意味着 windows-1252。
替换
未检测到。
GB18030
检测为GBK。
GBK
Big5
EUC-KR
Shift_JIS
windows-1250
windows-1251
windows-1252
windows-1253
windows-1254
windows-1255
windows-1256
windows-1257
windows-1258
windows-874
ISO-8859-2
ISO-8859-7
检测到:历史区域特定回退。
EUC-JP
ISO-2022-JP
KOI8-U
ISO-8859-5
IBM866
检测到:过去和现在的多个浏览器都检测到了。
KOI8-R
检测为 KOI8-U。 (始终猜测U变体不太可能损坏非框绘制字符。)
ISO-8859-8-I
检测为 windows-1255。
ISO-8859-4
检测到:IE和Chrome检测到;IE和Firefox中的菜单项。
ISO-8859-6
检测到:IE和Chrome检测到。
ISO-8859-8
检测到:在IE和Firefox的菜单中可用。
ISO-8859-13
检测到:Chrome检测到。这种编码与windows-1257非常相似,因此可以将windows-1257的菜单项视为包含这一项。由于检测器的机制,如果没有将其作为单独的项目包含在内,windows-1257的检测就不会捕获使用花括号引号且作为windows-1257无效的情况。
x-mac-cyrillic
未检测到:IE和Chrome未检测到。(以前被Firefox检测到。)
ISO-8859-3
ISO-8859-10
ISO-8859-14
ISO-8859-15
ISO-8859-16
macintosh
未检测到:这些编码从未在主要浏览器中作为区域特定回退或IE中的菜单项。

已知问题

  • GBK检测在ced中对于少于六个汉字的短标题不如准确。这主要是由于设计优先考虑优化二进制大小,而不是非常短输入的准确性。
  • 对于短输入,泰语检测不准确。
  • windows-1257检测非常不准确。(此检测器目前不使用三联组。ced使用8 KB的三联组数据来解决此问题。)
  • 在非通用域名上,一些可能与TLD本地编码混淆的编码除非根据所有TLD本地编码输入无效,否则直接排除猜测。

相关工具

  • traindet 工具用于计算生成的代码的统计数据
  • detector_char_classes 对单字节编码中的字符进行分类
  • charcounts traindet的中间文件,使其能够在不重新运行统计收集的情况下重新运行代码生成
  • testdet 测试工具

路线图

没有计划改进。

  • 研究使用Rayon并行化feed方法。
  • 改善短输入的windows-874检测。
  • 改善短输入的GBK检测。
  • 重新组织频率数据,以便区分短GBK、EUC-JP和EUC-KR输入。
  • 使通用域名上的立陶宛语和拉脱维亚语检测更加准确(可能需要查看三联组)。
  • 调整中欧检测。
  • 调整非通用TLD上的混淆编码的惩罚,以在非通用TLD上实现混淆编码的检测。
  • 通过不存储不可能的邻近字母字符类的评分来减少二进制大小。
  • 通过算法化分类ASCII来减少二进制大小。
  • 通过不存储C1控制字符的评分来减少二进制大小。

发布说明

0.1.17

  • 处理随后的windows-1252版权符号之后的非空间空间字节。

0.1.16

  • 将周围有空格的windows-1252版权符号检测为windows-1252。

0.1.15

  • 使crate在no_std下工作而不需要分配器。

0.1.14

  • 添加guess_assess,它提供了有关猜测的更多信息。
  • cfg-if依赖项升级到1.0。

0.1.13

  • 撤销对CJK额外评分的限制(从版本0.1.10开始)。此更改从未在Gecko中得到应用,因此没有经过实际遥测的验证。
  • 检测包含大量半角片假名的输入。

0.1.12

  • 修复上一版本中添加的代码中的边缘情况疏忽。

0.1.11

  • 允许Windows和Classic Mac OS扩展到旧CJK编码,并允许JIS X 0213扩展到Shift_JIS和EUC-JP(不是ISO-2022-JP)。

0.1.10

  • 在看到足够多的额外评分资格字符后停止计算常用CJK字符的额外评分。(提高长CJK输入的性能。)
  • 添加Rayon支持。
  • 避免将windows-1252欧元符号检测为GBK。

0.1.9

  • 修复ASCII前缀跳过中的错误。(自0.1.7以来引入。)

0.1.8

  • 避免将无间断空格中的英语检测为GBK或EUC-KR。

0.1.7

  • 避免将windows-1252英语错误检测为windows-1254。
  • 避免将windows-1252英语错误检测为IBM866。
  • 通过不对字母旁边的数字进行单字节编码评分来提高中文和日语检测。
  • 通过考虑序数指示符的使用来提高意大利语、葡萄牙语、卡斯蒂利亚语、加泰罗尼亚语和加利西亚语的检测。
  • 减少查找表的大小。

0.1.6

  • 调整中欧检测。

0.1.5

  • 大幅提高泰语准确性。
  • 稍微提高一些语言的准确性。
  • 删除未使用的希伯来ASCII表。

0.1.4

  • 对于windows-1252,正确考虑单词边界上的非ASCII字节。(特别是对意大利语和加泰罗尼亚语很重要。)
  • 将爱沙尼亚语从波罗的海模式移动到西方模式。这提高了整体的爱沙尼亚语检测,但导致以windows-1257、ISO-8859-13或ISO-8859-4编码的š和ž被错误解码。(可以通过添加后处理步骤来调整š和ž,但这会导致由于chardetng与Firefox的集成方式,需要重新加载。)
  • 为了防止将非ISO-8859-4输入错误检测为ISO-8859-4,正确分类ISO-8859-4有但windows-1257没有的字母。
  • 提高windows-1254的字符分类。
  • 避免将字节0xA1或以上分类为空格类。
  • 通过合并相似字符类来减小二进制大小。

0.1.3

  • 如果UTF-8有效但被禁止,则返回TLD关联的编码。

0.1.2

  • 如果UTF-8有效并且被允许,即使全部是ASCII,也返回UTF-8。
  • 如果UTF-8有效但被禁止,因为各种测试用例需要,则返回windows-1252。

0.1.1

  • 更频繁地检测视觉希伯来语。

0.1.0

  • 初始发布。

依赖项

~4MB
~128K SLoC