[C++] Codificador/Decodificador de Base64

  • 0 Respuestas
  • 6169 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Cervantes_xD

  • *
  • Underc0der
  • Mensajes: 5
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil

[C++] Codificador/Decodificador de Base64

  • en: Julio 06, 2011, 11:17:13 pm
Base64.hpp
Código: C++
  1. #include <iostream>
  2. #include <string>
  3. #include <math.h>
  4. #include <cstdio>
  5. #include <cstdlib>
  6.  
  7. using namespace std;
  8.  
  9. class Base64
  10. {
  11. private:
  12.    static string alfabeto;
  13.    static string TextToBinBase(string a, int b);
  14.    static void Reverse(string &a);
  15.    static void Complete(string &a, int b);
  16. public:
  17.    static string Encode(string a);
  18.    static string Decode(string a);
  19.    static string Binary(int a, int b);
  20.    static int BinToInt(string a);
  21.    static string TextToBin(string a, int b);
  22.  
  23. };

Base64.cpp
Código: C++
  1. #include "Base64.hpp"
  2. #include <sstream>
  3.  
  4. using namespace std;
  5.  
  6. string Base64::alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  7.  
  8. string Base64::Binary(int a, int b)
  9. {
  10.    string result = "";
  11.    while(a != 0)
  12.    {
  13.       if((a%2) == 0)
  14.          result += '0';
  15.       else
  16.          result += '1';
  17.       a = a/2;
  18.    }
  19.  
  20.    Complete(result, b);
  21.    Reverse(result);
  22.    return result;
  23. }
  24.  
  25. string Base64::Encode(string a)
  26. {
  27.    string binario = TextToBin(a, 8);
  28.    stringstream ret;
  29.    string *buffer;
  30.  
  31.    int padding;
  32.    int alt = binario.length()%6;
  33.    int aux;
  34.  
  35.    if(alt == 0)
  36.    {
  37.       int numcadenas = binario.length() / 6;
  38.       buffer = new string[numcadenas];
  39.       if(buffer != NULL)
  40.       {
  41.          for(int i = 0; i < numcadenas; i++)
  42.          {
  43.             buffer[ i ] = binario.substr(i*6, 6);
  44.             aux = BinToInt(buffer[ i ]);
  45.             ret << alfabeto.at(aux);
  46.          }
  47.  
  48.          delete[] buffer;
  49.       }
  50.    }
  51.    else
  52.    {
  53.       padding = (6 - alt) / 2;
  54.       Complete(binario, binario.length() + (6-alt));
  55.       int numcadenas = binario.length() / 6;
  56.       buffer = new string[numcadenas];
  57.       if(buffer != NULL)
  58.       {
  59.          int i;
  60.          for(i = 0; i < numcadenas; i++)
  61.          {
  62.             buffer[ i ] = binario.substr(i*6, 6);
  63.             aux = BinToInt(buffer[ i ]);
  64.             ret << alfabeto.at(aux);
  65.          }
  66.  
  67.          for(i = 0; i < padding; i++)
  68.             ret<<"=";
  69.  
  70.          delete[] buffer;
  71.       }
  72.    }
  73.  
  74.    return ret.str();
  75. }
  76.  
  77. string Base64::Decode(string a)
  78. {
  79.    string binario;
  80.    string cadena;
  81.    stringstream delpadding;
  82.  
  83.    int i;
  84.  
  85.    for(i = 0; i < a.length(); i++)
  86.    {
  87.       if(a.at(i) != '=')
  88.          delpadding<<a.at(i);
  89.    }
  90.  
  91.    cadena = delpadding.str();
  92.    binario = TextToBinBase(cadena, 6);
  93.  
  94.    stringstream ret;
  95.    string *buffer;
  96.  
  97.    int padding;
  98.    int alt = binario.length()/8;
  99.    int aux;
  100.  
  101.    buffer = new string[alt];
  102.  
  103.    if(buffer != NULL)
  104.    {
  105.       for(i = 0; i < alt; i++)
  106.       {
  107.          buffer[ i ] = binario.substr(i*8, 8);
  108.          aux = BinToInt(buffer[ i ]);
  109.          ret << (char)aux;
  110.       }
  111.       cout<<endl;
  112.       delete[] buffer;
  113.    }
  114.  
  115.    return ret.str();
  116. }
  117.  
  118. string Base64::TextToBin(string a, int b)
  119. {
  120.    stringstream c;
  121.    for(int i = 0; i < a.length(); i++)
  122.    {
  123.       c<<Binary((int)a.at(i), b);
  124.    }
  125.    return c.str();
  126. }
  127.  
  128. string Base64::TextToBinBase(string a, int b)
  129. {
  130.    stringstream c;
  131.    for(int i = 0; i < a.length(); i++)
  132.    {
  133.       int pos = (int)alfabeto.find(a.at(i));
  134.       c<<Binary(pos, b);
  135.    }
  136.    return c.str();
  137. }
  138.  
  139. void Base64::Reverse(string& a)
  140. {
  141.    string aux = "";
  142.    for(int i = 0; i < a.length(); i++)
  143.       aux += a.at(a.length() - i - 1);
  144.    a = aux;
  145. }
  146.  
  147. void Base64::Complete(string &a, int b)
  148. {
  149.    if(a.length() < b)
  150.    {
  151.       int fin = b - a.length();
  152.       a.append(fin, '0');
  153.    }
  154. }
  155.  
  156. int Base64::BinToInt(string a)
  157. {
  158.    int aux = 0;
  159.  
  160.    for(int i = 0; i < a.length(); i++)
  161.    {
  162.       if(a.at(i) == '1')
  163.       {
  164.          float ex = a.length() -i -1;
  165.          aux += (int)pow(2, ex);
  166.       }
  167.    }
  168.  
  169.    return aux;
  170. }

Main.cpp
Código: C++
  1. #include "Base64.hpp"
  2.  
  3. /*
  4. Compilación utilizando g++:
  5. g++ Main.cpp Base64.cpp -o base64
  6.  
  7. Uso:
  8. base64 -flag string
  9. Ej:
  10.    base64 -c hola
  11.  
  12. Flags disponibles:
  13.  
  14. -c : Encripta
  15. -d : Desencripta
  16.  
  17. Se pueden encriptar cadenas más grandes a una sola palabra si se coloca todo entre comillas dobles
  18. Ej:
  19.    base64 -c "Encriptando textos con espacios"
  20. */
  21.  
  22. using namespace std;
  23.  
  24. void usage()
  25. {
  26.    cout<<"Usage: "<<endl;
  27.    cout<<"base64 -c string || Crypt a string to a Base64 string"<<endl;
  28.    cout<<"base64 -d string || Decrypt a Base64 string"<<endl;
  29. }
  30.  
  31. int main(int argv, char** args)
  32. {
  33.    if(argv != 3)
  34.    {
  35.       usage();
  36.    }
  37.    else
  38.    {
  39.       string op, str;
  40.       op = args[1];
  41.       str = args[2];
  42.  
  43.       if(op == "-d")
  44.       {
  45.          cout<<Base64::Decode(str)<<endl;
  46.       }
  47.       if(op == "-c")
  48.       {
  49.          cout<<Base64::Encode(str)<<endl;
  50.       }
  51.       if( (op != "-c") && (op != "-d"))
  52.       {
  53.          usage();
  54.       }
  55.    }
  56.    return 0;
  57. }

Generado con el compilador de C++ de Visual C++ Express 2010

El proceso es el siguiente:
Codificación:

1.- Convertir el texto a binario utilizado el valor ASCII de sus caracteres, 8 bits deben salir (si es menos se rellena con ceros) por carácter
2.- Separar en cadenas de 6

Si la última cadena no es de 6 bits, se completa con 0 y a la hora de representar la cadena se añade el caracter = (padding), ¿cuántos? pues un = por cada dos ceros, a la hora de desencriptar no se tienen en cuenta

3.- Cada subcadena de 6 pasarla a entero y el valor que dé se corresponde con una posición en la tabla "alfabeto"

Decodificación:
1.- Convertir el texto a binario utilizado la posición que cada carácter ocupa en la tabla, 6 bits deben salir y no hay que rellenar nada (he ignorado el padding, por lo que su valor no se convierte :B es sólo un "aditivo" a la hora de encriptar)
2.- La longitud de la cadena es múltiplo de 8, así que se divide todo en subcadenas binarias de 8 bits
3.- Convertir cada cadena binaria a entero
4.- Pasar cada entero a ASCII (un simple casting :P)

Voilá! Espero que les sea de utilidad (aunque no lo creo x) )

He usado todo prácticamente estático porque no he visto la necesidad de tener que crear un objeto que lo único que tenga sean algoritmos y nada más sustancial, la ventaja es que obviamente no se necesita crear un objeto de la clase para poder encriptar/desencriptar

Un saludo

P.D: He usados tablas y cosas así, con lo cual hay bastantes cosas entre corchetes, y no sé si alguna de esas ha sido interpretada mal (como los [ i ] para poner la letra en cursiva xD)
Si no funciona me avisan y trato de arreglarlo
« Última modificación: Febrero 08, 2014, 05:47:39 pm por Expermicid »

 

[Código-C++] Decodificador.

Iniciado por JaAViEr

Respuestas: 1
Vistas: 2896
Último mensaje Agosto 10, 2012, 08:35:44 am
por P4|3L0