// A simple string message encryption/decryption
// Date 02:58 28/11/2016
// By Ben a.k.a DreamVB

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

const char* MsgEnterPws = "Please enter your secret password : ";

using namespace std;
using std::cout;
using std::endl;

string StrHex(string src){
	string buffer = "";
	ostringstream os;

	//Convert string of text to hexidecinal string.
	for (string::size_type x = 0; x < src.length(); ++x){
		//Line below converts the src[x] char to hex and also sets width to 2
		os << std::hex << std::setfill('0') << setw(2) << (int)src[x];
	}

	return os.str();
}

string HexToStr(string src){
	string Ret = "";
	int x = 0;

	//Check that string is equal size.
	if (src.length() % 2 != 0){
		return "";
	}
	//Convert hex string to a string
	while (x < src.length()){
		Ret += (char)strtoul(src.substr(x, 2).c_str(), NULL, 16);
		//INC counter
		x += 2;
	}
	return Ret;
}

void Crypt(string src, string password, bool encrypt){
	string crypt = "";
	int i = 0;
	unsigned k = 0;
	char c = 0;
	int KeyLen = password.length();

	crypt = src;

	if (!encrypt){
		crypt = HexToStr(crypt);
	}

	while (i < crypt.length()){
		k = (i%KeyLen);
		crypt[i] = crypt[i] ^ password[k];
		i++;
	}

	if (encrypt){
		cout << StrHex(crypt).c_str();
	}
	else{
		cout << crypt;
	}
	cout << endl;
}


int main(int argc, char *argv[]){
	string message = "";
	char pws[80];
	char op = '\0';
	bool Running = true;

	while (Running){
		system("cls");
		cout << "----Crypt----" << endl;
		cout << "[E] Encrypt String" << endl;
		cout << "[D] Decrypt String" << endl;
		cout << "[A] About..." << endl;
		cout << "[Q] Quit" << endl;
		cout << endl << "Enter choice : ";
		cin >> op;
		op = toupper(op);

		system("cls");

		switch (op){
		case 'E':
			cin.ignore();
			cout << "String to encrypt : ";
			std::getline(cin, message);
			//Get user password
			cout << MsgEnterPws;
			cin >> pws;

			cout << endl << "Your encrypted string:" << endl;
			Crypt(message, pws, true);
			break;
		case 'D':
			cin.ignore();
			cout << "String to decrypt : ";
			std::getline(cin, message);
			//Get user password
			cout << MsgEnterPws;
			cin >> pws;

			cout << endl << "Your decrypted string:" << endl;
			Crypt(message, pws, false);
			break;
		case 'A':
			cout << "About - Message Crypt" << endl << endl;
			cout << "Simple string message encryption/decryption" << endl;
			cout << "Version 1.0\n\tBy DreamVB" << endl;
			break;
		case 'Q':
			cout << "Thanks for trying this program." << endl;
			Running = false;
			break;
		default:
			cout << "Invaild menu option." << endl;
			break;
		}
		system("pause");
	}

	return 0;
}
