
793 paires ambiguës manquantes dans Unicode TR39, premier jeu de données inter-écritures au monde, notation SSIM tenant compte de la police parmi 230 polices et plus de 22 000 caractères
Évaluation empirique de la similarité des glyphes par raycasting vectoriel des contours. Rend les paires de caractères Unicode confusables dans 245 polices système, mesure la similarité structurelle directement à partir des contours (sans pixellisation), et produit des artefacts JSON notés avec des scores de distance continue par police.
Résultats clés issus de 52,6 millions de comparaisons mono-caractère et 190 millions de comparaisons multi-caractères sur 22 581 caractères et 12 systèmes d'écriture :
La sortie alimente directement namespace-guard pour la détection de confusables à l'exécution dans les noms de paquets, les noms de domaine et les identifiants.
RaySpace projette des rayons parallèles à travers les contours des polices à 36 angles et capture cinq couches d'information par glyphe : nombre d'intersections, positions des intersections, angles d'intersection, distances de ping (épaisseur de trait à chaque intersection) et ping max (largeur de contre-forme entre les intersections). Cela produit une signature compacte par caractère et par police. Deux signatures sont comparées avec une distance L1 pondérée sur les cinq couches.
Un filtre en cascade à trois étapes rend la comparaison exhaustive réalisable :
La banque de signatures (294 646+ entrées sur 245 polices ; plus avec --include-uppercase) est précalculée une fois. La découverte s'effectue ensuite par arithmétique mono-thread sur la banque, réalisant 52,6 millions de comparaisons en 31 minutes sans threads ouvriers ni GPU.
npm install
# 1. Construire la banque de signatures de rayons (prérequis, ~24 min)
npx tsx scripts/build-signature-bank.ts
# 1b. Inclure les lettres majuscules latines A-Z (optionnel)
# Par défaut la banque n'inclut que les points de code IDNA PVALID (minuscules,
# chiffres, symboles). Utilisez --include-uppercase pour ajouter A-Z majuscules,
# utile pour l'identification de polices et la comparaison visuelle de marques
# où les formes des majuscules comptent. Le constructeur est repréable, donc
# seuls les points de code supplémentaires sont calculés.
npx tsx scripts/build-signature-bank.ts --include-uppercase
# 1c. Inclure des plages arbitraires de points de code (optionnel)
npx tsx scripts/build-signature-bank.ts --extra-range=0041-005A
# 2. Découverte mono-caractère (22 581 caractères, 12 écritures, ~36 min)
npx tsx scripts/discover-singlechar-sdf.ts --scorer=ray
# 3. Découverte multi-caractère (bigrammes) (676 bigrammes, ~63 min)
npx tsx scripts/discover-multichar-sdf.ts --scorer=ray
# 4. Noter les confusables multi-caractères TR39 connus (~5 min)
npx tsx scripts/score-multichar-sdf.ts --scorer=ray
Le pipeline d'origine basé sur SSIM a noté 26,5 millions de comparaisons sur 230 polices. Il reste fonctionnel mais est remplacé par RaySpace pour toutes les tâches de découverte et de notation.
# Notation des paires confusables TR39
npx tsx scripts/build-index.ts # Construire l'index (~160s, 11 370 PNG)
npx tsx scripts/score-all-pairs.ts # Noter toutes les paires (~65s, 235 000 comparaisons)
# Découverte de nouveaux confusables
npx tsx scripts/build-candidates.ts # Ensemble candidat (~23 000 caractères)
npx tsx scripts/build-index.ts --candidates # Rendre les candidats (~40min, 89 000 PNG)
npx tsx scripts/score-candidates.ts # Noter par rapport aux cibles latines (~15min, 2,9 millions de comparaisons)
# Extraire les découvertes les mieux notées des deux pipelines
npx tsx scripts/extract-discoveries.ts
| Source | Cible | Écritures | Moyenne | Polices | Zéros |
|---|---|---|---|---|---|
| w U+0077 | ԝ U+051D | Latin-Cyrillique | 0,000 | 19 | 19 |
| j U+006A | ϳ U+03F3 | Latin-Grec | 0,013 | 21 | 18 |
| i U+0069 | і U+0456 | Latin-Cyrillique | 0,018 | 62 | 50 |
| s U+0073 | ѕ U+0455 | Latin-Cyrillique | 0,018 | 62 | 46 |
| c U+0063 | с U+0441 | Latin-Cyrillique | 0,019 | 61 | 45 |
| o U+006F | о U+043E | Latin-Cyrillique | 0,020 | 61 | 44 |
| j U+006A | ј U+0458 | Latin-Cyrillique | 0,021 | 60 | 48 |
| x U+0078 | х U+0445 | Latin-Cyrillique | 0,023 | 59 | 50 |
| p U+0070 | р U+0440 | Latin-Cyrillique | 0,024 | 61 | 46 |
| e U+0065 | е U+0435 | Latin-Cyrillique | 0,032 | 61 | 44 |
| a U+0061 | а U+0430 | Latin-Cyrillique | 0,042 | 61 | 45 |
« Zéros » = polices où les contours produisent des signatures de rayons bit-identiques (distance 0,000). Le w latin / ԝ cyrillique est identique dans les 19 polices contenant les deux glyphes.
| Source | Cible | Écritures | Moyenne | Polices |
|---|---|---|---|---|
| ο U+03BF | ჿ U+10FF | Grec-Géorgien | 0,057 | 2 |
| ヘ U+30D8 | へ U+3078 | Katakana-Hiragana | 0,122 | 11 |
| 丶 U+4E36 | ヽ U+30FD | Han-Katakana | 0,125 | 9 |
| 二 U+4E8C | ニ U+30CB | Han-Katakana | 0,249 | 11 |
| 口 U+53E3 | ロ U+30ED | Han-Katakana | 0,268 | 11 |
La codavie géorgienne (U+10FF) forme un anneau de confusables à quatre avec le o latin, le o cyrillique et l'omicron grec, tous en dessous d'une distance de 0,08.
| Bigramme | Cible | Moyenne | Polices | Notes |
|---|---|---|---|---|
| ll | ॥ U+0965 (double danda devanagari) | 0,176 | 8 | Inter-écriture |
| oy | ѹ U+0479 (uk cyrillique) | 0,322 | 16 | Nouveau bigramme confusable inter-écriture |
| rn | m U+006D | 0,531 | 95 | 33 polices en dessous de 0,40 |
| bl | ы U+044B (yeru cyrillique) | 0,797 | 49 | Inter-écriture |
La découverte oy/uk cyrillique est le résultat le plus marquant : le bigramme latin « oy » est visuellement identique à la lettre digraphe cyrillique uk (ѹ) à une distance de 0,000 dans Helvetica et 0,0005 dans Arial Unicode MS.
| Seuil moyen | Paires mono-caractère uniques | Paires multi-caractère uniques |
|---|---|---|
| < 0,50 | 138 | 13 |
| < 1,00 | 4 174 | 1 631 |
| < 1,50 | 59 700 | (bruit) |
| < 2,00 | 249 976 | 2 524 275 |
Trois niveaux d'exploitation recommandés :