Simple Cipher

Iniciado por d3adly, Mayo 18, 2020, 11:45:13 PM

Tema anterior - Siguiente tema

0 Miembros y 6 Visitantes están viendo este tema.

Mayo 18, 2020, 11:45:13 PM Ultima modificación: Mayo 07, 2022, 09:33:41 AM por d3adly
Hola les comparto un cipher sencillo que hice, basado en rot13 y xor a diferencia que rota 128 caracteres y este numero aumenta dependiendo de la longitud de la informacion a modificar, antes pasa por base64 para poder trabajar con caracteres imprimibles, logrando (aun no probado) trabajar con datos binarios, tiene varios errores y posiblemente mal manejo de memoria por lo cual agradezco sus aportes/correcciones/sugerencias.

Código: c++

#include<iostream>
#include<string>
#include<cstring>
class b64{
   public:
size_t b64_encoded_size(size_t inlen){
size_t ret = inlen;
if(inlen % 3 != 0){
ret += 3 - (inlen % 3);
}
ret /= 3;
ret *= 4;
return ret;
}
size_t b64_decoded_size(const char *in){
size_t len, ret, i;
if(in == nullptr){
return 0;
}
len = std::string(in).length();
ret = len / 4 * 3;
for(i = len; i-->0;){
if(in[i] == '='){
ret--;
} else {
break;
}
}
return ret;
}
int b64_valid_char(char c){
        if (c >= '0' && c <= '9'){
                return 1;
}
        if (c >= 'A' && c <= 'Z'){
                return 1;
}
        if (c >= 'a' && c <= 'z'){
                return 1;
}
        if (c == '+' || c == '/' || c == '='){
                return 1;
}
        return 0;
}
char *b64_encode(const unsigned char *in, size_t len){
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *out;
size_t elen, i, j, v;
if(in == nullptr || len == 0){
return nullptr;
}
elen = b64_encoded_size(len);
out = new char[elen+1];
out[elen] = '\0';
for(i = 0, j = 0; i < len; i += 3, j += 4){
v = in[i];
v = i + 1 < len ? v << 8 | in[i+1] : v << 8;
v = i + 2 < len ? v << 8 | in[i+2] : v << 8;
out[j]     = b64chars[(v >> 18) & 0x3F];
out[j + 1] = b64chars[(v >> 12) & 0x3F];
if(i + 1 < len){
out[j + 2] = b64chars[(v >> 6) & 0x3F];
}else{
out[j + 2] = '=';
}
if(i + 2 < len){
out[j + 3] = b64chars[v & 0x3F];
}else{
out[j + 3] = '=';
}
}
return out;
}

int b64_decode(const char *in, unsigned char *out, size_t outlen){
int b64_t[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
        59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
        6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
        29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
        43, 44, 45, 46, 47, 48, 49, 50, 51 };
size_t len, i, j;
int v;
if(in == nullptr || out == nullptr){
return 0;
}
len = std::string(in).length();
if(outlen < b64_decoded_size(in) || len % 4 != 0){
return 0;
}
for(i = 0; i < len; i++){
if(!b64_valid_char(in[i])){
return 0;
}
}
for(i = 0, j = 0; i < len; i += 4, j += 3){
v = b64_t[in[i] - 43];
v = (v << 6) | b64_t[in[i + 1] - 43];
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64_t[in[i + 2] - 43];
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64_t[in[i + 3] - 43];

out[j] = (v >> 16) & 0xFF;
if(in[i + 2] != '='){
out[j + 1] = (v >> 8 ) & 0xFF;
}
if(in[i + 3] != '='){
out[j + 2] = v & 0xFF;
}
}
return 1;
}
};

class LCipher: public b64{
   private:
int calc(char c, int complex = 0){
int tmp = c, count = 0;
while(1){
if(count++ == (128+complex)){break;}
if(tmp++ == 126){ tmp = 32;}
}
return tmp;

}
int r_calc(char c, int complex = 0){
int tmp = c, count = 128+complex;
while(1){
if(count-- == 0){break;}
if(tmp-- == 32){tmp = 126;}
}
return tmp;
}
std::string LOL(const std::string& message){
std::string final = "";
int tcplx = 0;
for(char c : message){
char tmp = calc(c, ++tcplx);
for(char x : this->password){
tmp ^= x;
}
final += tmp;
}
return final;
}
std::string OLO(const std::string& message){
std::string final = "";
int tcplx = 0;
for(char c : message){
for(char x : this->password){
c ^= x;
}
final += r_calc(c,++tcplx);
}
return final;
}
char *b64_e(const unsigned char* message){
int len = std::string((char *)message).length();
char *out = b64_encode(message, len);
        return out;
}
char *b64_d(const char* message){
size_t outlen = b64_decoded_size(message);
unsigned char *output = new unsigned char[outlen];
b64_decode(message, output, outlen);
return (char *)output;
}
std::string password;
   public:
LCipher(): password("default"){}
        LCipher(std::string p): password(p){}

int Cipher(char*& data, char **output){
char *tmp = b64_e((const unsigned char *)data);
std::string result = LOL(std::string(tmp));
delete tmp;
size_t rlen = result.length();
*output = new char[rlen + 2];
if(*output == nullptr){
return 1;
}
memcpy(*output, result.c_str(), rlen);
*output[rlen-1] = '\0';
return 0;
}
char *UnCipher(const char* data){
std::string tmp = OLO(std::string((char *)data));
char *out = b64_d(tmp.data());
return out;
}
};

int main(int argc, char **argv){
LCipher test(argv[2]);
char *out = nullptr;
test.Cipher(argv[1], &out);
char *out2 = test.UnCipher((const char *)out);
std::cout<<"Original : "<<argv[1]<<'\n';
std::cout<<"Cipher   : "<<out<<'\n';
std::cout<<"UnCipher : "<<out2<<'\n';
delete out;
delete out2;
return 0;
}
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn