/****************************************************************************** * This filter program encrypts/decrypts text using a Vigenere Cipher. * Input text is taken from standard input and output text is written * to standard output. Assume only ASCII input/output. * * The first command line argument is the password * The second command line argument is the encrypt "e" or decrypt "d" * mode. * * Copyright © 2017 Richard Lesh. All rights reserved. *****************************************************************************/ #undef NDEBUG #include "Utils.hpp" #include #include #include #include std::locale utf8loc(std::locale(), new std::codecvt_utf8); using namespace std; static wstring const ALPHABET = L" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; static int const ALPHABET_LEN = ALPHABET.length(); int shift_char(int cp, int shift, bool encrypt) noexcept { int new_cp = cp; int pos = ALPHABET.find(cp); if (pos != string::npos) { if (encrypt) { pos = (pos + shift) % ALPHABET_LEN; } else { pos = (pos - shift + ALPHABET_LEN) % ALPHABET_LEN; } new_cp = (int)(ALPHABET[pos]); } return new_cp; } int main(int argc, char **argv) { setlocale(LC_ALL, "en_US.UTF-8"); wcout.imbue(utf8loc); wcin.imbue(utf8loc); if (argc != 3) { wcout << L"Syntax: " << Utils::UTF8_to_wstring(argv[0]) << L" password e|d" << endl; exit(1); } wstring password = Utils::UTF8_to_wstring(argv[1]); bool encrypt = (Utils::UTF8_to_wstring(argv[2]) == L"e"); int password_pos = 0; int password_len = password.length(); int c; while ((c = getwchar()) != EOF) { int pwd_cp = (int)(password[password_pos % password_len]); int shift = ALPHABET.find(pwd_cp); if (shift != string::npos) { c = shift_char(c, shift, encrypt); } putwchar(c); ++password_pos; } return 0; }