Nesse post eu vou falar de um ponto que muitas vezes parece não ser importante pelo motivo de (quase) sempre desenvolvermos aplicações em português e inglês, deixando de lado algumas línguas mais complicadas como grego, hebraico, chinês, japonês, e outras línguas asiáticas.
Inicialmente vamos entender um pouco mais o que exatamente é o encoding, e para que ele serve.
Encodings são códigos (geralmente números) que representam um determinado caractere em uma determinada língua/plataforma. A primeira forma de representação desses caracteres foi o tão conhecido Ascii (American Standard Code for Information Interchange), que representa um caractere em questão em forma de bits, mais precisamente 7 bits (depois completaram os 8 bits). O problema é que o universo de caracteres representados no Ascii era muito pequeno, somente 128 caracteres (por conta do seu tamanho). Não precisa nem dizer que os alfabetos pelo mundo a fora possuem muito mais do que 128 caracteres somente (e a china é o nosso principal representante desse leque). O Ascii foi o primeiro, mas diversos outros encodings surgiram depois disso: ISO 8859-1 , GB 2312, etc.
Também é fácil de concluir que com os diversos encodings que surgiram, muitos caracteres conflitavam os seus códigos com outros encodings. Isso é, dois encodings usando o mesmo código para representar o mesmo caractere. Por conta desses problemas foi criado o Unicode, que NÃO É UM ENCODING, mas padroniza a representação de caracteres dos encodings. Então começaram a surgir os encodings que basearam seus representações de caracteres em códigos sugeridos pelo unicode, e aí entra um dos primeiros encodings famosos unicode, que foi o UCS-2.
UCS-2 (Universal Character Set) utiliza 2 bytes para representar caracteres, e é claro que por conta desse espaço maior de armazenamento foram acrescentadas “muitas e muitas” línguas nesse encoding. Infelizmente “muitas e muitas” é diferente de TODAS. Ou seja, o povo decidiu criar encodings ainda maiores, com 16 e 32 bits (sendo este último não muito utilizado).
O UCS-2 teve um problema, basicamente com sistemas linux-like (que por ser um sistema antigo, se baseava completamente no encoding Ascii). Podemos exemplificar o problema com a linguagem C, que tem a convenção de representar uma string como um array de caracteres (representação ascii) terminando em zero. Exemplo: C vai armazenar a string HELLO como 72 69 76 76 79 0, num mais puro Ascii. Na maior parte dos lugares dentro dos sistemas linux-like vão entender que essa é uma palavra de 5 letras porque ela termina com zero (null). Quando utilizamos o UCS-2, o mesmo HELLO é armazenado em 2 bytes da seguinte forma: 72 0 69 0 76 0 76 0 79 0 0 0. Praticamente todos os lugares vão interpretar isso como uma palavra de uma só letra “H”. Isso não é bom.
Foi aí que surgiram os encodings UTF (Unicode Transformation Format), uma vez que os sitemas linux (baseados em ascii 8 bits, não conseguiam se entender muito bem com os encodings 16 bits como o UCS-2). Esses UTF conseguem fazer os sistemas 8 e 16 bits se entenderem normalmente. O formato UTF mais utilizado é o UTF-8, que utiliza de até 4 bytes para representar um caractere. Como são utilizados esses bytes?
– 1 byte para a representação do caractere Ascii e
– 2 bytes para a representação de caracteres latinos, sírios, hebraicos, gregos, etc. ou 3 bytes para o restante de um plano multilingual que existe.
Com isso nós chegamos até o conceito mais utilizado hoje em termos de encoding, que é o UTF-8, que está se tornando cada vez mais um padrão para páginas, emails, e qualquer outro lugar onde caracteres sejam armazenados.
Muito Bom! Encondings é um tópico pouco entendido pela vasta maioria dos desenvolvedores nacionais (infelizmente). Como leitura adicional, recomendo (em inglês) o artigo de Joel Spolsky: http://www.joelonsoftware.com/articles/Unicode.html
Valeu Décio! Eu cheguei a dar uma lida nesse artigo de joel sim, é muito bom também!