Código: Seleccionar todo

//-----------------------------------MAIN.CPP-------------------------------//
#include "Base64.hpp"
 
/*
Compilación utilizando g++:
g++ Main.cpp Base64.cpp -o base64
 
Uso:
base64 -flag string
Ej:
	base64 -c hola
 
Flags disponibles:
 
-c : Encripta
-d : Desencripta
 
Se pueden encriptar cadenas más grandes a una sola palabra si se coloca todo entre comillas dobles
Ej:
	base64 -c "Encriptando textos con espacios"
*/
 
using namespace std;
 
void usage()
{
	cout<<"Usage: "<<endl;
	cout<<"base64 -c string || Crypt a string to a Base64 string"<<endl;
	cout<<"base64 -d string || Decrypt a Base64 string"<<endl;
}
 
int main(int argv, char** args)
{
	if(argv != 3)
	{
		usage();
	}
	else
	{
		string op, str;
		op = args[1];
		str = args[2];
 
		if(op == "-d")
		{
			cout<<Base64::Decode(str)<<endl;
		}
		if(op == "-c")
		{
			cout<<Base64::Encode(str)<<endl;
		}
		if( (op != "-c") && (op != "-d"))
		{
			usage();
		}
	}
	return 0;
}

Código: Seleccionar todo

//-----------------------------------BASE64.HPP-------------------------------//
#include <iostream>
#include <string>
#include <math.h>
#include <cstdio>
#include <cstdlib>
 
using namespace std;
 
class Base64
{
private:
	static string alfabeto;
	static string TextToBinBase(string a, int b);
	static void Reverse(string &a);
	static void Complete(string &a, int b);
public:
	static string Encode(string a);
	static string Decode(string a);
	static string Binary(int a, int b);
	static int BinToInt(string a);
	static string TextToBin(string a, int b);
 
};

Código: Seleccionar todo

//-----------------------------------BASE64.CPP------------------------------------//
#include "Base64.hpp"
#include <sstream>
 
using namespace std;
 
string Base64::alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
string Base64::Binary(int a, int b)
{
	string result = "";
	while(a != 0)
	{
		if((a%2) == 0)
			result += '0';
		else
			result += '1';
		a = a/2;
	}
 
	Complete(result, b);
	Reverse(result);
	return result;
}
 
string Base64::Encode(string a)
{
	string binario = TextToBin(a, 8);
	stringstream ret;
	string *buffer;
 
	int padding;
	int alt = binario.length()%6;
	int aux;
 
	if(alt == 0)
	{
		int numcadenas = binario.length() / 6;
		buffer = new string[numcadenas];
		if(buffer != NULL)
		{
			for(int i = 0; i < numcadenas; i++)
			{
				buffer[i] = binario.substr(i*6, 6);
				aux = BinToInt(buffer[i]);
				ret << alfabeto.at(aux);
			}
 
			delete[] buffer;
		}
	}
	else
	{
		padding = (6 - alt) / 2;
		Complete(binario, binario.length() + (6-alt));
		int numcadenas = binario.length() / 6;
		buffer = new string[numcadenas];
		if(buffer != NULL)
		{
			int i;
			for(i = 0; i < numcadenas; i++)
			{
				buffer[i] = binario.substr(i*6, 6);
				aux = BinToInt(buffer[i]);
				ret << alfabeto.at(aux);
			}
 
			for(i = 0; i < padding; i++)
				ret<<"=";
 
			delete[] buffer;
		}
	}
 
	return ret.str();
}
 
string Base64::Decode(string a)
{
	string binario;
	string cadena;
	stringstream delpadding;
 
	int i;
 
	for(i = 0; i < a.length(); i++)
	{
		if(a.at(i) != '=')
			delpadding<<a.at(i);
	}
 
	cadena = delpadding.str();
	binario = TextToBinBase(cadena, 6);
 
	stringstream ret;
	string *buffer;
 
	int padding;
	int alt = binario.length()/8;
	int aux;
 
	buffer = new string[alt];
 
	if(buffer != NULL)
	{
		for(i = 0; i < alt; i++)
		{
			buffer[i] = binario.substr(i*8, 8);
			aux = BinToInt(buffer[i]);
			ret << (char)aux;
		}
		cout<<endl;
		delete[] buffer;
	}
 
	return ret.str();
}
 
string Base64::TextToBin(string a, int b)
{
	stringstream c;
	for(int i = 0; i < a.length(); i++)
	{
		c<<Binary((int)a.at(i), b);
	}
	return c.str();
}
 
string Base64::TextToBinBase(string a, int b)
{
	stringstream c;
	for(int i = 0; i < a.length(); i++)
	{
		int pos = (int)alfabeto.find(a.at(i));
		c<<Binary(pos, b);
	}
	return c.str();
}
 
void Base64::Reverse(string& a)
{
	string aux = "";
	for(int i = 0; i < a.length(); i++)
		aux += a.at(a.length() - i - 1);
	a = aux;
}
 
void Base64::Complete(string &a, int b)
{
	if(a.length() < b)
	{
		int fin = b - a.length();
		a.append(fin, '0');
	}
}
 
int Base64::BinToInt(string a)
{
	int aux = 0;
 
	for(int i = 0; i < a.length(); i++)
	{
		if(a.at(i) == '1')
		{
			float ex = a.length() -i -1;
			aux += (int)pow(2, ex);
		}
	}
 
	return aux;
}

Progreso:
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
Autór del code : Incoming/Cervantes_xD
Responder

Volver a “Fuentes”