Codificação de Texto

Em um computador, codificação de texto (text encoding) refere ao algoritmo usado para transformar texto que seres humanos conseguem entender (letras, números, pontuações, e outros caracteres) em dados que o computador consegue entender (bits e bytes).

Todo texto em um computador possui uma codificação. Existem várias codificações, cada uma tendo um jeito diferente de representar em bits o valor de um caractere. Por exemplo, na codificação ASCII, o valor da letra "A" maiúscula é 1000001 em binário, que equivale a 65 em decimal. A letra "B" seria 66, a letra "C" 67, e assim por diante. Chamamos cada um desses valores de pontos de código (code points).

Por exemplo, a representação binária do texto "Bom dia!" poderia ser:

100 0010 B
110 1111 o
110 1101 m
010 0000 
110 0100 d
110 1001 i
110 0001 a
010 0001 !

Observe que em um sequencia de caracteres (character string, também chamado de cadeia de caracteres), o "espaço" é um caractere também e tem seu próprio ponto de código. Isto é, quando você aperta a tecla de espaço (spacebar) o computador insere um código binário no texto que representa um espaço. De mesma forma, quando você aperta a tecla enter para criar uma nova linha, o computador insere no texto um código que representa a um caractere de "nova linha" (new line).

Historicamente, a codificação ASCII foi feita por uma instituição Americana para escrever textos em Inglês, e não inclui pontos de código para representar letras com acentos (e.g. áÁãâ, etc.). Existe uma outra codificação não-padronizada chamada de ASCII estendido (extended ASCII), que usa 8 bits por ponto de código e suporta acentos. Isso significa que textos salvos com o ASCII original não tem acentos, e se tiverem, o programa de computador irá remover esses acentos e outros caracteres inválidos como cê-cedilha (ç) antes de codificá-lo em ASCII.

0100 0001 A
1110 0111 ç
1110 0011 ã
0110 1111 o
0010 1110 .
Ação.

Veja acima que o primeiro bit (o mais da esquerda) de ambos "ç" e "ã" é 1 em ASCII estendido. Isso por que o ASCII estendido inclui todos os pontos de código do ASCII original, mas adiciona 1 bit por ponto de código. Quando esse bit é 1, os códigos estendidos, que incluem acentos, são usados.

A Microsoft usava sua própria codificação proprietária que chamava de ANSI, também conhecida como Windows-1252 ou CP-1252, que possuía pontos de código para outros caracteres como aspas curvas (“”). Do outro lado do mundo, teríamos codificações como Shift-JIS criadas para escrever texto em Japonês, já que há milhares e milhares de caracteres Japonês (os kanji) que precisariam ser representados e não caberiam nas meras 256 permutações possíveis com 8 bits.

Com isso cada idioma teria que ter sua própria codificação para seu sistema de escrita, e até mesmo para representar o alfabeto Latin e os algarismos arábicos tínhamos várias codificações. Era um caos. A solução para esse caos foi a padronização internacional de codificação de texto, realizada pela organização Unicode, através da codificação UTF.

Originalmente, a codificação UTF usava 16 bits por ponto de código, o que é chamado de UTF-16. Quando o Unicode 2.0 foi lançado, haviam tantos pontos de código que seriam necessários 21 bits para mapear todos eles, e isso foi arrendondado para 32 bits (4 bytes), que é o que é chamado de UTF-32. Porém, o que é normalmente usado é o UTF-8. No UTF-8, cada caractere possui no mínimo 8 bits. Em UTF-16, é no mínimo 16 bits. E em UTF-32, o tamanho dos caracteres é constante.

A vantagem do UTF-32 é que podemos saber o tamanho de um texto em caracteres pelo tamanho do texto em bytes. Por exemplo, se tivermos 400 bytes de texto, e cada caractere é 4 bytes, temos 100 caracteres. A desvantagem disso é que com 32 bits temos 4 bilhões de pontos de código. Muito mais do que precisamos para codificar texto escrito por seres humanos. Então todo caractere estaria gastando memória. Para escrever um texto em Inglês, que é maioria dos textos na Internet, só precisamos de 7 bits, não há motivo para usar mais de 4 vezes mais bits para isso!

A solução para esse problema é o UTF-8. No UTF-8, os o pontos de código de 0 a 127 são os mesmos que o ASCII original. Quando o primeiro bit é 0, o UTF-8 funciona exatamente como ASCII estendido. Isto é, é o ASCII original, com um bit extra, só que sem as extensões. Com isso se tivermos 100 caracteres ASCII, usamos somente 100 bytes em UTF-8. Quando o primeiro bit for 1, isso pode significa que o próximo byte, ou próximos bytes, são a continuação do mesmo caractere. Nesse caso, os próximos bytes devem começar com 1 também. Isto é, teríamos o seguinte formato:1

0xxx xxxx - ASCII original.
110x xxxx 1xxx xxxx - Ponto de código de 2 bytes.
1110 xxxx 1xxx xxxx 1xxx xxxx - Ponto de código de 3 bytes.
1111 0xxx 1xxx xxxx 1xxx xxxx 1xxx xxxx - Ponto de código de 4 bytes.

O UTF-8 usa os primeiros bits para saber se um byte é válido ou não. Se ele encontrar um byte que começa com um 1 sem um byte que começa com 110 ou outro código antes dele, o algoritmo irá simplesmente descartar esse byte.

Note que como estamos usando o primeiro bit para validar os bytes, não temos como encaixar os acentos do ASCII estendido em um byte só. Em UTF-8, letras acentuadas usam 2 bytes. Por exemplo:

A = 0100 0001
ç = 1100 0011 1010 0111
ã = 1100 0011 1010 0011
o = 0110 1111
. = 0010 1110
Ação.

Com isso, a quantidade de bytes por caractere é variada. Não é possível pegar um arquivo de 400 bytes com codificação UTF-8 e dizer quantos caracteres ele contém usando uma simples operação de divisão. Por ter 100 caracteres. Por ter 400. Depende do que está escrito.

No mundo moderno, a maioria dos programas de computador lida apenas com codificações UTF. Isto é, quando um texto é carregado na memória do computador, ele estará em UTF, e se não estiver, no caso do texto for carregado de um arquivo bem antigo, ele terá de ser convertido de sua codificação original para UTF, um processo chamado de decodificação (decoding).

Em arquivos de texto simples (extensão .txt) apenas o caracteres são salvos no arquivo, e com isso não há como saber não há como saber qual a codificação que foi usada para salvar o texto. Computadores iram assumir que o texto estará codificado como UTF-8, mas essa assunção pode estar errada, especialmente se for um arquivo ou programa extremamente antigo.

Por exemplo, se você estiver jogando jogos de computador retro, você pode encontrar problemas de codificação. Na web, embora hoje em dia a maior parte do conteúdo é mantido por algumas poucas empresas gerenciando redes sociais gigantescas, ainda existem páginas online que foram criadas a décadas atrás e que podem ter um codificação de texto diferente da que usamos hoje.

Quando texto aparece "errado na tela, tipicamente isso será um problema de codificação. O computador estará tentando decodificar o texto de usando um algoritmo que não bate com a codificação que foi usada para salvar aquele texto, e com isso os valores em bytes são convertidos para os caracteres incorretos. Há casos que é possível definir qual codificação usar manualmente e, se você souber qual codificação é a correta, fazer o texto aparecer de forma correta na tela, mas isso nem sempre pode ser possível.

  1. https://www.rfc-editor.org/rfc/rfc3629, acessado em 2023-12-21. ↩︎

Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *