PCF-3

Questões comentadas, artigos e notícias

O que é um “texto claro”?

Posted by mike em 18/04/2009

text

Todo mundo pelo menos uma vez na vida, já salvou um arquivo .txt. Até aí grande coisa, afinal é a coisa mais normal do mundo. E você também provavelmente já deve ter trocado este .txt por e-mail ou copiado através um compartilhamento NFS ou SMB. Isso é tão trivial que a gente nem se importa com o que rola nos bastidores da memória, do processador ou na transmissão através da rede.

Pode parecer coisa de maluco esse papo, mas tente isso:

1. Crie um arquivo (no notepad) com o conteúdo: abc123
2. Salve como teste.txt
3. Tire o md5 dele

    Se você fizer uma máquina Windows, você terá o hash: e99a18c428cb38d5f260853678922e03

    Até aqui tudo muito simples, porém eu consegui um hash diferente: 85dd8abc8813834d58e4769c513ebbd4

    Eu estou realmente falando da string abc123. Como é possível obter dois hashes de um mesmo conteúdo? Uma das possibilidades é através da técnica de colisão, mas eu utilizei a ferramenta md5sum da instalação do cygwin, logo não é possível obter um resultado doido desses.

    O que eu fiz de diferente? Simples, um arquivo eu salvei no formato ANSI e o outro no formato UNICODE . E por qual motivo ele geraria um md5 diferente? Vamos relembrar o mais básico dos conceitos: um computador só entende 0 e 1. Um arquivo txt também é zero e 1. Vamos ver como os arquivos se parecem:

    $ hexdump.exe -C teste_asc.txt
    00000000 61 62 63 31 32 33 |abc123|
    00000006

    $ hexdump.exe -C teste_unicode.txt
    00000000 ff fe 61 00 62 00 63 00  31 00 32 00 33 00 |..a.b.c.1.2.3.|
    0000000e

    A ferramenta hexdump mostra o arquivo no formato raw, ou seja, como ele realmente é. Nos exemplos eu utilizei o parametro -C para facilitar a compreensão. Veja a documentação da ferramenta para entender melhor como ela funciona.

    A parte em azul é o offset do arquivo, a parte verde é o tamanho total em bytes e parte que interessa está em vermelho que são os dados.

    No primeiro exemplo temos a sequencia hexadecimal 61 62 63 31 32 33, que em decimal significa 97 98 99 49 50 51, que representam os códigos ANSI para a sequencia a b c 1 2 3.

    No segundo exemplo a coisa não é tão simples assim. O texto está em Unicode e aparece algumas coisas estranhas. Vamos entender ao modo jack estripador, por partes:

    ff fe 61 00 62 00 63 00  31 00 32 00 33 00

    Essa coisa estranha que está em vermelho significa como deve ser lido a string, também muito conhecido na praça por byte order mark (BOM).

    O que acontece é o seguinte, em Unicode, o ff fe quer dizer que é uma string UTF-16 Little Endian, logo estamos usando 2 bytes para escrever um caracter. Agora nos resta as partes em azul e verde. Cada trecho azul e verde são 2 bytes, cada byte está representado em hexadecimal.

    Para tudo!!! 61 00 não é letra a, mas sim o caracter maluco 愀. A pegadinha aqui é o seguinte: ff fe também quer dizer que a ordem de leitura dos bytes está invertida, eu te disse que era little endian, ou seja, o byte menos significativo (least significant byte – LSB) deve ser interpretado primeiro. No caso do 61 00 significa que o byte 00 é o menos significativo e depois o 61, logo a interpretação do caracter em hexadecimal será 00 61. Voilà! Agora temos a nossa conhecida letra a. E assim funciona para o resto dos caracteres.

    Apesar de vermos apenas abc123 no editor de texto, nos bastidores a coisa é um pouco diferente, que implica em cálculo de hash diferente, pois os bytes são diferentes. Um arquivo vai ter 6 bytes (ANSI) o outro vai ter 14 bytes (Unicode), 2 bytes para o BOM e mais 2 bytes para cada caracter.

    Isso ocorreu em uma máquina Windows, em uma máquina Linux o mesmo arquivo abc123 em ANSI vai ter um hash diferente, isso ocorre pois é adicionado no final da string o caracter de controle line feed. O mesmo texto ANSI criado em uma máquina Linux ficará assim:

    $ hexdump.exe -C teste_unix.txt
    00000000 61 62 63 31 32 33 0a |abc123.|
    00000007

    $ md5sum teste_unix.txt
    2c6c8ab6ba8b9c98a1939450eb4089ed *teste_unix.txt

    Percebeu que temos uma string de 7 bytes? 6 para a string literal e 1 para o caracter de controle. Ainda por cima conseguimos mais um hash para a string abc123.

    Conclusão:

    Não existe “texto claro”. Nós chamamos de texto claro, tudo aquilo que é codificado/decodificado de forma automática e transparente, mas no mundo real isso é uma falácia, um mito.

    Deixe uma resposta

    Preencha os seus dados abaixo ou clique em um ícone para log in:

    Logotipo do WordPress.com

    Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

    Imagem do Twitter

    Você está comentando utilizando sua conta Twitter. Sair / Alterar )

    Foto do Facebook

    Você está comentando utilizando sua conta Facebook. Sair / Alterar )

    Foto do Google+

    Você está comentando utilizando sua conta Google+. Sair / Alterar )

    Conectando a %s

     
    %d blogueiros gostam disto: