#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";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8Y2Fzc2VydD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cmluZyBhbHBoYWJldCA9ICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiI7CmludCB0b09yZGluYWwoY29uc3QgY2hhciYgYykgewoJYXV0byBvcmQgPSBhbHBoYWJldC5maW5kKGMpOwoJYXNzZXJ0KG9yZCAhPSBzdHJpbmc6Om5wb3MpOwoJcmV0dXJuIG9yZDsKfQpjaGFyIGZyb21PcmRpbmFsKGludCBuKSB7Cglhc3NlcnQobiA8IGFscGhhYmV0Lmxlbmd0aCgpICk7CglyZXR1cm4gYWxwaGFiZXRbbl07Cn0KCnN0cmluZyBjcnlwdFZpZ2VuZXJlKGNvbnN0IHN0cmluZyYgaW5wdXQsIGNvbnN0IHN0cmluZyYgIGtleSwgYm9vbCBlbmNyeXB0ID0gdHJ1ZSkgewoJc3RyaW5nIHJlczsKCWZvcihzaXplX3QgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7ICsraSkgewoJCWF1dG8gb3JkSW5wdXQgPSB0b09yZGluYWwoIGlucHV0W2ldICk7CgkJYXV0byBvcmRLZXkgICA9IHRvT3JkaW5hbCgga2V5W2kgJSBrZXkuc2l6ZSgpXSApIDsKCQlhdXRvIHJlc3VsdCAgID0gb3JkSW5wdXQgKyBvcmRLZXkgKiAoZW5jcnlwdCA/IDEgOiAtMSk7CgkJcmVzICs9IGZyb21PcmRpbmFsKCAocmVzdWx0ICsgYWxwaGFiZXQuc2l6ZSgpKSAlIGFscGhhYmV0LnNpemUoKSApOyAKCX0KCXJldHVybiByZXM7Cn0KCmludCBtYWluKCkgewoJYXV0byBlbmNyeXB0ZWRUZXh0ID0gY3J5cHRWaWdlbmVyZSgiVEhFQ0FLRUlTQUxJRSIsICJHTEFET1MiKTsKCWNvdXQgPDwgZW5jcnlwdGVkVGV4dCA8PCAiXG4iOwoJY291dCA8PCBjcnlwdFZpZ2VuZXJlKGVuY3J5cHRlZFRleHQsICJHTEFET1MiLCBmYWxzZSkgPDwgIlxuIjsKfQ==