Utilisation de la normalisation Unicode pour représenter des chaînes

Les applications peuvent utiliser Unicode pour représenter des chaînes sous plusieurs formes. À mesure que l’acceptation d’Unicode s’est accrue, en particulier via Internet, il est devenu nécessaire d’éliminer les différences non essentielles dans les chaînes Unicode. Les représentations multiples d’une combinaison de caractères compliquent les logiciels, par exemple lorsqu’un serveur Web répond à une demande de page ou qu’un éditeur de liens recherche un identificateur particulier dans une bibliothèque.

Attention

Différentes chaînes Unicode peuvent sembler visuellement identiques, ce qui soulève des problèmes de sécurité. Pour plus d’informations, consultez Considérations relatives à la sécurité : fonctionnalités internationales.

 

En réponse à cette exigence, le Consortium Unicode a défini un processus appelé « normalisation », qui produit une représentation binaire pour toutes les représentations binaires équivalentes d’un caractère. Une fois normalisées, deux chaînes sont équivalentes si et seulement si elles ont des représentations binaires identiques. La normalisation élimine certaines différences, mais préserve la casse.

Pour utiliser la normalisation Unicode, une application peut appeler les fonctions NormalizeString et IsNormalizedString pour réorganiser les chaînes qui s’enregistrent dans Unicode 4.0 TR#15. La normalisation peut aider à améliorer la sécurité en réduisant les représentations de chaînes alternatives qui ont la même signification linguistique. N’oubliez pas, toutefois, que la normalisation ne peut pas éliminer entièrement les représentations alternatives.

Pour obtenir une description détaillée des normes Unicode pour la normalisation, reportez-vous à l’Annexe standard Unicode n° 15 : Formulaires de normalisation Unicode (UAX #15).

Attention

Étant donné que la normalisation peut changer la forme d’une chaîne, les mécanismes de sécurité ou les algorithmes de validation de caractères doivent généralement être implémentés après la normalisation. Pour plus d’informations, consultez Considérations relatives à la sécurité : fonctionnalités internationales.

 

Fournir plusieurs représentations de la même chaîne

Dans de nombreux cas, Unicode autorise plusieurs représentations de ce qui est, sur le plan linguistique, la même chaîne. Par exemple :

  • La majuscule A avec dieresis (umlaut) peut être représentée sous la forme d’un seul point de code Unicode « Ä » (U+00C4) ou de la combinaison de A majuscules et du caractère Dieresis combiné (« A » + « ̈ », c’est-à-dire U+0041 U+0308). Des considérations similaires s’appliquent à de nombreux autres caractères avec des signes diacritiques.
  • La majuscule A elle-même peut être représentée de la manière habituelle (lettre majuscule latine A, U+0041) ou par lettre majuscule latine A (U+FF21). Des considérations similaires s’appliquent aux autres lettres latines simples (majuscules et minuscules) et aux caractères katakana utilisés pour écrire le japonais.
  • La chaîne « fi » peut être représentée par les caractères « f » et « i » (U+0066 U+0069) ou par la ligature « fi » (U+FB01). Des considérations similaires s’appliquent à de nombreuses autres combinaisons de caractères pour lesquelles Unicode définit des ligatures.

Utiliser les quatre formulaires de normalisation définis

Vos applications peuvent effectuer une normalisation Unicode à l’aide de plusieurs algorithmes, appelés « formulaires de normalisation », qui obéissent à différentes règles. Le Consortium Unicode a défini quatre formes de normalisation : NFC (formulaire C), NFD (formulaire D), NFKC (formulaire KC) et NFKD (formulaire KD). Chaque forme élimine certaines différences, mais conserve la casse. Win32 et .NET Framework prennent en charge les quatre formulaires de normalisation.

Le type d’énumération NLS NORM_FORM prend en charge les quatre formulaires de normalisation Unicode standard. Les formulaires C et D fournissent des formulaires canoniques pour les chaînes. Les formulaires non canoniques KC et KD offrent une compatibilité accrue et peuvent révéler certaines équivalences sémantiques qui ne sont pas apparentes dans les formulaires C et D. Toutefois, ils le font au détriment d’une certaine perte d’informations et ne doivent généralement pas être utilisés comme un moyen canonique de stocker des chaînes.

Parmi les deux formes canoniques, la forme C est une forme « composée » et la forme D est une forme « décomposée ». Par exemple, le formulaire C utilise le point de code Unicode unique « Ä » (U+00C4), tandis que le formulaire D utilise (« A » + « ̈ », c’est-à-dire U+0041 U+0308). Ceux-ci s’affichent de façon identique, car « ̈ » (U+0308) est un caractère de combinaison. Le formulaire D peut utiliser n’importe quel nombre de points de code pour représenter un point de code unique utilisé par le formulaire C.

Si deux chaînes sont identiques sous la forme C ou D, elles sont identiques dans l’autre forme. En outre, lorsqu’elles sont correctement affichées, elles s’affichent de façon indistinguable les unes des autres et de la chaîne non normalisée d’origine.

Une fois normalisées, les chaînes ne peuvent pas être retournées de manière cohérente à leur représentation d’origine. Par exemple, si une chaîne avec un mélange de représentations de caractères composées et décomposées est convertie en une forme normalisée, il n’existe aucun moyen de la dé normaliser dans la chaîne mixte d’origine. Par conséquent, si une application nécessite la représentation d’origine de la chaîne, elle doit stocker cette représentation explicitement. Toutefois, la conversion entre les deux formes canoniques est réversible. Une chaîne au format C peut être convertie en forme D, puis revenir à la forme C, et le résultat est identique à la chaîne C de forme d’origine.

Les formulaires KC et KD sont similaires aux formulaires C et D, respectivement, mais ces « formulaires de compatibilité » ont des mappages supplémentaires de caractères compatibles avec la forme de base de chaque caractère. Ces mappages peuvent entraîner la perte de variations de caractères mineures. Ils combinent certains caractères visuellement distincts. Par exemple, ils combinent des caractères pleine largeur et demi-largeur avec la même signification sémantique, ou différentes formes de la même lettre arabe, ou la ligature « fi » (U+FB01) et la paire de caractères « fi » (U+0066 U+0069). Ils combinent également certains caractères qui peuvent parfois avoir une signification sémantique différente, comme un chiffre écrit en exposant, en tant qu’indice ou placé dans un cercle. En raison de cette perte d’informations, les formulaires KC et KD ne doivent généralement pas être utilisés comme formes canoniques de chaînes, mais ils sont utiles pour certaines applications.

Le formulaire KC est un formulaire composé et le formulaire KD est un formulaire décomposé. L’application peut aller et retour entre les formulaires KC et KD, mais il n’existe aucun moyen cohérent de revenir du formulaire KC ou KD à la chaîne d’origine, même si la chaîne d’origine est au format C ou D.

Windows, les applications Microsoft et le .NET Framework génèrent généralement des caractères au format C à l’aide de méthodes d’entrée normales. Dans la plupart des cas, le formulaire C est le formulaire préféré. Par exemple, les caractères du formulaire C sont générés par l’entrée clavier Windows. Toutefois, les caractères importés à partir du Web et d’autres plateformes peuvent introduire d’autres formes de normalisation dans le flux de données.

Les exemples suivants sont tirés de UAX #15 et illustrent les différences entre les quatre formes de normalisation.

Original Formulaire D Formulaire C Notes
« Äffin » « A\u0308ffin » « Äffin » Le ffi_ligature (U+FB03) n’est pas décomposé, car il a un mappage de compatibilité, pas un mappage canonique.${REMOVE}$
« Ä\uFB03n » « A\u0308\uFB03n » « Ä\uFB03n »
« Henri IV » « Henri IV » « Henri IV » Le CHIFFRE ROMAIN IV (U+2163) n’est pas décomposé.${REMOVE}$
« Henry \u2163 » « Henry \u2163 » « Henry \u2163 »
ga ka +dix ga Les différents équivalents de compatibilité d’un seul caractère japonais n’entraînent pas la même chaîne au format C.${REMOVE}$
ka +dix ka +dix ga
hw_ka +hw_ten hw_ka +hw_ten hw_ka +hw_ten
ka +hw_ten ka +hw_ten ka +hw_ten
hw_ka +dix hw_ka +dix hw_ka +dix
kaks k i + a m + ks f kaks Les syllabes hangûl sont conservées sous normalisation.

 

Original Formulaire KD Formulaire KC Notes
« Äffin » « A\u0308ffin » « Äffin » Le ffi_ligature (U+FB03) est décomposé sous la forme KC, mais pas sous la forme C.${REMOVE}$
« Ä\uFB03n » « A\u0308ffin » « Äffin »
« Henri IV » « Henri IV » « Henri IV » Les chaînes obtenues ici sont identiques sous la forme KC.${REMOVE}$
« Henry \u2163 » « Henri IV » « Henri IV »
ga ka +dix ga Différents équivalents de compatibilité d’un seul caractère japonais aboutissent à la même chaîne au format KC.${REMOVE}$
ka +dix ka +dix ga
hw_ka +hw_ten ka +dix ga
ka +hw_ten ka +dix ga
hw_ka +dix ka +dix ga
kaks k i + a m + ks f kaks Les syllabes hangûl sont maintenues sous normalisation. Dans les versions Unicode antérieures, les caractères jamo tels que ks f avaient des mappages de compatibilité à k f + s f. Ces mappages ont été supprimés dans Unicode 2.1.9 pour garantir la maintenance des syllabes hangûl.

 

Notes

Les deux tableaux ci-dessus ont un droit d’auteur de © 1998-2006 Unicode, Inc. Tous droits réservés.

 

Utiliser des formulaires composés pour les glyphes uniques

De nombreuses séquences de caractères qui correspondent à un seul glyphe n’ont pas de formes composées. Même lorsqu’il est normalisé par le formulaire C, un seul glyphe visuel ou élément de texte logique peut être composé de plusieurs points de code Unicode. Par exemple, plusieurs caractères utilisés dans l’écriture lituanienne ont des doubles diacritiques, car ils n’ont que des formes décomposées. Un exemple est U minuscule avec macron et tilde (« ū̃ », U+016b U+0303, où le premier point de code est un U minuscule avec macron et le second est un accent aigu combinant).

Exemple

Vous trouverez un exemple pertinent dans NLS : Exemple de normalisation Unicode.

Utilisation de la prise en charge des langues nationales

Considérations relatives à la sécurité : Fonctionnalités internationales

IsNormalizedString

NormalizeString