Partilhar via


Usando a normalização Unicode para representar cadeias de caracteres

Os aplicativos podem usar Unicode para representar cadeias de caracteres em vários formulários. À medida que a aceitação do Unicode cresceu, especialmente através da Internet, surgiu a necessidade de eliminar diferenças não essenciais nas cadeias de caracteres Unicode. Várias representações para uma combinação de caracteres complicam o software, por exemplo, quando um servidor Web responde a uma solicitação de página ou um vinculador procura um identificador específico em uma biblioteca.

Atenção

Diferentes cadeias de caracteres Unicode podem parecer visualmente idênticas, levantando preocupações de segurança. Para obter mais informações, consulte Considerações de segurança: recursos internacionais.

 

Em resposta a este requisito, o Unicode Consortium definiu um processo chamado "normalização", que produz uma representação binária para qualquer uma das representações binárias equivalentes de um caractere. Uma vez normalizadas, duas cadeias de caracteres são equivalentes se e somente se tiverem representações binárias idênticas. A normalização elimina algumas diferenças, mas preserva o caso.

Para usar a normalização Unicode, um aplicativo pode chamar o NormalizeString e funções de IsNormalizedString para rearranjo de cadeias de caracteres de acordo com Unicode 4.0 TR#15. A normalização pode ajudar a melhorar a segurança, reduzindo representações de cadeia de caracteres alternativas que têm o mesmo significado linguístico. Lembre-se, no entanto, que a normalização não pode eliminar totalmente as representações alternativas.

Para obter uma descrição detalhada dos padrões Unicode para normalização, consulte Unicode Standard Annex #15: Unicode Normalization Forms (UAX #15).

Atenção

Como a normalização pode alterar a forma de uma cadeia de caracteres, mecanismos de segurança ou algoritmos de validação de caracteres geralmente devem ser implementados após a normalização. Para obter mais informações, consulte Considerações de segurança: funcionalidades internacionais.

 

Fornecer várias representações da mesma cadeia de caracteres

Em muitos casos, o Unicode permite várias representações do que é, linguisticamente, a mesma cadeia de caracteres. Por exemplo:

  • Capital A com dieresis (umlaut) pode ser representado como um único ponto de código Unicode "Ä" (U+00C4) ou a combinação de Capital A e o caractere Dieresis combinado ("A" + " ̈", ou seja, U+0041 U+0308). Considerações semelhantes se aplicam a muitos outros personagens com marcas diacríticas.
  • O próprio Capital A pode ser representado da maneira usual (Letra A maiúscula latina, U+0041) ou pela Letra A maiúscula latina de largura completa (U+FF21). Considerações semelhantes se aplicam para as outras letras latinas simples (maiúsculas e minúsculas) e para os caracteres katakana usados na escrita japonesa.
  • A string "fi" pode ser representada pelos caracteres "f" e "i" (U+0066, U+0069) ou pela ligadura "fi" (U+FB01). Considerações semelhantes se aplicam a muitas outras combinações de caracteres para as quais o Unicode define ligaduras.

Usar os quatro formulários de normalização definidos

Seus aplicativos podem executar a normalização Unicode usando vários algoritmos, chamados "formulários de normalização", que obedecem a regras diferentes. O Unicode Consortium definiu quatro formas de normalização: NFC (formulário C), NFD (formulário D), NFKC (formulário KC) e NFKD (formulário KD). Cada formulário elimina algumas diferenças, mas preserva o caso. O Win32 e o .NET Framework oferecem suporte a todos os quatro formulários de normalização.

O tipo de enumeração NLS NORM_FORM suporta os quatro formulários de normalização Unicode padrão. Os formulários C e D fornecem formas canônicas para cadeias de caracteres. As formas não-canônicas KC e KD fornecem compatibilidade adicional, e podem revelar certas equivalências semânticas que não são aparentes nas formas C e D. No entanto, eles fazem isso às custas de uma certa perda de informação, e geralmente não devem ser usados como uma maneira canônica de armazenar strings.

Das duas formas canônicas, a forma C é uma forma "composta" e a forma D é uma forma "decomposta". Por exemplo, o formulário C usa o único ponto de código Unicode "Ä" (U+00C4), enquanto o formulário D usa ("A" + " ̈", que é U+0041 U+0308). Estes renderizam de forma idêntica, porque " ̈" (U+0308) é um caractere combinado. O formulário D pode usar qualquer número de pontos de código para representar um único ponto de código usado pelo formulário C.

Se duas cadeias de caracteres são idênticas na forma C ou na forma D, elas são idênticas na outra forma. Além disso, quando renderizados corretamente, eles são exibidos indistintamente uns dos outros e da cadeia de caracteres não normalizada original.

Uma vez normalizadas, as cadeias de caracteres não podem ser consistentemente retornadas à sua representação original. Por exemplo, se uma cadeia de caracteres com uma mistura de representações de caracteres compostos e decompostos for convertida em uma forma normalizada, não há como desnormalizá-la para a cadeia de caracteres mista original. Portanto, se um aplicativo requer a representação original da cadeia de caracteres, ele deve armazenar essa representação explicitamente. No entanto, a conversão entre as duas formas canônicas é reversível. Uma cadeia de caracteres na forma C pode ser convertida para a forma D e, em seguida, de volta para a forma C, e o resultado é idêntico à cadeia de caracteres C original.

As formas KC e KD são semelhantes às formas C e D, respectivamente, mas essas "formas de compatibilidade" têm mapeamentos adicionais de caracteres compatíveis com a forma básica de cada caractere. Esses mapeamentos podem fazer com que pequenas variações de caracteres sejam perdidas. Eles combinam certos personagens que são visualmente distintos. Por exemplo, eles combinam caracteres de largura total e meia largura com o mesmo significado semântico, ou diferentes formas da mesma letra árabe, ou a ligadura "fi" (U+FB01) e o par de caracteres "fi" (U+0066 U+0069). Eles também combinam alguns caracteres que, por vezes, podem ter um significado semântico diferente, como um dígito escrito em sobrescrito, subscrito ou circundado por um círculo. Devido a essa perda de informações, os formulários KC e KD geralmente não devem ser usados como formas canônicas de strings, mas são úteis para determinadas aplicações.

A forma KC é uma forma composta e a forma KD é uma forma decomposta. O aplicativo pode ir e voltar entre os formulários KC e KD, mas não há uma maneira consistente de ir do formulário KC ou KD de volta para a cadeia de caracteres original, mesmo que a cadeia de caracteres original esteja na forma C ou D.

Windows, aplicativos da Microsoft e o .NET Framework geralmente geram caracteres no formato C usando métodos de entrada normais. Para a maioria das finalidades no Windows, o formulário C é o formulário preferido. Por exemplo, os caracteres no formato C são produzidos pela entrada de teclado do Windows. No entanto, caracteres importados da Web e de outras plataformas podem introduzir outros formulários de normalização no fluxo de dados.

Os exemplos a seguir são extraídos do UAX #15 e ilustram as diferenças entre as quatro formas de normalização.

Original Formulário D Formulário C Observações
"Äffin" Um(a)\u0308ffin "Äffin" O ffi_ligature (U+FB03) não é decomposto, porque tem um mapeamento de compatibilidade, não um mapeamento canônico.${REMOVE}$
Ä\uFB03n "Um\u0308\uFB03n" Ä\uFB03n
"Henrique IV" "Henrique IV" "Henrique IV" O ALGARISMO ROMANO IV (U+2163) não é decomposto.${REMOVE}$
"Henrique \u2163" "Henrique \u2163" "Henrique \u2163"
GA ka +dez GA Diferentes equivalentes de compatibilidade de um único caractere japonês não resultam na mesma cadeia de caracteres no formato C.${REMOVE}$
ka +dez ka +dez GA
hw_ka +hw_ten hw_ka +hw_ten hw_ka +hw_ten
Ka +hw_ten Ka +hw_ten Ka +hw_ten
hw_ka +dez hw_ka +dez hw_ka +dez
Kaks k i + a m + ks f Kaks As sílabas de Hangul são mantidas durante a normalização.

 

Original Formulário KD Formulário KC Observações
"Äffin" Um\u0308ffin "Äffin" O ffi_ligature (U+FB03) é decomposto na forma KC, mas não na forma C.${REMOVE}$
Ä\uFB03n Uma\u0308ffin "Äffin"
"Henrique IV" "Henrique IV" "Henrique IV" As cadeias de caracteres resultantes aqui são idênticas na forma KC.${REMOVE}$
"Henrique \u2163" "Henrique IV" "Henrique IV"
GA ka +dez GA Diferentes equivalentes de compatibilidade de um único caractere japonês resultam na mesma cadeia de caracteres no formato KC.${REMOVE}$
ka +dez ka +10 GA
hw_ka +hw_ten ka +dez GA
Ka +hw_ten ka +dez GA
hw_ka +dez ka +ten GA
Kaks k i + a m + ks f Kaks As sílabas de Hangul são mantidas durante a normalização. Em versões anteriores do Unicode, caracteres jamo como ks f tinham mapeamentos de compatibilidade para k f + s f. Esses mapeamentos foram removidos no Unicode 2.1.9 para garantir que as sílabas Hangul sejam mantidas.

 

Observação

As duas tabelas acima têm direitos autorais de © 1998-2006 Unicode, Inc. Todos os direitos reservados.

 

Usar formas compostas para glifos únicos

Muitas sequências de caracteres que correspondem a um único glifo não têm formas compostas. Mesmo quando normalizado pelo formulário C, um único glifo visual ou elemento de texto lógico pode ser composto por vários pontos de código Unicode. Por exemplo, vários caracteres usados na escrita lituana têm diacríticos duplos, pois têm apenas formas decompostas. Um exemplo é U minúsculo com macron e tilde ("ū̃", U+016b U+0303, onde o primeiro ponto de código é um U minúsculo com macron e o segundo é um acento agudo combinado).

Exemplo

Um exemplo relevante pode ser encontrado em NLS: Unicode Normalization Sample.

Usando o Suporte de Idiomas Nacionais

Considerações de segurança: Recursos internacionais

IsNormalizedString

NormalizeString