Codificação e decodificação de base 10 com c ++

Codificação e decodificação de base 10 com c ++
Base64 é um conjunto de caracteres de 64 caracteres, onde cada personagem consiste em 6 bits. Todos esses 64 caracteres são caracteres imprimíveis. Um personagem é um símbolo. Portanto, cada símbolo do conjunto de caracteres base de 64 é composto por 6 bits. Esses seis bits são chamados de sexteto. Um byte ou octeto consiste em 8 bits. O conjunto de caracteres ASCII consiste em 127 caracteres, alguns dos quais não são imprimíveis. Então, alguns personagens do conjunto de caracteres ASCII não são símbolos. Um símbolo para o conjunto de caracteres ASCII é composto por 8 bits.

Os dados no computador são armazenados em bytes de 8 bits cada. Os dados são enviados para fora do computador em bytes de 8 bits cada. Os dados são recebidos no computador em bytes de 8 bits cada.

Um fluxo de bytes pode ser convertido em um fluxo de sexto (6 bits por símbolo). E isso é a codificação base64. Um fluxo de Sextet pode ser convertido em um fluxo de bytes. E isso é base64 decodificação. Em outras palavras, um fluxo de caracteres ASCII pode ser convertido em um fluxo de símbolos de sexteto. Isso está codificando, e o inverso está decodificando. O fluxo de símbolos de sexteto, convertido de um fluxo de símbolos de octeto (byte), é mais longo que o fluxo de símbolos de octeto por número. Em outras palavras, um fluxo de caracteres base64 é mais longo que o fluxo correspondente de caracteres ASCII. Bem, codificando em base64 e decodificar a partir dele não é tão direto quanto apenas expresso.

Este artigo explica a codificação e decodificação de base64 com a linguagem do computador C ++. A primeira parte do artigo explica base64 codificação e decodificação corretamente. A segunda parte mostra como alguns recursos C ++ podem ser usados ​​para codificar e decodificar base64. Neste artigo, a palavra "octeto" e "byte" são usados ​​de forma intercambiável.

Conteúdo do artigo

  • Subindo para a base 64
  • Codificação de base64
  • Novo comprimento
  • Decodificação base64
  • Erro de transmissão
  • Recursos de bit c ++
  • Conclusão

Subindo para a base 64

Um alfabeto ou conjunto de caracteres de 2 símbolos pode ser representado com um bit por símbolo. Deixe os símbolos do alfabeto consistirem em: zero e um. Nesse caso, zero é o bit 0 e um é o bit 1.

Um alfabeto ou conjunto de personagens de 4 símbolos pode ser representado com dois bits por símbolo. Deixe os símbolos do alfabeto consistirem em: 0, 1, 2, 3. Nesta situação, 0 é 00, 1 é 01, 2 é 10 e 3 é 11.

Um alfabeto de 8 símbolos pode ser representado com três bits por símbolo. Deixe os símbolos do alfabeto consistirem em: 0, 1, 2, 3, 4, 5, 6, 7. Nesta situação, 0 é 000, 1 é 001, 2 é 010, 3 é 011, 4 é 100, 5 é 101, 6 é 110 e 7 é 111.

Um alfabeto de 16 símbolos pode ser representado com quatro bits por símbolo. Que os símbolos do alfabeto consistam em: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, f. Nesta situação, 0 é 0000, 1 é 0001, 2 é 0010, 3 é 0011, 4 é 0100, 5 é 0101, 6 é 0110, 7 é 0111, 8 é 1000, 9 é 1001, a é 1010, b é 1011, C é 1100, D é 1101, E é 1110 e F é 1111.

Um alfabeto de 32 símbolos diferentes pode ser representado com cinco bits por símbolo.

Isso nos leva a um alfabeto de 64 símbolos diferentes. Um alfabeto de 64 símbolos diferentes pode ser representado com seis bits por símbolo. Existe um conjunto de personagens específico de 64 símbolos diferentes, chamados base64. Neste conjunto, os 26 primeiros símbolos são as 26 cartas maiúsculas do idioma falado inglês, em sua ordem. Esses 26 símbolos são os primeiros números binários de 0 a 25, onde cada símbolo é um sexteto, seis bits. Os próximos números binários de 26 a 51 são as 26 letras minúsculas da língua falada inglesa, em sua ordem; Novamente, cada símbolo, um sexteto. Os próximos números binários de 52 a 61 são os 10 dígitos em árabe, em sua ordem; Ainda assim, cada símbolo, um sexteto.

O número binário para 62 é para o símbolo +, e o número binário para 63 é para o símbolo / . Base64 tem variantes diferentes. Portanto, algumas variantes têm símbolos diferentes para os números binários de 62 e 63.

A tabela base64, mostrando correspondências para o índice, número binário e caráter, é:

O alfabeto base64

Índice Binário Caracteres Índice Binário Caracteres Índice Binário Caracteres Índice Binário Caracteres
0 000000 A 16 010000 Q 32 100000 g 48 110000 c
1 000001 B 17 010001 R 33 100001 h 49 110001 x
2 000010 C 18 010010 S 34 100010 eu 50 110010 y
3 000011 D 19 010011 T 35 100011 j 51 110011 z
4 000100 E 20 010100 você 36 100100 k 52 110100 0
5 000101 F 21 010101 V 37 100101 eu 53 110101 1
6 000110 G 22 010110 C 38 100110 m 54 110110 2
7 000111 H 23 010111 X 39 100111 n 55 110111 3
8 001000 EU 24 011000 Y 40 101000 o 56 111000 4
9 001001 J 25 011001 Z 41 101001 p 57 111001 5
10 001010 K 26 011010 a 42 101010 q 58 111010 6
11 001011 eu 27 011011 b 43 101011 r 59 111011 7
12 001100 M 28 011100 c 44 101100 s 60 111100 8
13 001101 N 29 011101 d 45 101101 t 61 111101 9
14 001110 O 30 011110 e 46 101110 você 62 111110 +
15 001111 P 31 0111111 f 47 101111 v 63 111111 /

Preenchimento =

Na verdade, existem 65 símbolos. O último símbolo é =, cujo número binário ainda consiste em 6 bits, que é 111101. Não entra em conflito com o símbolo base64 de 9 - veja abaixo.

Codificação de base64
Campos de bits de sexteto

Considere a palavra:

cachorro

Existem três bytes ASCII para esta palavra, que são:

01100100 01101111 01100111

ingressou. Estes são 3 octetos, mas consistem em 4 Sextet da seguinte forma:

011001 000110 111101 100111

A partir da tabela de alfabeto Base64 acima, esses 4 sextettes são os símbolos,

ZG9N

Observe que a codificação de "cachorro" na base64 é "zg9n", o que não é compreensível.

Base64 codifica uma sequência de 3 octetos (bytes) em uma sequência de 4 sexto. 3 octetos ou 4 sextetas são 24 bits.

Considere agora a seguinte palavra:

isto

Existem dois octetos ASCII para esta palavra, que são:

01101001 01110100

ingressou. Estes são 2 octetos, mas consistem em 2 sexto e 4 bits. Um fluxo de caracteres base64 é composto de sextettetes (6 bits por caractere). Portanto, dois bits zero precisam ser anexados a esses 16 bits para ter 3 sextetos, ou seja::

011010 010111 010000

Isso não é tudo. A sequência Base64 é composta por 4 sextos por grupo; isto é, 24 bits por grupo. O caractere de preenchimento = é 111101. Dois zero bits já foram anexados aos 16 bits para ter 18 bits. Portanto, se os 6 bits de preenchimento do caractere de preenchimento forem anexados aos 18 bits, haverá 24 bits conforme necessário. Aquilo é:

011010 010111 010000 111101

Os últimos seis bits do último sexteto são o sexta . Esses 24 bits consistem em 4 sextetos, dos quais o último, mas um sexto tem os 4 primeiros bits do símbolo base64, seguido por dois bits zero.

Agora, considere a palavra a seguir:

EU

Há um octeto ASCII para esta palavra, que é:

01001001

Isso é 1 octeto, mas consiste em 1 sexto e 2 bits. Um fluxo de caracteres base64 é composto de sextettetes (6 bits por caractere). Portanto, quatro bits zero precisam ser anexados a esses 8 bits para ter 2 sextetas, ou seja::

010010 010000

Isso não é tudo. A sequência Base64 é composta por 4 sextos por grupo; isto é, 24 bits por grupo. O caractere de preenchimento = é 111101, que tem seis bits de comprimento. Quatro bits zero já foram anexados aos 8 bits para ter 12 bits. Isso não é até quatro sextettes. Portanto, mais dois sextois de preenchimento precisam ser anexados a fazer 4 Sextet, ou seja:

010010 010000 111101 111101

Fluxo de saída de base64

No programa, uma matriz de cargas do alfabeto base64 deve ser feita, onde o índice 0 tem o caráter de 8 bits, a; O índice 1 tem o caráter de 8 bits, b; O índice 2 tem o caráter de 8 bits, C, até que o índice 63 tenha o caráter de 8 bits, / / .

Então, a saída para a palavra de três caracteres, "cachorro" será "ZG9N" de quatro bytes, expressos em bits como

01011010 01000111 00111001 01101110

onde z é 01011010 de 8 bits; G é 01000111 de 8 bits; 9 é 00111001 de 8 bits e n é 01101110 de 8 bits. Isso significa que, de três bytes da string original, quatro bytes são emitidos. Esses quatro bytes são valores da matriz do alfabeto base64, onde cada valor é um byte.

A saída para a palavra de dois caracteres, "it" será "axq =" de quatro bytes, expressos em bits como

01100001 01011000 01010001 00111101

obtido da matriz. Isso significa que, de dois bytes, quatro bytes ainda são emitidos.

A saída para a palavra de um personagem, "eu" será "sq ==" de quatro bytes, expressos em bits como

01010011 01010001 00111101 00111101

Isso significa que, de um byte, quatro bytes ainda são emitidos.

Um sexteto de 61 (111101) é emitido como 9 (00111001). Um sexteto de = (111101) é emitido como = (00111101).

Novo comprimento

Há três situações a serem consideradas aqui para ter uma estimativa para o novo comprimento.

  • O comprimento original da corda é um múltiplo de 3, e.g., 3, 6, 9, 12, 15, etc. Nesse caso, o novo comprimento será exatamente 133.33% da duração original porque três octetos acabam como quatro octetos.
  • O comprimento original da corda tem dois bytes de comprimento, ou termina com dois bytes, depois de um múltiplo de 3. Nesse caso, o novo comprimento estará acima de 133.33% do comprimento original porque uma parte da corda de dois octetos acaba como quatro octetos.
  • O comprimento original da corda tem um byte de comprimento, ou termina com um byte após um múltiplo de 3. Nesse caso, o novo comprimento estará acima de 133.33% do comprimento original (mais acima do caso anterior), porque uma parte da corda de um octeto acaba como quatro octetos.

Comprimento máximo de linha

Depois de passar da string original através da matriz do alfabeto Base64 e terminar com octetos de pelo menos 133.33% de comprimento, nenhuma sequência de saída deve ter mais de 76 octetos. Quando uma sequência de saída tem 76 caracteres, um personagem de nova linha deve ser adicionado antes de outros 76 octetos ou menos caracteres são adicionados. Uma string de saída longa possui todas as seções, composta por 76 caracteres cada, exceto a última, se não for até 76 caracteres. O uso dos programadores de separadores de linha é provavelmente o caractere de nova linha, '\ n'; Mas deveria ser "\ r \ n".

Decodificação base64

Para decodificar, faça o inverso da codificação. Use o algoritmo a seguir:

  • Se a string recebida for superior a 76 caracteres (octetos), divida a corda longa em uma matriz de cordas, removendo o separador da linha, que pode ser "\ r \ n" ou '\ n'.
  • Se houver mais de uma linha de 76 caracteres cada, isso significa todas as linhas, exceto as últimas consistem em grupos de quatro caracteres cada. Cada grupo resultará em três caracteres usando a matriz do alfabeto base64. Os quatro bytes precisam ser convertidos em seis sextetas antes de serem convertidos em três octetos.
  • A última linha, ou a única linha que a string poderia ter, ainda consiste em grupos de quatro caracteres. O último grupo de quatro caracteres pode resultar em um ou dois caracteres. Para saber se o último grupo de quatro caracteres resultará em um personagem, verifique se os dois últimos octetos do grupo são cada um ASCII, = =. Se o grupo resultar em dois caracteres, apenas o último octeto deve ser ASCII, = =. Qualquer sequência quádrupla de caracteres em frente a esta última sequência quádruplina é tratada como na etapa anterior.

Erro de transmissão

No final do recebimento, qualquer caractere que não seja o do caractere de separação de linha ou caracteres que não é um valor da matriz alfabeta base64 indica um erro de transmissão; e deve ser tratado. O manuseio de erros de transmissão não é abordado neste artigo. Nota: A presença do byte, = entre os 76 caracteres, não é um erro de transmissão.

Recursos de bit c ++

Membros fundamentais do elemento Struct podem receber vários bits que não 8. O programa a seguir ilustra o seguinte:

#incluir
usando namespace std;
struct s3
não assinado int a: 6;
não assinado int b: 6;
não assinado int c: 6;
não assinado int d: 6;
s3;
int main ()

S3.a = 25;
S3.b = 6;
S3.c = 61;
S3.d = 39;
cout<retornar 0;

A saída é:

25, 6, 61, 39

Os números inteiros de saída são os atribuídos. No entanto, cada um ocupa 6 bits na memória e não 8 ou 32 bits. Observe como o número de bits é atribuído, na declaração, com o cólon.

Extraindo os primeiros 6 bits do octeto

C ++ não tem uma função ou operador para extrair o primeiro conjunto de bits de um octeto. Para extrair os 6 primeiros bits, desligue o conteúdo do octeto por 2 lugares. Os dois bits desocupados na extremidade esquerda estão cheios de zeros. O octeto resultante, que deve ser um char não assinado, agora é um número inteiro, representado pelos primeiros 6 bits do octeto. Em seguida, atribua o octeto resultante a um membro do campo de bits de 6 bits. O operador de mudança certo é >>, não deve ser confundido com o operador de extração do objeto Cout.

Supondo que o membro do campo de 6 bits da estrutura seja, S3.A, então os 6 primeiros bits do personagem 'D' são extraídos da seguinte forma:

char não assinado CH1 = 'D';
CH1 = CH1 >> 2;
S3.a = CH1;

O valor de S3.A agora pode ser usado para indexar a matriz do alfabeto base64.

Produzindo segundo sexto a partir de 3 caracteres

Os segundos seis bits consistem nos dois últimos bits do primeiro octeto e nos próximos 4 bits do segundo octeto. A idéia é colocar os dois últimos bits para a quinta e a sexta posições de seu octeto e fazer com que o restante dos bits do octeto zero; Então, em termos de bit e com os quatro primeiros bits do segundo octeto que foi alterado para o fim.

A mudança de esquerda nos últimos dois bits para a quinta e a sexta posições é feita pelo operador de deslocamento esquerdo de bits, <<, which is not to be confused with the cout insertion operator. The following code segment left-shifts the last two bits of 'd' to the fifth and sixth positions:

char não assinado i = 'd';
i = i <<4;

Neste ponto, os bits desocupados foram preenchidos com zeros, enquanto os bits deslocados não vacados que não são necessários ainda estão lá. Para fazer o resto dos bits em i zero, eu tenho que ser um pouco em termos e com 00110000, que é o número inteiro, 96. A seguinte declaração faz isso:

i = i & 96;

O segmento de código a seguir, muda os quatro primeiros bits do segundo octeto para as últimas posições de quatro bits:

char não assinado j = 'o';
j = j >> 4;

Os bits desocupados foram preenchidos com zeros. Neste ponto, eu tenho 8 bits e J tem 8 bits. Todos os 1s nesses dois chars não assinados estão agora em suas posições certas. Para obter o char, para o segundo sexteto, esses dois chars de 8 bits devem ser de um pouco e, como segue:

char não assinado ch2 = i & j;

Ch2 ainda tem 8 bits. Para fazer seis bits, ele deve ser atribuído a um membro do campo de bits de 6 bits. Se o membro do campo de bits da estrutura for S3.B, então a tarefa será feita da seguinte maneira:

S3.b = CH2;

A partir de agora, S3.B será usado em vez de CH2 para indexar a matriz do alfabeto base64.

Adicionando dois zeros para o terceiro sexto

Quando a sequência a ser codificada tem dois caracteres, o terceiro sexteto precisa ser adicionado a dois zeros. Suponha que um octeto já esteja prefixado por dois bits zero, e os próximos quatro bits são os bits certos. Para fazer os dois últimos bits deste octeto, dois zeros, em termos de bit e o octeto com 11111100, que é o número inteiro, 252. A seguinte declaração faz isso:

char não assinado ch3 = octeto e 252;

Ch3 agora tem todos os últimos seis bits, que são os bits necessários, embora ainda consista em 8 bits. Para fazer seis bits, ele deve ser atribuído a um membro do campo de bits de 6 bits. Se o membro do campo de bits da estrutura for S3.C, então a tarefa será feita da seguinte forma:

S3.c = CH3;

A partir de agora, S3.C será usado em vez de CH2 para indexar a matriz do alfabeto base64.

O restante do manuseio de bits pode ser feito como explicado nesta seção.

Base64 Array do alfabeto

Para codificar, a matriz deve ser algo como,

char não assinado arr [] = 'a', 'b', 'c', - - - '/';

Decodificação é o processo reverso. Portanto, um mapa não ordenado deve ser usado para essa estrutura, algo como,

UNODERED_MAP umap = 'a', 0, 'b', 1, 'c', 2, - - - '/', 63;

A classe String

A classe String deve ser usada para as seqüências totais de codificação e codificada. O restante da programação é a programação normal de C ++.

Conclusão

Base64 é um conjunto de caracteres de 64 caracteres, onde cada personagem consiste em 6 bits. Para codificação, cada três bytes da string original é convertido em quatro sextoções de 6 bits cada. Esses Sextets são usados ​​como índices para a tabela de alfabeto base64 para codificar. Se a sequência consistir em dois caracteres, quatro sextetas ainda serão obtidos, com o último sexteto, sendo o número 61. Se a sequência consistir em um caractere, quatro sextetas ainda serão obtidos, com os dois últimos Sextet, sendo dois dos número 61.

Decodificação faz o contrário.