Developer 101: Codificação de caracteres
De tempos em tempos gosto de fazer uma “revisão geral” sobre conceitos que considero fundamentais para todo desenvolvedor de software. É natural que algumas coisas que estudamos acabem caindo no “limbo da memória” pela falta de uso, mas é sempre bom dar uma atualizada nesses conceitos, pois nunca se sabe quando eles serão necessário.
Resolvi, então, iniciar a série “Developer 101″ onde, à medida que faço minhas revisões, vou publicar um pouco sobre o assunto e listar links para mais recursos.
No primeiro artigo da série, falarei um pouco sobre algo fundamental e, geralmente, negligenciado por escolas e profissionais: a codificação de caracteres. Não é algo muito fácil de entender e muito dessa dificuldade deve-se às confusões e ambigüidades criadas pelas próprias empresas e entidades de padronização.
Em resumo, a codificação de caracteres define como caracteres (grafemas e símbolos utilizados em alfabetos e outros símbolos específicos) são representados internamente para armazenamento, processamento ou transmissão.
Para entender a codificação de caracteres, precisamos de três definições básicas:
1. Repertório de caracteres (character repertoire ou character set)
Um repertório de caracteres é um conjunto de caracteres distintos. Um repertório não tem qualquer ligação com dados computacionais.
Exemplo: o alfabeto grego, o conjunto de caracteres que uma criança chinesa aprenderá na terceira série, etc.
2. Conjunto codificado de caracteres (coded character set)
Um mapeamento um a um entre um caractere de um repertório e um código único. Esse código possui diversas nomenclaturas, como code point, code position ou code value, mas todos se referem à mesma coisa.
Exemplo de conjuntos: Braile, Unicode, I Ching.
Exemplo de mapeamento: o code point U+0041 representa a letra A no conjunto Unicode.
3. Codificação de caracteres (character encoding)
Um método (algoritmo) para apresentar caracteres em formato digital, mapeando códigos de caracteres para bytes. Existem diversos tipos de codificações. Algumas fixam o número de bytes de cada caractere, outros permitem caracteres multibytes variáveis.
Exemplos: ASCII (um byte por caractere), UTF-8 (multibyte variável).
A ambigüidade
O nome character set (conjunto de caracteres) é usado para se referir a repertórios, conjuntos codificados ou codificações. Charset também é bastante utilizado para se referir à codificação. Esse tipo de confusão torna o assunto bastante complexo, por isso é necessário entender bem os conceitos descritos mais acima.
Juntando as partes
Suponha que queremos representar todos os caracteres do alfabeto latino mais todos os símbolos especiais e diacríticos utilizados na língua portuguesa. Esse é o nosso repertório de caracteres.
Para isso, criamos uma grande tabela com todos esses caracteres e, a cada um, atribuímos um código único. Temos agora um conjunto codificado de caracteres.
Em seguida vamos buscar uma forma eficiente de representar esses caracteres em um meio digital. O que vamos representar, na verdade, é o código de cada caractere.
Supondo que temos 1000 códigos, estabelecemos que cada código poderá ocupar até dois bytes de espaço, o que nos habilita a representar até 65536 códigos (2 bytes é igual a 16 bits, 2^16 é igual a 65536). Tomamos essa decisão pois com 1 byte conseguiríamos representar até 256 códigos. Além disso, é sempre uma medida de bom senso deixar “espaços livres” para caracteres especiais (para representar uma quebra de linha, por exemplo) e possíveis necessidades de compatibilidade. Temos, então, nossa própria codificação.
É importante notar que a idéia de caractere é diferente de sua representação. Por exemplo, o conceito da letra “A” é diferente do fonema em português ou da sequência de bytes no UTF-8.
Além disso, cada representação utiliza uma codificação diferente: no exemplo anterior, sons e bytes, respectivamente. Ou seja, uma codificação é uma maneira de representar um conceito.
É por esses motivos que a codificação de caracteres é tão importante: experimente salvar um arquivo em uma codificação (UTF-8, por exemplo) e tentar ler o mesmo arquivo utilizando outra codificação (ASCII, por exemplo). Grande parte, senão todo o conteúdo, será perdido.
Exemplos
Veja, na tabela abaixo, como fica a codificação (representação em bytes) dos caracteres A, א e 好 do conjunto codificado Unicode, nas codificações UTF-8, UTF-16 e UTF-32:
| A | א | 好 | |
|---|---|---|---|
| Code point | U+0041 | U+05D0 | U+597D |
| UTF-8 | 41 | D7 90 | E5 A5 BD |
| UTF-16 | 00 41 | 05 D0 | 59 7D |
| UTF-32 | 00 00 00 41 | 00 00 05 D0 | 00 00 59 7D |
Recomendações para desenvolvimento
Desde o início do projeto, utilize sempre o conjunto Unicode e, de preferência, a codificação (encoding) UTF-8.
Isso abrange o conjunto codificado e a codificação utilizados para salvar cada arquivo com texto (código-fonte, xml, arquivos para internacionalização etc), cabeçalhos HTTP e meta tags content-type em aplicações web, servidores web, armazenamento em banco de dados e conexões com o mesmo.
Lembre-se: isso não é uma verdade universal. Utilizar Unicode e UTF-8 cobre a maioria dos casos, mas não todos.
Finalizando
Desde o início, preste atenção na codificação que você está utilizando ao desenvolver software, pois isso pode poupar muito tempo, evitando sérios problemas.
De forma alguma esse artigo é algo completo, é apenas o que consegui rever com algumas horas de leitura, exposto de forma simples. Aprofunde-se e, se encontrar algum erro ou inconsistência no que escrevi, por favor, me avise.
Veja também
- The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
- Do you know your character encodings?
- Tutorial: Character sets & encodings in XHTML, HTML and CSS (W3C)
- Unicode and You
Comments
2 Responses to “Developer 101: Codificação de caracteres”
Leave a Reply
Bom post.
[...] Depois de um bom tempo, mais um artigo da série “Developer 101″. Dessa vez decidi falar sobre vários assuntos de uma forma sucinta com o objetivo de instigar a curiosidade do leitor. [...]