+5

Trabalhando com Unicode

criado por Rubens Takiguti Ribeiro em 02/12/2009 9:28pm
Codificação UTF-8

Finalmente chegamos à codificação UTF-8. Esta codificação utiliza um número variável de bytes para representar símbolos. Dependendo do símbolo, ele pode gastar 1, 2, 3 ou 4 bytes.

Os símbolos com 1 byte são idênticos aos da tabela ASCII. Isso possibilita compatibilidade entre as duas codificações. Em outras palavras, os símbolos cujos códigos estão entre 0 e 127 são representados da mesma forma que os símbolos ASCII. Logo, se um byte é capturado e ele começa com zero, então o byte representa um símbolo da tabela ASCII.

Os símbolos com 2 bytes, são aqueles que possuem o formato de bits assim:
110xxxxx 10xxxxxx

Onde estão os "x" ficam os bits que, em sequência, representariam um número binário que na notação inteira indicaria o código do caractere.

Bom, então o código Unicode 128 (que é posterior ao 127) é representado por dois bytes da seguinte forma:
11000010 10000000
   ^^^^^   ^^^^^^
   00010   000000

pegando os bits das posicoes x temos: 00010000000

Note que se pegarmos os bits onde estavam os "x" e colocarmos em sequência, teremos a sequência binária "00010000000", que na notação decimal representa 128.

O símbolo "ç", cujo código é 231 (em binário é "11100111") seria representado da seguinte forma:
11000011 10100111
   ^^^^^   ^^^^^^
   00011   100111

pegando os bits das posicoes x temos: 00011100111

Você já deve ter passado por problemas de codificação. Se fizermos o seguinte código PHP e salvarmos o arquivo como UTF-8, teremos um problema:
<?php
header('Content-type: text/html; charset=ISO-8859-1');
echo 'ç';
?>

O código acima irá enviar um arquivo com dois bytes (aqueles mostrados anteriormente para representar o "ç"), só que o cabeçalho HTTP enviado ao navegador diz que o conteúdo está codificado em ISO-8859-1. Com isso, o navegador pegará o código binário "11000011" e exibirá o símbolo correspondente, depois pegará o código binário "10100111" e exibirá o símbolo correspondente.

Seria exibido "ç".

Isso acontece pois o código binário "11000011" vale 195 (decimal) e, na tabela ISO-8859-1, representa o símbolo "Ã".
Já o código binário "10100111" vale 167 (decimal) e, na tabela ISO-8859-1, representa o símbolo §. Logo, o símbolo "ç" possui o mesmo código em ISO-8859-1 e em Unicode, mas a codificação UTF-8 "monta" os bits de uma forma diferente da codificação ISO-8859-1.

Para os símbolos que precisam de 3 bytes, é utilizada a máscara de bits:
1110xxxx 10xxxxxx 10xxxxxx
(16 bits efetivos)

E para os símbolos que precisam de 4 bytes, é utilizada a máscara de bits:
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
(21 bits efetivos)

Observe que estas máscaras possuem uma lógica. Os símbolos de 1 byte sempre começam com o bit 0.
Os símbolos de 2 bytes, sempre começam com os bits 110xxxxx.
Os símbolos de 3 bytes, sempre começam com os bits 1110xxxx.
Os símbolos de 4 bytes, sempre começam com os bits 11110xxx.

E para os símbolos de 2 a 4 bytes, os bytes posteriores ao primeiro sempre começam com "10xxxxxx".

Como UTF-8 usa 1 ou 2 bytes para caracteres latinos, o tamanho dos textos gerados em UTF-8 costuma ser muito menor que um texto UTF-32.

Já a codificação UTF-16 usa 2 ou 4 bytes. Existe uma conta própria que se conseguir determinar se o símbolo precisará de 2 ou 4 bytes. Como é uma codificação menos comum, não é muito valioso conhecer os detalhes de como ela funciona.

Comentários:

Mostrando 1 - 6 de 6 comentários
PazNatan disse:
ficou legalzinho
03/05/2010 1:01pm (~10 anos atrás)

Nelson disse:
Artigo explicado de forma bem "entendível", gostei muito.
Sugiro um deste tipo falando de array, seria legal.
17/03/2010 1:30pm (~10 anos atrás)

Ótimo artigo!!!
Você explicou muito bem desde a base até ao topo, fazendo-o ficar fácil de compreender!!!
Parabéns!!!
13/03/2010 7:13pm (~10 anos atrás)

Daniel Silva disse:
Uau! Magnífico o artigo! Muito elucidativo! Meus parabéns!
06/01/2010 1:10am (~10 anos atrás)

Marcos Regis disse:
Ótimo artigo. Parabéns.
05/12/2009 4:13pm (~11 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)