Como Criar um Simples Codificador e Decodificador com C++ da forma correta

🚀 Melhorando o código mostrado nos vídeos curtos.


Como Criar um Simples Codificador e Decodificador com C++ da forma correta


Há um tempo atrás eu havia postado no Shorts, Reels e Tik Tok um código que criava uma forma simples e rápida de codificar e decodificar strings que pode ser usado para inúmeras situações onde as pessoas só esperam codificadores como: base64, por exemplo.

Logo, essa maneira, dificulta um pouco mais saber qual o algoritmo para decodificar. O código C++ se resumia ao conteúdo abaixo:

#include <iostream>

constexpr auto encode = [](auto S){
  while((*S++)++);
};

constexpr auto decode = [](auto S){
  while(--(*S++));
};

int main(int argc, char **argv){
  std::string str {};
  if(argc > 1){
    str = argv[1];
  }else{ return EXIT_FAILURE;}

  encode(str.data());
  std::cout << "Encode: " << str << '\n';
  
  decode(str.data());
  std::cout << "Decode: " << str << '\n';

  return EXIT_SUCCESS;
}

Apesar de funcionar, esse código possui alguns problemas:

  • O ideal não é usar constexpr, estamos modificando o ponteiro da string, tornar a função do tipo void é o mais lógico;
  • A função encode não faz verificação de final de linha e isso resulta em um problema grave que causa corrupção de memória.

Eu percebi isso quando fui implementar em uma solução que estava criando, onde eu só copiei o código gerado pela função encode e fui usar em um aplicativo e quando tentei rodar apareceu a seguinte falha:

*** stack smashing detected ***: terminated
Abortado (imagem do núcleo gravada)

Logo, o código corrigido fica assim:

#include <iostream>
#include <string>

void encode(char * s) {
  while (*s != '\0') {   // Verifica o fim da string
    ++(*s);              // Incrementa o caractere atual
    ++s;                 // Avança para o próximo caractere
  }
}

void decode(char * s) {
  while (*s != '\0') {   // Verifica o fim da string
    --(*s);              // Decrementa o caractere atual
    ++s;                 // Avança para o próximo caractere
  }
}

int main(int argc, char **argv) {
  if (argc > 1) {
    std::string str = argv[1];

    encode(str.data());
    std::cout << "Encode: " << str << '\n';

    decode(str.data());
    std::cout << "Decode: " << str << '\n';
  }

  return EXIT_SUCCESS;
}

Agora se você copiar o resultado codificado poderá usá-lo para decodificar em outra implementação sem chance de ter um stack smashing.

Para confirmar isso você pode usar flags que verificam se houve violação de memória, exemplo:

g++ -g -Wpedantic -Wall -Werror -fsanitize=address encode.cpp

Após rodar, exemplo:

./a.out "Terminal Root"
Encode: Ufsnjobm!Sppu
Decode: Terminal Root

Se quiser dificultar ainda mais, você pode usar loops para rodar a função quantas vezes você quiser e usar o mesmo número de vezes para decodificar, exemplo do que estou falando sem loops:

Isso, modifica 4 vezes a string e usamos 4 vezes novamente para retonar a string original:

encode(str.data());
encode(str.data());
encode(str.data());
encode(str.data());
std::cout << "Encode: " << str << '\n';

decode(str.data());
decode(str.data());
decode(str.data());
decode(str.data());
std::cout << "Decode: " << str << '\n';

Ou usando o um loop for:

for(int i = {}; i < 4; ++i){
  encode(str.data());
}
std::cout << "Encode: " << str << '\n';

for(int i = {}; i < 4; ++i){
  decode(str.data());
}
std::cout << "Decode: " << str << '\n';

Em ambos os casos a saída será a mesma:

./a.out "Terminal Root"
Encode: Xivqmrep$Vssx
Decode: Terminal Root

Como funciona?

  • Encode: Cada caractere da string é incrementado em 1. Por exemplo:
    • ‘T’ -> ‘U’
    • ‘e’ -> ‘f’
    • ‘r’ -> ‘s’
    • etc.
  • Decode: Cada caractere da string é decrementado em 1, revertendo a operação do encode. Por exemplo:
    • ‘U’ -> ‘T’
    • ‘f’ -> ‘e’
    • ’s’ -> ‘r’
    • etc.

Para mais informações sugiro os links:


cpp cppdaily


Compartilhe


Nosso canal no Youtube

Inscreva-se


Marcos Oliveira

Marcos Oliveira

Desenvolvedor de software
https://github.com/terroo


Crie Aplicativos Gráficos para Linux e Windows com C++

Aprenda C++ Moderno e crie Games, Programas CLI, GUI e TUI de forma fácil.

Saiba Mais

Receba as novidades no seu e-mail!

Após cadastro e confirmação do e-mail, enviaremos semanalmente resumos e também sempre que houver novidades por aqui para que você mantenha-se atualizado!