Kodumaro :: Diferença entre dado binário e dado textual

Publicado em 15 de Junho, 2017
As sombras da programação.

Às vezes percebo que as pessoas apresentam dificuldade em entender a diferença entre um protocol texto e outro binário. Pretendo dar uma explicação bem simples.

Texto ou binário significa a forma como os dados são representados em disco, memória ou na transmissão entre processos ou mesmo entre computadores.

Protocolo binário

A representação binária que vemos em arquivos binários, nos dados em memória de um programa em execução ou na transferência de dados em protocolos binários significa a representação mais direta possível dos dados em questão.

Por exemplo: tomemos o número 98.765. Sua representação binária é 1.1000.0001.1100.1101₂.

Para a representação binária, a primeira coisa que precisamos considerar é seu tipo. Se imaginarmos que se trata de um inteiro de 64 bits (em C chamado int), ele será representado usando 4 bytes:

00000000.00000001.10000001.11001101

Traduzindo em hexadecimal: 000181CD₁₆. É o equivalente a colocar zeros à esquerda de um número para completar as casas decimais.

A maior parte dos processadores atuais usam representação little-endian, o que significa que o byte de menor relevância (equivalente à unidade) fica mais à esquerda, enquanto os mais relevantes ficam sucessivamente à direita.

Dessa forma, o número 98.765 será representado como CD.81.01.00.

Na comunicação de rede, usa-se big-endian, que é justo o contrário: o byte mais relevante fica à esquerda: 00.01.81.CD.

Em muitos protocolos de comunicação é fornecido um byte que indica o tipo do valor que o sucede. Digamos que em nosso protocolo, inteiro de 64 bits seja representado pelo número 2. Então nosso dado seria codificado como 02.00.01.81.CD.

Esse é o conceito de protocolo binário.

Protocolo textual

No protocolo texto ou textual, todos os dados são codificados como strings, Então nosso número seria representado pelos códigos ASCII de cada dígito.

Então 98.765 seria:

39.38.37.36.35

No protocolo texto, sempre deve haver algum indicador do tamanho da string. Há duas abordagens mais comuns:

A primeira é a usada em C: acrescentar um carácter nulo ao final da string: 39.38.37.36.35.00.

A segunda abordagem é a de Pascal: colocar o tamanho da string no primeiro byte: 05.39.38.37.36.35.

Como nosso protocolo é texto, não podemos usar 05 como representação, já que textualmente trata-se de um carácter de controle, precisamos então também usar uma representação de textual de tamanho, e um carácter de controle como separação. Os caracteres mais usados pra isso são o LF (0A) e o CR (0C). Vamos usar o CR: 30.35.0C.39.38.37.36.35.

Colocando a comparação em perspectiva:

Em memóriaEm transferência
BinárioCD.81.01.0002.00.01.81.CD
Texto39.38.37.36.35.0030.35.0C.39.38.37.36.35

Dado textual

Um caso interessante é o da própria string.

No protocolo binário, um texto é representado pelos códigos de seus caracteres. Por exemplo Blog Kodumaro.

Usando codificação C, em memória seria: 41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.00.

Para transmissão seria informado um primeiro valor para seu tipo (digamos que string seja 1) e um byte para seu comprimento: 01.0D.41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.

Em protocolo texto, geralmente são usados caracteres de começo e fim de string, geralmente aspas (código 22₁₆).

Então em memória seria 22.41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.22.00.

Na transferência seria: 31.35.0C.22.41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.22.

Em memóriaEm transferência
Binário41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.0001.0D.41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F
Texto22.41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.22.0031.35.0C.22.41.6C.6F.67.20.4B.6F.64.75.6D.61.72.6F.22

Espero ter exclarecido um pouco.

Bônus: resposta HTTP

Os dados acima seriam transferidos em protocolo HTTP (texto) da forma mais compacta como:

32 30 30 20 4F 4B 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 70 65 3A 20 74 65 78 74 2F 70 6C 61 69 6E 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A 20 35 0D 0A 0D 0A 39 38 37 36 35 0D 0A

E:

32 30 30 20 4F 4B 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 70 65 3A 20 74 65 78 74 2F 70 6C 61 69 6E 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A 20 31 37 0D 0A 0D 0A 22 42 6C 6F 67 20 4B 6F 64 75 6D 61 72 6F 22 0D 0A

Respectivamente.