#include <iostream>
#include <string>
#include <cassert>
using namespace std;

string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int toOrdinal(const char& c) {
	auto ord = alphabet.find(c);
	assert(ord != string::npos);
	return ord;
}
char fromOrdinal(int n) {
	assert(n < alphabet.length() );
	return alphabet[n];
}

string cryptVigenere(const string& input, const string&  key, bool encrypt = true) {
	string res;
	for(size_t i = 0; i < input.size(); ++i) {
		auto ordInput = toOrdinal( input[i] );
		auto ordKey   = toOrdinal( key[i % key.size()] ) ;
		auto result   = ordInput + ordKey * (encrypt ? 1 : -1);
		res += fromOrdinal( (result + alphabet.size()) % alphabet.size() ); 
	}
	return res;
}

int main() {
	auto encryptedText = cryptVigenere("THECAKEISALIE", "GLADOS");
	cout << encryptedText << "\n";
	cout << cryptVigenere(encryptedText, "GLADOS", false) << "\n";
}