Saltar para o conteúdo

UTF-16

Origem: Wikipédia, a enciclopédia livre.
Série Unicode
Unicode
UCS
UTF-7
UTF-8
UTF-16
UTF-32/UCS-4
SCSU
Punycode

Em computação, UTF-16 é um "Formato de Transformação Unicode" de 16-bits. Um formato de transformação Unicode é uma codificação de caracteres que provê uma maneira de representar os diversos caracteres abstratos, presentes no Unicode e no ISO/IEC 10646, como uma série de palavras (neste caso, de 16-bits), para então poder ser armazenados ou transmitidos por uma rede. A codificação UTF-16 é oficialmente definida no Anexo Q do padrão ISO/IEC 10646-1. É também descrita em "The Unicode Standard", versões 3.0 e superiores, bem como no RFC 2781.

O espaço de código Unicode é dividido em dezessete planos de 216 (65.536) pontos de código cada. Apesar de alguns pontos de código ainda não terem sido designados com valores de caractere, alguns são reservados para uso privado e alguns são reservados permanentemente como não-caracteres. Os pontos de código em cada plano possuem valores hexadecimais xx0000 a xxFFFF, onde xx é um valor hexadecimal de 00 a 10, que significa o plano ao qual os valores pertencem.

Pontos de código de U+0000 a U+D7FF e de U+E000 a U+FFFF

[editar | editar código-fonte]

O primeiro plano (pontos de código de U+0000 a U+FFFF) contem os caracteres usados com maior frequência e é chamado de Plano Multilingue Básico (PMB), do inglês Basic Multilingual Plane - BMP. Tanto o UTF-16 quanto o UCS-2 codificam pontos de código neste intervalo como unidades de código de 16 bits simples que são numericamente iguais aos pontos de código correspondentes. Os pontos de código no PMB são os únicos pontos de código que podem ser representados em UCS-2. Dentro deste plano, os pontos de código de U+D800 a U+DFFF (ver abaixo) são reservados para substitutos posteriores e anteriores.

Pontos de código de U+010000 a U+10FFFF

[editar | editar código-fonte]

Pontos de código de outros planos (chamados de Planos Suplementares) são codificados em UTF-16 por pares de unidades de código de 16 bits chamadas de pares substitutos, pelo seguinte esquema:

  • 0x010000 é subtraído do ponto de código, deixando um número de 20 bits no intervalo 0..0x0FFFFF.
  • Os dez bits mais altos (um número no intervalo 0..0x03FF) são adicionados a 0xD800 para dar a primeira unidade de código ou substituto posterior, o qual estará no intervalo 0xD800..0xDBFF. (As versões anteriores do Padrão Unicode referiam-se a esses substitutos como substitutos altos.)
  • Os dez bits mais baixos (também no intervalo 0..0x03FF) são adicionados a 0xDC00 para dar a segunda unidade de código ou substituto anterior, que estará no intervalo 0xDC00..0xDFFF. (As versões anteriores do Padrão Unicode referiam-se a esses como substitutos baixos.)

Pontos de código U+D800 a U+DFFF

[editar | editar código-fonte]

O padrão Unicode reserva permanentemente estes valores de ponto de código para codificação UTF-16 dos substitutos anteriores e posteriores, e eles nunca serão designados com um caractere, desta forma não há razão de codificá-los. O padrão Unicode oficial diz que nenhuma das formas UTF, incluindo o UTF-16, pode codificar estes pontos de código.

Entretanto UCS-2, UTF-8 e UTF-32 pode codificar estes pontos de código de maneiras triviais e óbvias, e grandes quantidades de software fazem isso mesmo que o padrão afirme que tais disposições devam ser tratadas como erros de codificação. É possível codifica-los de forma não ambígua em UTF-16 usando uma unidade de código igual ao ponto de código, enquanto nenhuma sequência de duas unidades de código possa ser interpretada como um par substituto legal (isto é, enquanto um substituto posterior nunca seja seguido por um substituto anterior). A maioria das implementações de codificadores e decodificadores UTF-16 traduzem entre codificações como se este fosse o caso.

Exemplos em UTF-16

[editar | editar código-fonte]

Para os caracteres que tenham recebido um identificador entre 0 e 65535 nas listas Unicode ou ISO/IEC 10646, a codificação UTF-16 representa-os simplesmente como um número idêntico ao seu código. Por exemplo, o código UTF-16 do carácter identificado por 0 é 0. O código UTF-16 do carácter identificado pelo número hexadecimal FFFD é FFFD.

No caso dos valores maiores que 65535 (número hexadecimal FFFF), o UTF-16 representa-os como um par de códigos, cada um deles valendo desde D800 até DFFF (isto é possível porque não existe nenhum carácter atribuído a esta série de números, que são menores que FFFF). O primeiro carácter a representar, maior que FFFF é o 10000. Para este é atribuído o código D800 DC00. Para o carácter 10001, o código é D800 DC01. O último carácter Unicode definido, que é o 10FFFD, vira o valor DBFF DFFD. O algoritmo que retorna corretamente o código UTF-16 de um dado "carácter alto" é o seguinte:

Hipótese: ultimo carácter ISO/IEC 10646 Z = 10FFFD
Seja U: carácter ISO/IEC 10646 que queremos passar para UTF-16 (U tem 21 bits)

U' := U - 0x10000 (U' tem 20 bits)
uh := dez bits altos de U' (uh tem 10 bits)
ul := dez bits baixos de U' (ul tem 10 bits)

vh := uh estendido para 16 bits (colocados zeros à esquerda)
vl := ul estendido para 16 bits (colocados zeros à esquerda)
utf16,1 := 0xD800 | vh
utf16,2 := 0xDC00 | vl

Após a execução do algoritmo, o código UTF-16 é composto de utf16,1 e utf16,2.

Dado o código UTF-16 (seja com 16, seja com 32 bits), este há de ser "serializado", isto é, seus bits colocados em alguma ordem bem definida. Devido às diferenças de arquitetura de computadores, especificam-se três formas de serialização: UTF-16, UTF-16LE e UTF-16BE.

O esquema UTF-16 de serialização requer que a ordem de bytes seja declarada com um comando Byte Order Mark antes do primeiro carácter serializado. O comando BOM é representado pela codificação UTF-16 do carácter "Zero-Width No-Break Space", que tem o código FEFF, no começo da mensagem. Numa máquina little-endian, este código é serializado como FF FE (isto é o primeiro byte a ser armazenado ou transmitido é o FF, após este, FE), enquanto numa máquina big-endian, como FE FF. Um BOM no início de um texto UTF-16, encontrado por um desserializador UTF-16 é tratado como um comando e não é incluído como parte da mensagem.

Os esquemas UTF-16LE e UTF-16BE, em vez de utilizarem um comando, simplesmente assumem implicitamente uma das formas de operação. Este serializa em big-endian e aquele, em little-endian. Se existisse uma mensagem com um código BOM no começo, o código, portanto, faria parte da própria mensagem.

A IANA aprovou as codificações UTF-16, UTF-16BE e UTF-16LE para uso na Internet, com exatamente estes nomes (sem diferenciar maiúsculas ou minúsculas). As variações UTF_16 ou UTF16 podem significar o mesmo em certas linguagens de programação ou certos programas, mas não são considerados padrões.

Hoje em dia, UTF-16 é a representação nativa de texto no Microsoft Windows e na Linguagem de programação Java.

identificador do carácter carácter código UTF-16 exemplo de glifo*
122 (hexa 7A) Z minúsculo (latino) 007A z
946 (hexa 3B2) Beta minúsculo (grego) 03B2 β
27700 (hexa 6C34) água (chinês) 6C34
119070 (hexa 1D11E) clave de sol D834 DD1E 𝄞

* Pode ser necessário que você configure seus programas e instale fontes para ver corretamente os glifos

Exemplos de serializações nos três esquemas UTF-16

[editar | editar código-fonte]
Serializações
mensagem Unicode UTF-16 (l) UTF-16 (b) UTF-16LE UTF-16BE
z β 水 00007A 0003B2 006C34 FF FE 7A 00 B2 03 34 6C FE FF 00 7A 03 B2 6C 34 7A 00 B2 03 34 6C 00 7A 03 B2 6C 34
z 𝄞 00007A 01D11E FF FE 7A 00 34 D8 1E DD FE FF 00 7A D8 34 DD 1E 7A 00 34 D8 1E DD 00 7A D8 34 DD 1E

Exemplo de algoritmo corrido para codificação de "caracteres altos"

[editar | editar código-fonte]

Queremos codificar em UTF-16 o carácter 0x64321. Como este é maior que 0xFFFF, deve ser codificado por um par:

 U = 0x64321
 U' = U - 0x10000
    = 0x54321
    = 0101 0100 0011 0010 0001

 uh = 0101010000 // 10 bits altos
 ul = 1100100001 // 10 bits baixos

 vh = 000000 0101010000 = 0000 0001 0101 0000 // 16 bits
 vl = 000000 1100100001 = 0000 0011 0010 0001 // 16 bits

 utf16,1 = 1101 1000 0000 0000 | 0000 0001 0101 0000
         = 1101 1001 0101 0000 
         = 0xD950
 utf16,2 = 1101 1100 0000 0000 | 0000 0011 0010 0001
         = 1101 1111 0010 0001
         = 0xDF21

Resultado da codificação: o carácter Unicode 0x64321 é codificado em UTF-16 como 0xD950 0xDF21