Verwenden der Unicode-Normalisierung zum Darstellen von Zeichenfolgen

Anwendungen können Unicode verwenden, um Zeichenfolgen in mehreren Formularen darzustellen. Mit wachsender Unicode-Akzeptanz, insbesondere über das Internet, ist die Notwendigkeit entstanden, nicht wesentliche Unterschiede in Unicode-Zeichenfolgen zu beseitigen. Mehrere Darstellungen für eine Kombination von Zeichen erschweren Software, z. B. wenn ein Webserver auf eine Seitenanforderung antwortet oder ein Linker einen bestimmten Bezeichner in einer Bibliothek sucht.

Achtung

Verschiedene Unicode-Zeichenfolgen können visuell identisch erscheinen, was Sicherheitsbedenken aufwirft. Weitere Informationen finden Sie unter Sicherheitsüberlegungen: Internationale Features.

 

Als Reaktion auf diese Anforderung hat das Unicode-Konsortium einen Prozess namens "Normalisierung" definiert, der eine binäre Darstellung für jede der äquivalenten binären Darstellungen eines Zeichens erzeugt. Nach der Normalisierung sind zwei Zeichenfolgen nur dann gleichwertig, wenn sie identische binäre Darstellungen aufweisen. Die Normalisierung beseitigt einige Unterschiede, behält aber die Groß- und Kleinschreibung bei.

Um die Unicode-Normalisierung zu verwenden, kann eine Anwendung die Funktionen NormalizeString und IsNormalizedString aufrufen, um Zeichenfolgen neu anzuordnen, die unicode 4.0 TR#15 zugeordnet sind. Normalisierung kann zur Verbesserung der Sicherheit beitragen, indem alternative Zeichenfolgendarstellungen reduziert werden, die dieselbe linguistische Bedeutung haben. Denken Sie jedoch daran, dass die Normalisierung alternative Darstellungen nicht vollständig beseitigen kann.

Eine ausführliche Beschreibung der Unicode-Standards für die Normalisierung finden Sie im Unicode-Standard anhang 15: Unicode Normalization Forms (UAX #15).

Achtung

Da die Normalisierung die Form einer Zeichenfolge ändern kann, sollten in der Regel Sicherheitsmechanismen oder Zeichenvalidierungsalgorithmen nach der Normalisierung implementiert werden. Weitere Informationen finden Sie unter Sicherheitsüberlegungen: Internationale Features.

 

Bereitstellen mehrerer Darstellungen derselben Zeichenfolge

In vielen Fällen ermöglicht Unicode mehrere Darstellungen der linguistischen Zeichenfolge. Beispiel:

  • Großbuchstaben A mit Dieresis (Umlaut) kann entweder als einzelner Unicode-Codepunkt "Ä" (U+00C4) oder als Kombination aus Groß-/Kleinbuchstaben und dem kombinierenden Dieresiszeichen ("A" + " ̈", d. h. U+0041 U+0308) dargestellt werden. Ähnliche Überlegungen gelten für viele andere Zeichen mit diakritischen Zeichen.
  • Großbuchstabe A selbst kann entweder in der üblichen Weise (lateinischer Großbuchstabe A, U+0041) oder durch fullwidth Latin Capital Letter A (U+FF21) dargestellt werden. Ähnliche Überlegungen gelten für die anderen einfachen lateinischen Buchstaben (Groß- und Kleinbuchstaben) und für die katakana-Zeichen, die im Japanischen verwendet werden.
  • Die Zeichenfolge "fi" kann entweder durch die Zeichen "f" und "i" (U+0066 U+0069) oder durch die Ligatur "fi" (U+FB01) dargestellt werden. Ähnliche Überlegungen gelten für viele andere Zeichenkombinationen, für die Unicode Ligaturen definiert.

Verwenden der vier definierten Normalisierungsformulare

Ihre Anwendungen können eine Unicode-Normalisierung mit mehreren Algorithmen durchführen, die als "Normalisierungsformen" bezeichnet werden und unterschiedliche Regeln befolgen. Das Unicode-Konsortium hat vier Normalisierungsformen definiert: NFC (Form C), NFD (Form D), NFKC (Form KC) und NFKD (Form KD). Jedes Formular beseitigt einige Unterschiede, behält jedoch die Groß- und Kleinschreibung bei. Win32 und die .NET Framework unterstützen alle vier Normalisierungsformulare.

Der NLS-Enumerationstyp NORM_FORM unterstützt die vier Unicode-Standardnormalisierungsformulare. Die Formulare C und D stellen kanonische Formen für Zeichenfolgen bereit. Nicht kanonische Formen KC und KD bieten eine weitere Kompatibilität und können bestimmte semantische Äquivalenzen aufdecken, die in den Formen C und D nicht erkennbar sind. Dies geschieht jedoch auf Kosten eines gewissen Informationsverlusts und sollte im Allgemeinen nicht als kanonische Methode zum Speichern von Zeichenfolgen verwendet werden.

Von den beiden kanonischen Formen ist Form C eine "zusammengesetzte" Form und Form D ist eine "zerlegte" Form. Beispielsweise verwendet Formular C den einzelnen Unicode-Codepunkt "Ä" (U+00C4), während Form D ("A" + " ̈", also U+0041 U+0308) verwendet. Diese werden identisch gerendert, da "̈" (U+0308) ein kombinierendes Zeichen ist. Form D kann eine beliebige Anzahl von Codepunkten verwenden, um einen einzelnen Codepunkt darzustellen, der vom Formular C verwendet wird.

Wenn zwei Zeichenfolgen in Form C oder Form D identisch sind, sind sie in der anderen Form identisch. Außerdem werden sie bei korrekter Darstellung nicht voneinander und von der ursprünglichen nicht normalisierten Zeichenfolge unterschieden.

Nach der Normalisierung können Zeichenfolgen nicht mehr konsistent in ihre ursprüngliche Darstellung zurückgegeben werden. Wenn z. B. eine Zeichenfolge mit einer Mischung aus zusammengesetzten und zerlegten Zeichendarstellungen in ein normalisiertes Formular konvertiert wird, gibt es keine Möglichkeit, die Normalisierung mit der ursprünglichen gemischten Zeichenfolge aufzuheben. Wenn eine Anwendung daher die ursprüngliche Darstellung der Zeichenfolge benötigt, muss sie diese explizit speichern. Die Konvertierung zwischen den beiden kanonischen Formen ist jedoch umkehrbar. Eine Zeichenfolge in Form C kann in Form D und dann zurück in Formular C konvertiert werden, und das Ergebnis ist mit der ursprünglichen Zeichenfolge in Form C identisch.

Formulare KC und KD ähneln den Formularen C bzw. D, aber diese "Kompatibilitätsformulare" verfügen über zusätzliche Zuordnungen kompatibler Zeichen zur Basisform jedes Zeichens. Solche Zuordnungen können dazu führen, dass kleinere Zeichenvariationen verloren gehen. Sie kombinieren bestimmte Zeichen, die visuell unterschiedlich sind. Sie kombinieren z. B. Zeichen mit voller und halber Breite mit der gleichen semantischen Bedeutung oder unterschiedlichen Formen desselben arabischen Buchstabens oder der Ligatur "fi" (U+FB01) und dem Zeichenpaar "fi" (U+0066 U+0069). Sie kombinieren auch einige Zeichen, die manchmal eine andere semantische Bedeutung haben können, z. B. eine Ziffer, die als hochgestellt, als Tiefgestellt geschrieben oder in einen Kreis eingeschlossen ist. Aufgrund dieses Informationsverlusts sollten Formulare KC und KD im Allgemeinen nicht als kanonische Formen von Zeichenfolgen verwendet werden, aber sie sind für bestimmte Anwendungen nützlich.

Formular KC ist ein zusammengesetztes Formular, und das Formular KD ist ein zerlegtes Formular. Die Anwendung kann zwischen den Formularen KC und KD hin- und herwechseln, aber es gibt keine konsistente Möglichkeit, von Form KC oder KD zurück zur ursprünglichen Zeichenfolge zu wechseln, auch wenn die ursprüngliche Zeichenfolge in Form C oder D vorliegt.

Windows, Microsoft-Anwendungen und die .NET Framework in der Regel Zeichen in Form C mithilfe normaler Eingabemethoden generieren. Für die meisten Zwecke unter Windows ist Formular C das bevorzugte Formular. Beispielsweise werden Zeichen in Form C von der Windows-Tastatureingabe erzeugt. Aus dem Web und anderen Plattformen importierte Zeichen können jedoch andere Normalisierungsformen in den Datenstrom einführen.

Die folgenden Beispiele stammen aus UAX #15 und veranschaulichen die Unterschiede zwischen den vier Normalisierungsformen.

Ursprünglich Formular D Formular C Hinweise
"Äffin" "A\u0308ffin" "Äffin" Die ffi_ligature (U+FB03) ist nicht zerlegt, da sie über eine Kompatibilitätszuordnung und keine kanonische Zuordnung verfügt.${REMOVE}$
"Ä\uFB03n" "A\u0308\uFB03n" "Ä\uFB03n"
"Henry IV" "Henry IV" "Henry IV" Die RÖMISCHE ZAHL IV (U+2163) ist nicht zerlegt.${REMOVE}$
"Henry \u2163" "Henry \u2163" "Henry \u2163"
ga ka +ten ga Unterschiedliche Kompatibilitätsäquivalente eines einzelnen japanischen Zeichens führen nicht zu derselben Zeichenfolge im Format C.${REMOVE}$
ka +ten ka +ten ga
hw_ka +hw_ten hw_ka +hw_ten hw_ka +hw_ten
ka +hw_ten ka +hw_ten ka +hw_ten
hw_ka +zehn hw_ka +zehn hw_ka +zehn
kaks k i + a m + ks f kaks Hangul-Silben werden unter Normalisierung beibehalten.

 

Ursprünglich Formular KD Formular KC Hinweise
"Äffin" "A\u0308ffin" "Äffin" Die ffi_ligature (U+FB03) wird in Form KC, aber nicht in form C.${REMOVE}$ zerlegt.
"Ä\uFB03n" "A\u0308ffin" "Äffin"
"Heinrich IV" "Heinrich IV" "Heinrich IV" Die hier resultierenden Zeichenfolgen sind in der Form KC.${REMOVE}$ identisch.
"Henry \u2163" "Heinrich IV" "Heinrich IV"
ga ka +zehn ga Unterschiedliche Kompatibilitätsäquivalente eines einzelnen japanischen Zeichens führen zu derselben Zeichenfolge in der Form KC.${REMOVE}$
ka +zehn ka +zehn ga
hw_ka +hw_ten ka +zehn ga
ka +hw_ten ka +zehn ga
hw_ka +zehn ka +zehn ga
kaks k i + a m + ks f kaks Hangul-Silben werden unter Normalisierung beibehalten. In früheren Unicode-Versionen hatten Jamo-Zeichen wie ks f Kompatibilitätszuordnungen zu k f + s f. Diese Zuordnungen wurden in Unicode 2.1.9 entfernt, um sicherzustellen, dass Hangul-Silben beibehalten werden.

 

Hinweis

Die beiden obigen Tabellen haben ein Copyright von © 1998-2006 Unicode, Inc. Alle Rechte vorbehalten.

 

Verwenden von zusammengesetzten Formularen für einzelne Glyphen

Viele Zeichenfolgen, die einer einzelnen Glyphe entsprechen, verfügen nicht über zusammengesetzte Formulare. Selbst bei normalisierter Form C kann eine einzelne visuelle Glyphe oder ein logisches Textelement aus mehreren Unicode-Codepunkten bestehen. Zum Beispiel haben mehrere Zeichen, die zum Schreiben litauisch verwendet werden, doppelte diakritische Zeichen, da sie nur zerlegte Formen haben. Ein Beispiel ist klein geschriebenes U mit Macron und Tilde ("ū̃", U+016b U+0303, wobei der erste Codepunkt ein Kleinbuchstaben-U mit Macron und der zweite ein kombinierter akuten Akzent ist).

Beispiel

Ein relevantes Beispiel finden Sie unter NLS: Unicode-Normalisierungsbeispiel.

Verwenden der Unterstützung für nationale Sprachen

Sicherheitsüberlegungen: Internationale Features

IsNormalizedString

NormalizeString