Encoding, UTF-8, Unicode…

Contexto
Primeira postagem sobre o meu pet project, o camus {cã.mí}.
Ele é um sistema em que pretendo com o tempo ir adicionando módulos relacionados ao processamento de linguagem natural da língua portuguesa. Ver a descrição em “Hello Dave, Hello World”. Apesar do blog não ser exclusivamente sobre ele, muitas das postagens pretendo que sejam.
A primeira funcionalidade sendo implementada no camus é a versificação de um poema.

Sobre versificação:
“A versificação é o estudo de técnicas para propiciar a eufonia dos versos de um poema ou música” [1]
“Cada linha de um poema corresponde a um verso, os quais são classificados de acordo com as sílabas poéticas que apresentam.” [2]

Para realizar essa tarefa é preciso manipular palavras, frases e textos da língua portuguesa. Textos esses que podem conter caracteres em suas frases que não existam na língua inglesa, tais como cedilha, til, crase, acento circunflexo e acento agudo, que podem dar resultados inesperados caso não tratados previamente.
Nesse momento da implementação da separação silábica para fazer a versificação, os problemas mais recorrentes foram referentes ao encondig dos arquivos. Eles aconteceram desde o momento da visualização do arquivo pelo eclipse, passando pela compilação do projeto utilizando gradle, seguindo pelo commit e pull no github, com a aplicação já funcionando no heroku e devem vir ainda mais outros com o tempo.
Resolvi dar uma pesquisada sobre, e abaixo relato algumas informações encontradas apontando suas devidas referências.

ASCII
Computadores entendem apenas números, um código ASCII é uma representação numérica de um caractere, como uma letra, um número e um acento. Em 1963 o ASCII foi lançado para padronizar os caracteres utilizados nas trocas de informações entre os computadores. A ideia era que 128 caracteres (entre eles letras, pontuações, números, caracteres de controle, etc.) poderiam ser representados por um valor numérico pra cada um.  Exemplificando, tem-se que a letra ‘A’ é representada pelo número 65, que em hexadecimal equivale a 41 e em binário 01000001; a letra ‘B’ representada pelo número 66 (decimal), 42 (hexadecimal) e 01000010 (binário).
A primeira tabela ASCII descrevia 128 caracteres, depois ela foi aumentada para suportar 256 caracteres.

Criada na década de 1960 a partir do alfabeto inglês[4], não continha todos os caracteres para as outras línguas e não havia padronização, cada região montava seu próprio conjunto de caracteres e seu processo de manipulação, tornando difícil a transferência de textos de um computador para o outro, visto que o conjunto de caracteres e a forma como eles eram lidos eram diferentes. Como exemplo a palavra ‘atenção’ escrita utilizando UTF-8 e sendo lida utilizando ISO-8859-1, fica: atenção

Unicode
Para resolver esses problemas foi criado o Unicode, através do Unicode Consortium.
Ele é um conjunto de caracteres que reúne num só lugar, como um superconjunto, os caracteres necessários para escrita na maioria das línguas utilizadas nos computadores.
Para entender o Unicode é de grande importância conhecer os conceitos de Code Points e Code Space. Code points são os valores que estão no code space. Code Space é um intervalo, um conjunto de valores disponíveis para armazenar os caracteres do encoding. No ASCII estendido existem 256 code points, compreendidos entre os valores 0 até FF (hexadecimal) (code space), já o Unicode compreende 1.114.112 code points, entre os valores 0 até 10FFFF (hexadecimal) (code space). O jeito de armazenamento dos code points são diferentes para o ASCII e para o Unicode.

“Unicode codespace: A range of integers from 0 to 10FFFF. This particular range is defined for the codespace in the Unicode Standard. Other character encoding standards may use other codespaces.” [5]

UTF-8
É um codificador de caracteres (character encoding), capaz de codificar todos os caracteres possíveis definidos pelo Unicode. Utilizado para codificar texto em qualquer língua e com tamanho variável de armazenamento, manipula os code points a nível binário podendo usar de 1 a 4 bytes para codificar um code point Unicode.
Como exemplo pra representar 1 byte vou utilizar a seguinte notação: [00000001].

“UTF-8 is defined to encode codepoints in one to four bytes, depending on the number of significant bits in the numerical value of the codepoint” [6]

As codificações realizas ocupando 1 byte de espaço são para os caracteres de 0 a 127, equivalente a tabela ASCII, permitindo que a tabela Unicode seja compatível com a ASCII e um super conjunto dela.
2 bytes para caracteres entre 128 e 2047.
3 bytes para codificar caracteres entre 2048 até 65535
4 bytes para caracteres entre 65536 até 1.112.064

Utiliza os ‘high-order bits‘ para descobrir quantos bytes serão utilizados para realizar a codificação daquele determinado caractere. É a partir dele que se identifica quantos bytes serão utilizados para codificar o valor e obter o caractere desejado.

1-byte encoding:
Nas codificações com 1 byte de espaço, estão os valores entre 0 e 127, que são os mesmos da tabela ASCII. Cada byte tem o seguinte formato [00000000] (8 bits).
(X – notação para dizer que o espaço está livre)
7 bytes ficam disponíveis para armazenar o valor do caractere.
[0XXXXXXX]

2-byte enconding:
Com 2 bytes de espaço, os primeiros 3 bits do primeiro byte são ‘110’ e os dois primeiros bits do segundo byte são ’10’. Isso dá 11 bits para armazenar um caractere.
[110XXXXX][10XXXXXX]

3-byte encoding:
Utilizando 3 bytes pra armazenar o caractere, os 4 primeiros bits do primeiro byte são ‘1110’, e os dois primeiros bits dos 2 bytes restantes são ’10’, dando um total de 16 bits disponíveis para representar um caractere.
[1110XXXX][10XXXXXX][10XXXXXX]

4-byte encoding:
com 4 bytes segue-se o mesmo padrão, os primeiros bits ficam ‘11110’ e os primeiros bits dos bytes seguintes ficam com ’10’.
[11110XXX][10XXXXXX][10XXXXXX][10XXXXXX]

Conclusão
Basicamente é preciso ter cuidado ao lidar com arquivos de texto, pois a representação dos caracteres muda de acordo com o encoding escolhido. Muitos problemas ocorrem por criar um arquivo utilizando um determinado encoding e depois tentar lê-lo utilizando um diferente. Viu-se a existência de code points, code spaces e a estratégia que o UTF-8 utiliza para fazer a manipulação dos valores que representam cada caractere.
Abaixo existe uma lista de links interessantes sobre o assunto e que também serviram de referência para essa postagem.

Links interessantes
Introduction to UTF-8 and Unicode
Characters, Symbols and the Unicode Miracle – Computerphile
Decode unicode – the world’s writing systems: Johannes Bergerhausen at TEDxVienna
What is Unicode? and how Encoding works? [closed]
What’s the difference between encoding and charset?
What is Unicode, UTF-8, UTF-16?
The Unicode Standard: A Technical Introduction
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
Entendendo Unicode e os Character Encodings
Glossary of Unicode Terms

Referências
[1] https://pt.wikipedia.org/wiki/Versifica%C3%A7%C3%A3o
[2] https://www.todamateria.com.br/versificacao/
[3] http://www.ascii-code.com/
[4] https://en.wikipedia.org/wiki/ASCII#Overview
[5] http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf#G2212
[6] https://en.wikipedia.org/wiki/UTF-8#Description

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s