#include <algorithm>
#include <cctype>
#include <string>
#include <iostream>
struct CaesarCipher {
std::string alphabet;
int shift;
CaesarCipher(std::string alphabet, int sh) : alphabet(alphabet) {
shift = std::abs(sh) % alphabet.length();
if (sh < 0) shift = alphabet.length() - shift;
}
//Encrypts one character
char operator() (char c) {
int index = alphabet.find(c);
if (index != std::string::npos)
return alphabet[(index + shift) % alphabet.length()];
else return c;
}
};
//Encrypts a container using given alphabet
template <typename InputIterator, typename OutputIterator>
OutputIterator generic_caesar_cipher(
InputIterator src_begin, InputIterator src_end, OutputIterator dest_begin,
std::string alphabet, int shift)
{
return std::transform(src_begin, src_end, dest_begin, CaesarCipher(alphabet, shift));
}
//Encrypts a container using the lowercase latin alphabet
template <typename InputIterator, typename OutputIterator>
OutputIterator caesar_cipher(
InputIterator src_begin, InputIterator src_end, OutputIterator dest_begin,
int shift)
{
return generic_caesar_cipher(src_begin, src_end, dest_begin, "abcdefghijklmnopqrstuvwxyz", shift);
}
int main() {
std::string s = "wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj";
caesar_cipher(s.begin(), s.end(), s.begin(), -3);
std::cout << s << std::endl;
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGNjdHlwZT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IENhZXNhckNpcGhlciB7CiAgICBzdGQ6OnN0cmluZyBhbHBoYWJldDsKICAgIGludCBzaGlmdDsKICAgIAogICAgQ2Flc2FyQ2lwaGVyKHN0ZDo6c3RyaW5nIGFscGhhYmV0LCBpbnQgc2gpIDogYWxwaGFiZXQoYWxwaGFiZXQpIHsKICAgICAgICBzaGlmdCA9IHN0ZDo6YWJzKHNoKSAlIGFscGhhYmV0Lmxlbmd0aCgpOwogICAgICAgIGlmIChzaCA8IDApIHNoaWZ0ID0gYWxwaGFiZXQubGVuZ3RoKCkgLSBzaGlmdDsKICAgIH0KICAgIAogICAgLy9FbmNyeXB0cyBvbmUgY2hhcmFjdGVyCiAgICBjaGFyIG9wZXJhdG9yKCkgKGNoYXIgYykgewogICAgICAgIGludCBpbmRleCA9IGFscGhhYmV0LmZpbmQoYyk7CiAgICAgICAgaWYgKGluZGV4ICE9IHN0ZDo6c3RyaW5nOjpucG9zKQogICAgICAgICAgIHJldHVybiBhbHBoYWJldFsoaW5kZXggKyBzaGlmdCkgJSBhbHBoYWJldC5sZW5ndGgoKV07CiAgICAgICAgZWxzZSByZXR1cm4gYzsKICAgIH0KfTsKCi8vRW5jcnlwdHMgYSBjb250YWluZXIgdXNpbmcgZ2l2ZW4gYWxwaGFiZXQKdGVtcGxhdGUgPHR5cGVuYW1lIElucHV0SXRlcmF0b3IsIHR5cGVuYW1lIE91dHB1dEl0ZXJhdG9yPgpPdXRwdXRJdGVyYXRvciBnZW5lcmljX2NhZXNhcl9jaXBoZXIoCiAgICBJbnB1dEl0ZXJhdG9yIHNyY19iZWdpbiwgSW5wdXRJdGVyYXRvciBzcmNfZW5kLCBPdXRwdXRJdGVyYXRvciBkZXN0X2JlZ2luLAogICAgc3RkOjpzdHJpbmcgYWxwaGFiZXQsIGludCBzaGlmdCkKewogICAgcmV0dXJuIHN0ZDo6dHJhbnNmb3JtKHNyY19iZWdpbiwgc3JjX2VuZCwgZGVzdF9iZWdpbiwgQ2Flc2FyQ2lwaGVyKGFscGhhYmV0LCBzaGlmdCkpOwp9CgovL0VuY3J5cHRzIGEgY29udGFpbmVyIHVzaW5nIHRoZSBsb3dlcmNhc2UgbGF0aW4gYWxwaGFiZXQKdGVtcGxhdGUgPHR5cGVuYW1lIElucHV0SXRlcmF0b3IsIHR5cGVuYW1lIE91dHB1dEl0ZXJhdG9yPgpPdXRwdXRJdGVyYXRvciBjYWVzYXJfY2lwaGVyKAogICAgSW5wdXRJdGVyYXRvciBzcmNfYmVnaW4sIElucHV0SXRlcmF0b3Igc3JjX2VuZCwgT3V0cHV0SXRlcmF0b3IgZGVzdF9iZWdpbiwKICAgIGludCBzaGlmdCkKewogICAgcmV0dXJuIGdlbmVyaWNfY2Flc2FyX2NpcGhlcihzcmNfYmVnaW4sIHNyY19lbmQsIGRlc3RfYmVnaW4sICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIsIHNoaWZ0KTsKfQoKaW50IG1haW4oKSB7CiAgICBzdGQ6OnN0cmluZyBzID0gIndraCB0eGxmbiBldXJ6cSBpcmEgbXhwc3YgcnlodSB3a2ggb2RjYiBncmoiOwoKICAgIGNhZXNhcl9jaXBoZXIocy5iZWdpbigpLCBzLmVuZCgpLCBzLmJlZ2luKCksIC0zKTsKICAgIHN0ZDo6Y291dCA8PCBzIDw8IHN0ZDo6ZW5kbDsKfQ==