! ? @ + - * / = < > 0 1 2 3 4 5 6 7 8 9 A E I O U C … Á Â Ã É Í Ó Ô Õ Ú Ç … ≡ ≠ ≤ ≥ Γ Δ Π Σ Ω ⋮
Esta página faz uma rápida introdução aos conceitos de Unicode, esquema de codificação, e UTF-8. Para mais informações sobre o assunto veja os artigos indicados no fim da página.
Sumário:
Um caractere é um símbolo tipográfico usado para escrever texto em alguma língua. (Embora imperfeita, essa definição é suficiente para nossas necessidades.) É importante não confundir o conceito de caractere com o tipo-de-dados char da linguagem C. Eis alguns exemplos de caracteres:
! " - 9 A B a b ~ À ã ç é ÿ Σ α — “
O número de caracteres usados pelas diferentes línguas do mundo é muito grande. O português usa apenas 127 caracteres e o inglês fica satisfeito com 94 desses. Mas não podemos nos limitar a essas duas línguas porque estamos expostos a muitas outras línguas, às vezes várias numa mesma sentença. A isso se somam os caracteres especiais usados por várias áreas da ciência.
Para começar a organizar essa Torre de Babel, é preciso dar nomes a todos os caracteres. O consórcio Unicode de empresas de informática atribuiu nomes numéricos (conhecidos como code points) a mais de 1 milhão de caracteres. Segue uma minúscula amostra da lista de caracteres e seus números:
número Unicode | caractere |
33 | ! |
34 | " |
45 | - |
57 | 9 |
65 | A |
66 | B |
97 | a |
98 | b |
126 | ~ |
192 | À |
227 | ã |
231 | ç |
233 | é |
255 | ÿ |
931 | Σ |
945 | α |
8212 | — |
8220 | “ |
Nessa amostra, os nomes numéricos dos caracteres
estão escritos em notação decimal.
Em geral, entretanto,
esses nomes são escritos em notação
hexadecimal.
Além disso, é usual acrescentar o prefixo U+
a cada número:
Unicode | caractere |
U+0021 | ! |
U+0022 | " |
U+002D | - |
U+0039 | 9 |
U+0041 | A |
U+0042 | B |
U+0061 | a |
U+0062 | b |
U+007E | ~ |
U+00C0 | À |
U+00E3 | ã |
U+00E7 | ç |
U+00E9 | é |
U+00FF | ÿ |
U+03A3 | Σ |
U+03B1 | α |
U+2014 | — |
U+201C | “ |
A lista completa de caracteres e seus números Unicode pode ser vista na página List of Unicode characters da Wikipedia ou na página Unicode / Character reference do Wikibooks.
O conjunto de todos os caracteres da lista Unicode pode ser chamado alfabeto Unicode e cada caractere desse alfabeto pode ser chamado caractere Unicode. (Se a pretensão do projeto Unicode for justificada, todos os caracteres de todas as línguas do mundo são caracteres Unicode.)
Os primeiros 128 caracteres da lista Unicode são os mais usados. Esse conjunto de caracteres vai de U+0000 a U+007F e é conhecido como alfabeto ASCII. Os elementos desse alfabeto serão chamados caracteres ASCII. O alfabeto ASCII contém letras, dígitos decimais, sinais de pontuação, e alguns caracteres especiais. A lista dos 128 caracteres ASCII e seus números Unicode está registrada na Tabela ASCII.
Infelizmente o alfabeto ASCII não é suficiente para escrever texto em português, pois não contém letras com sinais diacríticos.
Como armazenar os caracteres Unicode em arquivos digitais e na memória? Poderíamos representar cada caractere pelo seu número Unicode escrito em notação binária. Mas isso exigiria 3 bytes por caractere, o que é muito ineficiente dado que apenas 1 byte é suficiente para os caracteres mais comuns. É preciso recorrer, então, a representações mais complexas.
Um esquema de codificação
(= character encoding)
é uma tabela que associa uma sequência de bytes
com cada número Unicode,
e portanto com cada caractere Unicode.
(Em geral, omitimos a palavra esquema
e dizemos apenas codificação
.)
A sequência de bytes associada com um caractere
é o código do caractere.
As próximas seções examinam dois esquemas de codificação:
ASCII e UTF-8.
O código ASCII é muito simples: o número Unicode de cada caractere é escrito em notação binária. Esse código é usado apenas para o alfabeto ASCII. Como o alfabeto tem apenas 128 caracteres, o código ASCII necessita de apenas 1 byte por caractere e o primeiro bit desse byte é 0. Segue uma amostra da tabela de códigos:
Unicode | ASCII | hexa | |
U+0021 | ! | 00100001 | 0x21 |
U+0022 | " | 00100010 | 0x22 |
U+002D | - | 00101101 | 0x2D |
U+0039 | 9 | 00100111 | 0x39 |
U+0041 | A | 01000001 | 0x41 |
U+0042 | B | 01000010 | 0x42 |
U+0061 | a | 01100001 | 0x61 |
U+0062 | b | 01100010 | 0x62 |
U+007E | ~ | 01111110 | 0x7E |
A última coluna traz o código ASCII escrito em notação hexadecimal.
(Por que não aproveitar todos os 8 bits de um byte? Com isso, poderíamos codificar 128 caracteres adicionais além dos 128 do alfabeto ASCII. O código ISO-LATIN-1 faz exatamente isso, mas caiu em desuso. O conjunto ISO-LATIN-1 de caracteres inclui, entre outros, os caracteres ª ± º ¼ ½ ¾ À Á Â Ã Ç È É Ê Ì Í Î Ò Ó Ô × Ù Ú Û à á â ã ç è é ê ì í î ò ó ô õ ÷ ù ú û . Os nomes numéricos desses caracteres são iguais na tabela ISO-LATIN-1 e na tabela Unicode.)
Se usássemos um número fixo de bytes por caractere, precisaríamos de 3 bytes. A solução é recorrer a um código multibyte, que emprega um número variável de bytes por caractere: alguns caracteres usam 1 byte, outros usam 2 bytes, e assim por diante.
O código multibyte mais usado é conhecido como UTF-8. Ele associa uma sequência de 1 a 4 bytes (8 a 32 bits) com cada caractere Unicode. Os primeiros 128 caracteres usam o velho e bom código ASCII de 1 byte por caractere. Os demais caracteres têm um código mais longo. Veja uma minúscula amostra:
Unicode | código UTF-8 | hexa | |
U+0021 | ! | 00100001 | 0x21 |
U+0022 | " | 00100010 | 0x22 |
U+002D | - | 00101101 | 0x2D |
U+0039 | 9 | 00100111 | 0x39 |
U+0041 | A | 01000001 | 0x41 |
U+0042 | B | 01000010 | 0x42 |
U+0061 | a | 01100001 | 0x61 |
U+0062 | b | 01100010 | 0x62 |
U+007E | ~ | 01111110 | 0x7E |
U+00C0 | À | 11000011 01000000 | 0xC380 |
U+00E3 | ã | 11000011 10100011 | 0xC3A3 |
U+00E7 | ç | 11000011 10100111 | 0xC3A7 |
U+00E9 | é | 11000011 10101001 | 0xC3A9 |
U+00FF | ÿ | 11000011 10111111 | 0xC3BF |
U+03A3 | Σ | 11001110 10100011 | 0xCEA3 |
U+03B1 | α | 11001110 10110001 | 0xCEB1 |
U+2014 | — | 11100010 10000000 10010100 | 0xE28094 |
U+201C | “ | 11100010 10000000 10011100 | 0xE2809C |
(A última coluna traz o código UTF-8 escrito em notação hexadecimal.) A lista dos códigos UTF-8 de todos os caracteres Unicode pode ser vista em UTF-8 encoding table and Unicode characters ou na página Unicode / Character reference do Wikibooks. Por exemplo, a cadeia de caracteres ação é representada em UTF-8 pela seguinte sequência de bytes:
0x61 | 0xC3 | 0xA7 | 0xC3 | 0xA3 | 0x6F |
a | ç | ã | o |
Todas as letras com sinais diacríticos usadas em português são representados em UTF-8 por apenas 2 bytes, o primeiro dos quais é 0xC3 (195 em notação decimal).
Decodificação. Como o número de bytes por caractere não é fixo, a decodificação de uma sequência de bytes não é fácil. Como saber onde termina o código de um caractere e começa o código do caractere seguinte? O esquema de codificação UTF-8 foi construído de modo que os primeiros bits do código de um caractere dizem quantos bytes o código ocupa. Assim, se o primeiro bit é 0, e portanto o valor do primeiro byte é menor que 128, então esse é o único byte do caractere. Se o valor do primeiro byte pertence ao intervalo 192 .. 223 então o código do caractere tem dois bytes. E assim por diante.
Suporemos UTF-8. A linguagem de programação C não prescreve um esquema de codificação específico. Mas o código mais usado é UTF-8, tanto para entrada e saída quanto para a representação interna de caracteres. O presente sítio supõe que todos os arquivos de texto, sejam eles programas ou dados, usam código UTF-8. (Mas em muitos exemplos apenas o subconjunto ASCII de UTF-8 é usado.)
67 195 179 100 105 103 111
0x41 0x74 0x65 0x6E 0xC3 0xA7 0xC3 0xA3 0x6F 0x21
(Consulte a página UTF-8 encoding table and Unicode characters. Use o botão go to other block para ver as várias partes da tabela.)
Não há como saber, com certeza, qual o esquema de codificação usado por um dado arquivo de texto. O autor do arquivo precisa informar, fora do arquivo, qual código usou.
Há utilitários (como file, por exemplo) que examinam um arquivo e tentam adivinhar, com algum grau de confiança, o seu esquema de codificação.
Se souber qual o esquema de codificação usado por seu arquivo, você pode usar o aplicativo iconv para mudar a codificação (convertendo, por exemplo, um arquivo codificado em ISO-LATIN-1 em um arquivo equivalente codificado em UTF-8).