Uso della normalizzazione Unicode per rappresentare le stringhe

Le applicazioni possono usare Unicode per rappresentare stringhe in più moduli. Man mano che l'accettazione Unicode è cresciuta, soprattutto tramite Internet, è necessario eliminare le differenze non essenziali nelle stringhe Unicode. Più rappresentazioni per una combinazione di caratteri complicano il software, ad esempio quando un server Web risponde a una richiesta di pagina o un linker cerca un identificatore specifico in una libreria.

Attenzione

Le stringhe Unicode diverse possono sembrare identiche visivamente, generando problemi di sicurezza. Per altre informazioni, vedere Considerazioni sulla sicurezza: Funzionalità internazionali.

 

In risposta a questo requisito, Il Consorzio Unicode ha definito un processo denominato "normalizzazione", che produce una rappresentazione binaria per una delle rappresentazioni binarie equivalenti di un carattere. Una volta normalizzate, due stringhe sono equivalenti se e solo se hanno rappresentazioni binarie identiche. La normalizzazione elimina alcune differenze, ma mantiene la distinzione tra maiuscole e minuscole.

Per usare la normalizzazione Unicode, un'applicazione può chiamare le funzioni NormalizeString e IsNormalizedString per riorganizzare le stringhe acccording a Unicode 4.0 TR#15. La normalizzazione può contribuire a migliorare la sicurezza riducendo le rappresentazioni di stringa alternative con lo stesso significato linguistico. Tenere presente, tuttavia, che la normalizzazione non può eliminare completamente rappresentazioni alternative.

Per una descrizione dettagliata degli standard Unicode per la normalizzazione, vedere Unicode Standard Annex #15: Unicode Normalization Forms (UAX #15).

Attenzione

Poiché la normalizzazione può modificare la forma di una stringa, i meccanismi di sicurezza o gli algoritmi di convalida dei caratteri devono in genere essere implementati dopo la normalizzazione. Per altre informazioni, vedere Considerazioni sulla sicurezza: Funzionalità internazionali.

 

Specificare più rappresentazioni della stessa stringa

In molti casi, Unicode consente più rappresentazioni di ciò che è, in modo linguistico, la stessa stringa. Ad esempio:

  • La maiuscola A con dieresi (umlaut) può essere rappresentata come un singolo punto di codice Unicode "Ä" (U+00C4) o la combinazione di maiuscole e minuscole (carattere di dieresi) ("A" + " ̈", ovvero U+0041 U+0308). Considerazioni simili si applicano a molti altri caratteri con segni diacritici.
  • La maiuscola A stessa può essere rappresentata nel modo consueto (lettera maiuscola latina A, U+0041) o da Fullwidth Alfabeto Latino Lettera A (U+FF21). Si applicano considerazioni simili per le altre lettere latine semplici (maiuscole e minuscole) e per i caratteri katakana usati per scrivere il giapponese.
  • La stringa "fi" può essere rappresentata dai caratteri "f" e "i" (U+0066 U+0069) o dalla legatura "fi" (U+FB01). Considerazioni simili si applicano a molte altre combinazioni di caratteri per cui Unicode definisce le legature.

Usare i quattro moduli di normalizzazione definiti

Le applicazioni possono eseguire la normalizzazione Unicode usando diversi algoritmi, denominati "moduli di normalizzazione", che rispettano regole diverse. Il Consorzio Unicode ha definito quattro forme di normalizzazione: NFC (modulo C), NFD (modulo D), NFKC (modulo KC) e NFKD (modulo KD). Ogni modulo elimina alcune differenze, ma mantiene la distinzione tra maiuscole e minuscole. Win32 e .NET Framework supportano tutti e quattro i moduli di normalizzazione.

Il tipo di enumerazione NLS NORM_FORM supporta i quattro moduli di normalizzazione Unicode standard. I moduli C e D forniscono forme canoniche per le stringhe. Le forme non canoniche KC e KD offrono ulteriore compatibilità e possono rivelare determinate equivalenze semantiche che non sono evidenti nelle forme C e D. Tuttavia, lo fanno a scapito di una certa perdita di informazioni e in genere non devono essere usati come modo canonico per archiviare le stringhe.

Tra le due forme canoniche, il formato C è una forma "composta" e il formato D è un modulo "scomposto". Ad esempio, il formato C usa il singolo punto di codice Unicode "Ä" (U+00C4), mentre il modulo D usa ("A" + " ̈", ovvero U+0041 U+0308). Il rendering è identico, perché " ̈" (U+0308) è un carattere combinato. Il modulo D può usare qualsiasi numero di punti di codice per rappresentare un singolo punto di codice usato dal modulo C.

Se due stringhe sono identiche in formato C o D, sono identiche nell'altro formato. Inoltre, quando viene eseguito correttamente il rendering, vengono visualizzati indistinguabilmente l'uno dall'altro e dalla stringa originale non normalizzata.

Una volta normalizzate, le stringhe non possono essere restituite in modo coerente alla relativa rappresentazione originale. Ad esempio, se una stringa con una combinazione di rappresentazioni di caratteri composte e scomposte viene convertita in una forma normalizzata, non è possibile normalizzarla nella stringa mista originale. Pertanto, se un'applicazione richiede la rappresentazione originale della stringa, deve archiviare tale rappresentazione in modo esplicito. Tuttavia, la conversione tra le due forme canoniche è reversibile. Una stringa nel formato C può essere convertita in formato D e quindi nuovamente nel formato C e il risultato è identico alla stringa C originale.

I moduli KC e KD sono simili ai formati C e D, ma questi "moduli di compatibilità" hanno mapping aggiuntivi di caratteri compatibili alla forma di base di ogni carattere. Tali mapping possono causare la perdita di variazioni di caratteri minori. Combinano determinati caratteri visivamente distinti. Ad esempio, combinano caratteri a larghezza intera e a metà larghezza con lo stesso significato semantico o forme diverse della stessa lettera araba oppure la legatura "fi" (U+FB01) e la coppia di caratteri "fi" (U+0066 U+0069). Combinano anche alcuni caratteri che a volte hanno un significato semantico diverso, ad esempio una cifra scritta come apice, come pedice o racchiusa in un cerchio. A causa di questa perdita di informazioni, i moduli KC e KD in genere non devono essere usati come forme canoniche di stringhe, ma sono utili per determinate applicazioni.

Il modulo KC è un modulo composto e il formato KD è un modulo scomposto. L'applicazione può tornare avanti e indietro tra i moduli KC e KD, ma non esiste un modo coerente per passare dal formato KC o KD alla stringa originale, anche se la stringa originale è in formato C o D.

Windows, le applicazioni Microsoft e .NET Framework in genere generano caratteri nel formato C usando metodi di input normali. Per la maggior parte dei casi in Windows, il formato C è il formato preferito. Ad esempio, i caratteri nel formato C vengono prodotti dall'input della tastiera di Windows. Tuttavia, i caratteri importati dal Web e da altre piattaforme possono introdurre altri moduli di normalizzazione nel flusso di dati.

Gli esempi seguenti sono tratti da UAX #15 e illustrano le differenze tra le quattro forme di normalizzazione.

Originale Modulo D Modulo C Note
"Äffin" "A\u0308ffin" "Äffin" Il ffi_ligature (U+FB03) non è scomposto perché ha un mapping di compatibilità, non un mapping canonico.${REMOVE}$
"Ä\uFB03n" "A\u0308\uFB03n" "Ä\uFB03n"
"Henry IV" "Henry IV" "Henry IV" IL NUMERO ROMANO IV (U+2163) non è scomposto.${REMOVE}$
"Henry \u2163" "Henry \u2163" "Henry \u2163"
ga ka +dieci ga Gli equivalenti di compatibilità diversi di un singolo carattere giapponese non generano la stessa stringa nel formato C.${REMOVE}$
ka +dieci ka +dieci ga
hw_ka +hw_ten hw_ka +hw_ten hw_ka +hw_ten
ka +hw_ten ka +hw_ten ka +hw_ten
hw_ka +dieci hw_ka +dieci hw_ka +dieci
kaks k i + a m + ks f kaks Le sillabe hangul vengono mantenute in fase di normalizzazione.

 

Originale Modulo KD Modulo KC Note
"Äffin" "A\u0308ffin" "Äffin" Il ffi_ligature (U+FB03) è decomposto in formato KC, ma non in formato C.${REMOVE}$
"Ä\uFB03n" "A\u0308ffin" "Äffin"
"Henry IV" "Henry IV" "Henry IV" Le stringhe risultanti sono identiche nel formato KC.${REMOVE}$
"Henry \u2163" "Henry IV" "Henry IV"
ga ka +dieci ga Equivalenti di compatibilità diversi di un singolo carattere giapponese generano la stessa stringa nel formato KC.${REMOVE}$
ka +dieci ka +dieci ga
hw_ka +hw_ten ka +dieci ga
ka +hw_ten ka +dieci ga
hw_ka +dieci ka +dieci ga
kaks k i + a m + ks f kaks Le syllable hangul vengono mantenute sotto la normalizzazione. Nelle versioni unicode precedenti, i caratteri jamo come ks f avevano mapping di compatibilità a k f + s f. Questi mapping sono stati rimossi in Unicode 2.1.9 per garantire che le syllable Hangul siano mantenute.

 

Nota

Le due tabelle precedenti hanno un copyright del © 1998-2006 Unicode, Inc. Tutti i diritti riservati.

 

Usare moduli composti per i singoli glifi

Molte sequenze di caratteri che corrispondono a un singolo glifo non hanno forme composte. Anche se normalizzato dal formato C, un singolo glifo visivo o un elemento di testo logico può essere composto da più punti di codice Unicode. Ad esempio, diversi caratteri usati nella scrittura in lituano hanno doppia diacritica, perché hanno solo forme decomposte. Un esempio è U minuscolo con macron e tilde ("ū̃", U+016b U+0303, dove il primo punto di codice è un punto minuscolo U con macron e il secondo è una combinazione di accento acuto).

Esempio

Un esempio pertinente è disponibile in NLS: Esempio di normalizzazione Unicode.

Uso del supporto per la lingua nazionale

Considerazioni sulla sicurezza: funzionalità internazionali

IsNormalizedString

NormalString