
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:
constexpr, estamos modificando o ponteiro da string, tornar a função do tipo void é o mais lógico;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.cppApós rodar, exemplo:
./a.out "Terminal Root"
Encode: Ufsnjobm!Sppu
Decode: Terminal RootSe 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 RootComo funciona?
encode. Por exemplo:
Para mais informações sugiro os links:
cpp cppdaily shorts reels tiktok