全球首个逐字体易混淆字符数据集。 哪些 Unicode 字符看起来像哪些字符,是从字体的轮廓而非像素中测量得出的。当前版本 2026.09.26 比较了 322 种字体中每个字母和数字所绘制的字形,采用每个字形在正文中的大小和基线位置。然后对 ASCII 字母和数字的相似字符进行原位检查:将它们置于常用字体中其他字母之间,以人们阅读时的大小呈现,并与公认为相似的字符对(如 0 和 O)进行比较。
addons.mozilla.org 使用 confusable-vision 中的字符来检查附加组件名称中的相似字符,已在 Mozilla 源码中注明出处;参见使用方。

src/olympia/amo/confusables.py,拉取请求 #24468、#24541、#24612 和 #24665(2026 年 2 月至 3 月)。data/confusables_supplement.tsv、data/confusables_vision.tsv。docs/hkb.md)。这些项目的数据来自 confusable-vision 2026 年 2 月和 3 月的输出。
在 Hacker News 上的讨论:我在 230 种字体上渲染了 1,418 个易混淆字符 和 Confusables.txt 与 NFKC 在 31 个字符上存在分歧。
版本 2026.09.26 的数据:
数据以版本化发布形式发布于 data/release/2026.09.26/(CC-BY-4.0)。namespace-guard 和 d0ma1n 基于它构建。
版本 2(2026.09.24,TLD 数据为 2026.09.25)仅比较了早期运行中比较过的字符对和字体。对相同字形的审计发现,在字体用相同字形绘制两个字符的 2,654 个案例中,它只捕获了 637 个。版本 3 修复了这一问题并增加了三项内容:
2026 年 3 月的数据(245 种字体中的 249,976 个单字符对和 2,524,275 个双字母对)来自忽略大小和基线的测量。它们已被取代;那些运行的文件保留在 data/output/ 中供参考。
RaySpace 以 36 个角度向每个字形的轮廓投射平行射线,每个角度 50 条射线,并记录每条射线的五项信息:它穿过轮廓多少次、在哪里、以什么角度、每次穿过墨迹的距离(其 ping,即笔画沿射线的宽度),以及笔画之间的最宽间隙。每个字形测量两次:在其自身框中,用于形状;在基线上的固定框架中,以便大小和位置计入。当形状距离低于 0.5 且基线锚定距离低于 0.2 时,两个字符在一种字体中相似。比较在 Rust(native/cv-pairs)中运行,使用所有核心。
孤立测量的相似字符在一行文本中仍可能显得突出。因此,每个 ASCII 字母、数字或序列的候选相似字符都被置于邻居之间(pa_nel、20_5),在五种上下文中:系统字体 13 px,以及 Helvetica、Arial、Times New Roman 和 Georgia 16 px,每种在设备像素比为 1 和 2 下,使用平台的字体回退。不进行任何缩放:相似字符在其落入行中的位置进行比较。
每个上下文中的标准来自公认为相似的字符对:0 和 O、1 和 l、I 和 l,仅在该上下文以相同大小和位置绘制它们时计入。相似字符分为:
检查项,对两个字形均以设备分辨率的四倍栅格化:当窄于一个设备像素的间隙闭合后,片段和孔洞数量相同;字腔方形或圆形相似,位置相同且大小大致相同;与邻居的间距;墨迹的顶部、底部和宽度;从右到左字符对其周围数字的重排序;笔画粗细;每侧的形状(镜像);墨迹伸入每个角的程度;倾斜;中间的竖笔(Y 对 V);以及穿过竖笔的横杠(Ŧ 对 T)。双字母序列逐字母检查。
这些层级根据对渲染样本的视觉判断进行调整,并以公认的字符对为锚点。尚未有读者参与的研究。
六个不在 Unicode 的 confusables.txt 中的严格相似字符,每个在所有五种上下文中都相似。macOS 用 Noto 回退字体绘制每一个:

| 字符 | 名称 | 冒充 |
|---|---|---|
| ᱛ U+1C5B | OL CHIKI LETTER AT | O |
| ꢝ U+A89D | SAURASHTRA LETTER TTHA | O |
| 𖩠 U+16A60 | MRO DIGIT ZERO | O |
| 𑫤 U+11AE4 | PAU CIN HAU LETTER FINAL Y | O |
| ᦞ U+199E | NEW TAI LUE LETTER LOW VA | o |
| ᧐ U+19D0 | NEW TAI LUE DIGIT ZERO | o |
大多数相似域名背后的 ASCII 替换仅在某些字体中成立。I 替换 l 在系统字体、Helvetica 和 Arial 中几乎相同。1 替换 l 仅在 Times New Roman 中成立,0 替换 o 仅在 Georgia 中成立(其数字为小写高度),rn 替换 m 仅在标准密度屏幕上 Arial 16 px 中成立。d 替换 cl 和 w 替换 vv 在 16 px 下不成立。
顺带发现:macOS 和 iOS 附带的 Georgia 将 ⅳ(U+2173,SMALL ROMAN NUMERAL FOUR)绘制得与 ⅸ(九)完全相同。Windows 11 的 Georgia 是正确的。该问题于 2026 年 3 月首次在 Microsoft Q&A 上报告,并已报告给 Apple。
| 文件 | 每行对应 |
|---|---|
characters.jsonl.gz | 测量的码点,含文字、类别、TR39 标识符类型、IDNA2008 状态以及其注册机构接受它的 TLD |
lookalikes.jsonl.gz | 在至少一种字体或组合中相似的字符对,含其背后的计数和每种字体中的距离 |
sequences.jsonl.gz | 与双字符 ASCII 序列相似的字符 |
in-place.jsonl.gz | 原位检查的候选相似字符,含判定结果和每个上下文中失败的检查 |
DATASET.md 给出了每个字段、比较了什么、缺失字符对的含义以及建议阈值。通过版本号固定发布版本。其他已提交的输出:
| 文件 | 描述 |
|---|---|
data/output/idn-relevant-pairs.json | 发布的 IDN 视图:2,923 对通过其阈值且其字符均可在通用 TLD 注册的字符对。npx tsx scripts/export-idn-pairs.ts |
data/output/confusable-weights-v4.json、font-specific-weights-v4.json | namespace-guard 的权重:涉及 ASCII 字母或两种文字的字符对,按它们相似的字体比例评分(总体和每种字体)。scripts/generate-weights-release.ts、scripts/generate-font-weights-release.ts |
data/output/unicode-submission/ | 对 Unicode 易混淆字符数据的拟议补充,含每行背后的测量。scripts/build-unicode-submission.ts |
data/input/tld-rules.json | 每个已委派 TLD 的注册机构在二级接受的字符,来自 IANA 的 IDN 表、ICANN 注册协议和研究的国家代码政策。scripts/build-tld-rules.py;d0ma1n 导入它 |
需要 macOS(Core Text 设置文本)、Node 22 或更高版本、Rust,以及用于 Swift 辅助工具的 Xcode 命令行工具。
npm install
(cd native/cv-pairs && cargo build --release)
# Every pair in every font, across fonts, and the sequences (about two hours on an M-series Mac)
npx tsx scripts/score-all.ts --scope all --cross --sequences --out all-pairs-v8
# The in-place check (about 15 minutes), and the ASCII pairs Unicode lists
node --import tsx scripts/in-place.ts --run all-pairs-v8
node --import tsx scripts/in-place.ts --run all-pairs-v8 --pairs data/input/ascii-known.txt --how "Unicode (ASCII)" \
--out data/output/all-pairs-v8.ascii.in-place.jsonl
# The release, its IDN view, and the weights
npx tsx scripts/build-release.ts 2026.09.26 --run all-pairs-v8
npx tsx scripts/export-idn-pairs.ts
npx tsx scripts/generate-weights-release.ts data/release/2026.09.26
npx tsx scripts/generate-font-weights-release.ts data/release/2026.09.26
# The README's figures
swiftc -O scripts/render-readme-figures.swift -o /tmp/figs && /tmp/figs docs/images