Aussi disponible en : English · Español · Português · العربية
Normalisateur Unicode
Les quatre formes de normalisation à la fois, avec le détail caractère par caractère de ce que chacune replie, modifie ou jette.
Qu’est-ce que la normalisation Unicode ?
Unicode offre souvent plus d’une façon d’écrire la même chose. La lettre é peut être un seul point de code, U+00E9, ou bien la lettre e suivie d’un accent aigu combinatoire. Les deux s’affichent à l’identique et les deux sont correctes, mais ce sont des suites d’octets différentes : une comparaison naïve les déclare distinctes, une recherche sur l’une ne trouve pas l’autre, et une base de données avec une contrainte d’unicité accepte tranquillement les deux.
La normalisation est le remède. Elle réécrit le texte dans l’une des quatre formes définies, de sorte que tout ce qui signifie la même chose finisse écrit de la même manière. Ces formes s’appellent NFC, NFD, NFKC et NFKD, et le choix entre elles est la partie qui compte vraiment.
Les noms encodent deux décisions indépendantes. Le C signifie composée et le D décomposée : é finit-il en un point de code ou en deux. Le K, plus déroutant, signifie compatibilité, et c’est un axe entièrement différent : il détermine si des caractères qui se ressemblent seulement sont fondus ensemble. Se tromper sur le premier ne coûte rien qu’un lecteur puisse voir. Se tromper sur le second détruit de l’information.
Comment l’utiliser
- Collez n’importe quel texte dans la zone. Les quatre formes sont calculées au fil de la frappe. Chacune est étiquetée canonique ou compatibilité, et signalée lorsqu’elle diffère de ce que vous avez saisi.
- Comparez les trois décomptes sous chaque forme. Les unités UTF-16 sont ce que rapporte la longueur d’une chaîne, les points de code sont ce que compte Unicode, et les caractères sont ce que compte un lecteur. Un même mot peut donner trois réponses différentes, et NFC et NFD divergent sur les deux premières tout en désignant le même texte.
- Regardez ce que lui fait l’astuce de suppression des accents. Le panneau du bas exécute la recette habituelle et montre, caractère par caractère, quelles lettres ont été repliées en ASCII, lesquelles sont restées intactes et lesquelles ont purement disparu.
Le canonique est sûr, la compatibilité ne l’est pas
NFC et NFD sont des formes canoniques. Elles réarrangent sans changer le sens : é en un point de code et é en deux sont véritablement le même caractère, et passer de l’une à l’autre est réversible au sens qui compte, puisque NFC appliqué à la forme décomposée redonne exactement la composée. Les appliquer à un texte quelconque est sans danger, et NFC est ce qu’il vous faut presque toujours, parce que c’est ce qu’attendent le web, les noms de fichiers et la plupart des bases de données.
NFKC et NFKD sont des formes de compatibilité, et il s’agit d’une opération d’une autre nature sous un nom voisin. Elles fondent des caractères sur d’autres auxquels ils ne font que ressembler. Le deux en exposant de m² devient un 2 ordinaire : un mètre carré devient donc m2. La ligature fi devient deux lettres. Le chiffre romain Ⅳ devient les lettres I et V. Le symbole de marque déposée devient TM. La fraction ½ devient 1⁄2. Les chiffres cerclés deviennent des chiffres ordinaires, et les lettres latines pleine chasse des lettres normales.
Rien de tout cela n’est un défaut : c’est exactement l’objectif. Le repli de compatibilité existe pour qu’une recherche sur m2 trouve m², et pour qu’on ne puisse pas usurper un identifiant avec des caractères sosies. Mais il est à sens unique. Une fois un exposant replié en chiffre, impossible de savoir si l’original était m² ou m2, et si cette distinction portait un sens, il a disparu. Employez les formes de compatibilité pour des clés de comparaison et des index de recherche ; ne conservez pas leur sortie comme s’il s’agissait du texte de l’utilisateur.
La mesure qui sous-tend tout cela mérite d’être donnée telle quelle. Sur les 288 767 points de code attribués, NFC en modifie 1120, NFD 13 233, NFKC 4928 et NFKD 17 029. Chaque paire de formes diverge d’une autre quelque part : NFC contre NFKD sur 15 930 points de code à elles seules. Un seul caractère peut aussi enfler spectaculairement : U+FDFA, une ligature arabe, se déploie en dix-huit caractères sous NFKD.
L’astuce anti-accents supprime de vraies lettres
Cherchez comment retirer les accents d’une chaîne et vous trouverez partout la même recette en trois temps : normaliser en NFD, retirer les marques combinatoires, ne garder que l’ASCII. Elle fonctionne à merveille sur l’exemple que tout le monde essaie. café devient cafe, naïve devient naive, et l’astuce est recopiée dans un projet de plus.
Il vaut la peine d’être précis sur l’endroit où cela dérape, car la version courante le raconte à l’envers. L’étape de normalisation ne supprime rien du tout : mesuré sur l’ensemble des lettres latines, retirer les marques combinatoires après NFD en élimine exactement zéro. Les dégâts viennent du filtre ASCII qui suit. Une lettre comme ß, ø, ł, đ, ħ, þ ou æ n’a aucun accent à retirer au départ ; elle traverse la normalisation parfaitement intacte, puis se fait jeter pour le crime de ne pas figurer entre a et z.
Balayé sur les 907 lettres latines d’Unicode, NFD suivi de ce filtre en replie 540 en ASCII et en supprime 367 purement et simplement. Passer à NFKD n’améliore guère les choses : 578 repliées, 329 supprimées, en sauvant 38 lettres que NFD perd parce qu’elles possèdent une décomposition de compatibilité là où elles n’en ont pas de canonique.
Sur des mots ordinaires, le résultat n’a rien de subtil. Straße devient Strae — non pas Strasse, la translittération allemande correcte, mais un mot auquel il manque simplement une lettre. Łódź devient odz. Đà Nẵng devient aNang. Et Ærø, une île danoise, devient la seule lettre r, parce que deux de ses trois lettres sont supprimées et que la survivante est un r ASCII auquel on n’a jamais touché. Si vous devez replier du texte en ASCII, il vous faut une table de translittération, pas une forme de normalisation.
Limites honnêtes
Les quatre formes sont calculées par l’implémentation de la norme intégrée à votre navigateur, celle-là même qu’utilisera votre code. Cette page n’implémente pas la normalisation ; elle vous montre ce que fait la plateforme et en compte les conséquences.
La démonstration de l’astuce anti-accents reproduit délibérément l’extrait populaire, y compris ses plages de marques combinatoires. Elle est là pour montrer ce que fait cette recette précise, non pour être le meilleur replieur ASCII possible : un outil qui emploierait discrètement un meilleur algorithme argumenterait contre quelque chose que personne n’a écrit.
La normalisation n’est pas le repli de casse, et elle ne constitue pas à elle seule une frontière de sécurité. NFKC intervient dans la comparaison d’identifiants de plusieurs normes, mais replier ne suffit pas à rendre deux identifiants sûrs à traiter comme égaux ; les caractères confondables entre écritures forment un autre problème, avec ses propres données Unicode, que cette page n’aborde pas.
Enfin, les chiffres cités plus haut sont liés à une version d’Unicode. Ils ont été mesurés contre celle que livre la bibliothèque standard de Python, recoupés avec l’implémentation de votre navigateur, et le script qui les a produits est versionné à côté du site afin que les nombres puissent être régénérés plutôt que crus sur parole.
Pourquoi est-ce gratuit ?
Parce que cela ne coûte rien à faire tourner. Chaque forme est calculée dans votre navigateur au fil de la frappe ; rien n’est envoyé, rien n’est journalisé, et aucun serveur ne voit votre texte.
Ni compte, ni inscription, ni rien réservé. Le comportement provient de l’annexe Unicode que votre navigateur implémente déjà, et les mesures de cette page sont confrontées à une implémentation distincte en Python : les nombres sont donc une comparaison et non une affirmation.