Share via


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

Os aplicativos podem usar Unicode para representar cadeias de caracteres em várias formas. À medida que a aceitação unicode cresceu, especialmente por meio 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 busca um identificador específico em uma biblioteca.

Cuidado

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

 

Em resposta a esse 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. Depois de normalizadas, duas cadeias de caracteres serão equivalentes se e somente se tiverem representações binárias idênticas. A normalização elimina algumas diferenças, mas preserva os casos.

Para usar a normalização Unicode, um aplicativo pode chamar as funções NormalizeString e IsNormalizedString para reorganização de cadeias de caracteres que estão de acordo com o 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, de 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 Anexo Padrão Unicode nº 15: Unicode Normalization Forms (UAX #15).

Cuidado

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: recursos 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:

  • O 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 caracteres com marcas diacríticas.
  • O capital A em si pode ser representado da maneira usual (Letra Latina maiúscula A, U+0041) ou pela Letra Maiúscula Latina A (U+FF21). Considerações semelhantes se aplicam às outras letras latinas simples (maiúsculas e minúsculas) e aos caracteres katakana usados na escrita em japonês.
  • A cadeia de caracteres "fi" pode ser representada pelos caracteres "f" e "i" (U+0066 U+0069) ou pela ligatura "fi" (U+FB01). Considerações semelhantes se aplicam a muitas outras combinações de caracteres para as quais Unicode define ligaturas.

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

Seus aplicativos podem executar a normalização Unicode usando vários algoritmos, chamados de "formulários de normalização", que obedecem a regras diferentes. O Unicode Consortium definiu quatro formulários 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 maiúsculas e minúsculas. O Win32 e o .NET Framework dão suporte a todos os quatro formulários de normalização.

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

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). Eles são renderizados de forma idêntica, porque " ̈" (U+0308) é um caractere de combinação. 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 forem idênticas na forma C ou na forma D, elas serão idênticas na outra forma. Além disso, quando renderizados corretamente, eles são exibidos indistinguishably um do outro e da cadeia de caracteres original não normalizada.

Depois de normalizadas, as cadeias de caracteres não podem ser retornadas consistentemente à representação original. Por exemplo, se uma cadeia de caracteres com uma mistura de representações de caracteres compostas e decompostas for convertida em uma forma normalizada, não haverá como des normalizá-la para a cadeia de caracteres mista original. Portanto, se um aplicativo exigir a representação original da cadeia de caracteres, ele deverá armazenar essa representação explicitamente. No entanto, a conversão entre as duas formas canônicas é reversível. Uma cadeia de caracteres no formato C pode ser convertida no formulário D e, em seguida, voltar para a forma C, e o resultado é idêntico à cadeia de caracteres C do formulário original.

Os formulários KC e KD são semelhantes aos formulários C e D, respectivamente, mas esses "formulários de compatibilidade" têm mapeamentos adicionais de caracteres compatíveis para a forma básica de cada caractere. Esses mapeamentos podem fazer com que pequenas variações de caracteres sejam perdidas. Eles combinam determinados caracteres que são visualmente distintos. Por exemplo, eles combinam caracteres de largura total e meia largura com o mesmo significado semântico, ou formas diferentes da mesma letra árabe, ou a ligatura "fi" (U+FB01) e o par de caracteres "fi" (U+0066 U+0069). Eles também combinam alguns caracteres que às vezes podem ter um significado semântico diferente, como um dígito escrito como um sobrescrito, como um subscrito ou colocado em 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 cadeias de caracteres, mas são úteis para determinados aplicativos.

O Formulário KC é uma forma composta e o formulário KD é uma forma decomposta. O aplicativo pode ir e voltar entre as formas 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 no formato C ou D.

Aplicativos Windows, Microsoft e .NET Framework geralmente geram caracteres no formulário C usando métodos de entrada normais. Para a maioria das finalidades no Windows, o formulário C é o formulário preferencial. Por exemplo, os caracteres no formato C são produzidos pela entrada de teclado do Windows. No entanto, os 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 os quatro formulários de normalização.

Original Formulário D Formulário C Observações
"Äffin" "A\u0308ffin" "Äffin" O ffi_ligature (U+FB03) não está decomposto, pois tem um mapeamento de compatibilidade, não um mapeamento canônico.${REMOVE}$
"Ä\uFB03n" "A\u0308\uFB03n" "Ä\uFB03n"
"Henrique IV" "Henrique IV" "Henrique IV" O ROMAN NUMERAL IV (U+2163) não está decomposto.${REMOVE}$
"Henry \u2163" "Henry \u2163" "Henry \u2163"
ga ka +ten ga Diferentes equivalentes de compatibilidade de um único caractere japonês não resultam na mesma cadeia de caracteres no formato 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 +dez hw_ka +dez hw_ka +dez
kaks k i + a m + ks f kaks As sílabas hangul são mantidas sob normalização.

 

Original Formulário KD Formulário KC Observações
"Äffin" "A\u0308ffin" "Äffin" O ffi_ligature (U+FB03) é decomposto no formato KC, mas não no formato C.${REMOVE}$
"Ä\uFB03n" "A\u0308ffin" "Äffin"
"Henrique IV" "Henrique IV" "Henrique IV" As cadeias de caracteres resultantes aqui são idênticas no formato KC.${REMOVE}$
"Henry \u2163" "Henrique IV" "Henrique IV"
ga ka +ten ga Diferentes equivalentes de compatibilidade de um único caractere japonês resultam na mesma cadeia de caracteres no formato KC.${REMOVE}$
ka +ten ka +ten ga
hw_ka +hw_ten ka +ten ga
ka +hw_ten ka +ten ga
hw_ka +dez ka +ten ga
kaks k i + a m + ks f kaks As sílabas hangul são mantidas sob normalização. Em versões anteriores do Unicode, caracteres de 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 formulários compostos para glifos únicos

Muitas sequências de caracteres que correspondem a um único glifo não têm formulários compostos. Mesmo quando normalizado pelo formulário C, um único elemento de glifo visual ou 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 til ("ū̃", 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 no NLS: Exemplo de normalização Unicode.

Usando o Suporte à Linguagem Nacional

Considerações sobre segurança: recursos internacionais

IsNormalizedString

NormalizeString