Codificação

Uma introdução a ASCII e Unicode

No artigo bits, bytes e unidades de medida vimos que os computadores representam números, imagens e tudo mais através de zeros e uns. E não é diferente com textos, é preciso que exista um sistema de codificação que faça a conversão de letras e caracteres para números, para que depois o computador possa ter a representação binária disso.

Ou seja, tudo o que o computador vai processar precisa ser convertido para bytes, afinal. É aí que entra a tabela ASCII (sigla para Código Padrão Americano para o Intercâmbio de Informação), um sistema de codificação de caracteres que foi adotado em larga escala na computação. A primeira tabela ASCII usava um código de 7 bits e deixava o oitavo bit liberado para outros fins (de checagem de erros de transmissão), o que fez com que ela pudesse representar no máximo 128 caracteres.

Tabela ASCII

Tabela ASCII 7 bits

O “a” minúsculo que você digita no teclado é representado na tabela pelo decimal 97, mas internamente o computador trabalha isso em binário, ou seja, com 8 bits 01100001 (97 em decimal).

Faça esse teste: crie um arquivo de texto e coloque nele apenas a letra a. Depois de salvá-lo, o seu sistema operacional vai reconhecer que ele ocupa apenas 1 byte (8 bits):

One Byte

Se você adicionar mais um caractere de 8 bits, como o b, ele vai contabilizar 2 bytes.

Ainda lá nos anos 60 notaram a necessidade de normalizar a tabela para usar os 8 bits disponíveis (1 byte), que era o sistema mais usado na época. Criaram uma versão estendida da ASCII e então ela passou representar até 256 caracteres. Além dos caracteres da versão original, a estendida dispõe de alguns novos símbolos e caracteres gráficos:

Tabela ASCII 8 bits

O problema, e você já deve ter notado, é que a tabela ASCII não consegue representar os símbolos de outras línguas como a hebraica, arábica, grega, japonesa e até mesmo alguns símbolos latinos, como alguns da nossa língua portuguesa.

Foi então que no início dos anos 90 surgiu o Unicode, bem no advento da internet, momento crucial em que a informática passou a necessitar de um padrão universal de representação de texto, para que o tráfego das informações ficasse inteligível em todos os computadores, não importando o idioma de escrita.

Unicode

O Unicode faz parte do ISO 10646 e é o padrão de representação de texto mais usado. Uni em latim significa um, Unicode remete à ideia de um padrão universal de codificação de caracteres. Ele foi projetado com base no código ASCII, com a diferença que ele é capaz de codificar quase todos os caracteres e símbolos presentes nas mais variadas línguas do mundo, até mesmo aquele emoji que você tanto curte, ele consegue representar. Existem diversos sistemas de codificação Unicode e hoje (junho 2020) eles conseguem representar mais de 143 mil caracteres. Unicode nos permite usar 8, 16 e até 32 bits (mais de 2 bilhões de caracteres possíveis).

Você pode experimentar salvar um caractere unicode no disco, como esse aqui:

😍

Ele vai ocupar 4 bytes, ou seja, estará usando 32 bits.

Unicode mapeia cada caractere para um código específico chamado de code point que tem o formato U+<código hexadecimal> numa faixa de U+0000 a U+10FFFF.

Alguns caracteres representados em Unicode e ASCII:

UnicodeASCII (decimal)Caractere
U+002133!
U+002436$
U+002638&
U+002A42*

Para ter acesso a uma lista completa de caracteres unicode, tem uma ótima referência na wikipedia.

UTF-8

O encoding da família Unicode mais amplamente usado e difundido em sistemas operacionais, web e linguagens de programação é o UTF-8, que foi co-criado no início dos anos 90 por um dos arquitetos da linguagem Go (Rob Pike). Além disso, UTF-8 é o encoding padrão adotado pela W3C para a Web e ele é 100% compatível com a tabela ASCII.

Ele é um padrão de encoding variável e pode usar de 1 até 4 bytes, a depender do caractere que se está representando. Ele resolve o problema de não se fixar 32 bits para todos os caracteres, o que naturalmente faria um texto escrito em inglês ocupar um espaço muito maior do que ele poderia ocupar.

No seu HTML quando você indica:

<meta charset="utf-8">

Você está dizendo pro navegador que sua página utiliza esse encoding.

Nas linguagens de programação

Go é um exemplo de linguagem moderna que adota a codificação UTF-8 por padrão (e não poderia ser diferente, já que o Rob Pike é um dos arquitetos dela):

package main

import "fmt"

func main() {
    fmt.Println("嗨")
    fmt.Println("Cześć")
    fmt.Println("Coração")
}

Hoje em dia a maioria das linguagens possuem um bom suporte a Unicode, o que não necessariamente quer dizer que elas o suportem na escrita de declarações, nomes de variáveis etc. Mas Go, PHP, entre outras suportam.

https://play.golang.org/p/ANEgJAFStmX

package main

import "fmt"

func こんにちは() {
    fmt.Println("Hello")
}

func main() {
    こんにちは()
}

Um exemplo em PHP:

<?php

$こんにちは = "Hello";

echo $こんにちは;

No PHP, para imprimir um caractere unicode através do seu code point, basta usar essa sintaxe:

<?php

echo "\u{1F648}"; // 🙈

O código desse emoji e de outros você pode obter no site Unicode Table.

Exemplo em Go que imprime uma lista de emojis a partir da faixa de seus códigos Unicode: https://play.golang.org/p/yPgKw3Z9HW

Concluindo

Vimos apenas a superfície do que são os padrões de codificação de caracteres. São bem mais complexos e amplos que isso, em especial o Unicode. Mas o que vimos aqui é o essencial que todo desenvolvedor precisa saber.

Recomendo que você assista o vídeo Characters, Symbols and the Unicode Miracle.

Até a próxima!

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200