Help create the vcipher.h and vcipher.cc files for the vigenere cipher which MUST inherit
from substitution and running key cipher(kcipher.h and kcipher.cc). Please follow the
instructions and complete the provided code:
Substitution cipher (implemented in cipher.h and cipher.cc) class has already been defined (but
not implemented) for you. The other cipher classes MUST
a) inherit from the substitution cipher, or
b) inherit from one of the four other cipher classes (e.g., Caesar inherits from Substitution,
ROT13 inherits from Caesar).
4. Each new cipher class MUST have a constructor, a default constructor (except the ROT13
cipher, as described below), and a destructor .
a) Each constructor should accept the input appropriate for the cipher:
i) substitution - cipher alphabet - must contain every letter in the alphabet, and only once, and
they must all be lower case. It should contain no other characters (e.g., no space, punctuation,
etc.). Cipher alphabet length should always be 26.
iv) Running Key - a vector of strings. The vector represents the cipher "book," and each element
in the vector is a "page" from the book. Each page should be a non-empty string. This string
should consist of only lower case letter or spaces.
v) Vigenere - a string representing the key word. The key word should consist of only lower case
letters.
b) Each default constructor should not accept any inputs.
ii) Other ciphers: default constructor should initialize the object so that encrypting any plain text
should return a cipher text that is identical to the plain text. For example, for Caesar, setting the
shift to 0 will achieve this. YOU CANNOT SIMPLY RETURN THE PLAIN TEXT - IT MUST
STILL ENCRYPT THE TEXT using the proper method.
b) the destructor should free all memory. Valgrind will be used to make sure there are no
memory leaks.
5. Each cipher must also provide encrypt and decrypt functions. They can either be implemented
explicitly, or implicitly using inheritance. This is a design decision, but the decision should be
made to minimize/modularize your code.
i) Encrypt: Assume that the input plain text will always be a) lower case letter, b) upper case
letter, or c) a space. Space should not be encrypted (i.e., if the plain text is "hello world", the
encrypted text should look something like "abcde fghij". Upper case letter should be encrypted to
an upper case letter (you don't have to, but you will find that meeting the decrypt requirement
below will be difficult otherwise).
ii) Decrypt: This should take in the encrypted text and return the origin plain text. It should
a) retain the case (i.e., if the input plain text has an upper case letter, the decrypted plain text
should have that letter as upper case.
b) retain the space - If the plain text had spaces, the decrypted text should still have those spaces
in the correct place.
6. Data members in all cipher classes should be hidden using the Cheshire smile.
7. Each cipher should also check to make sure that the provided cipher alphabet, rotation etc.
meets the requirements before initializing the object with it. For example, see the is_valid_alpha
function in cipher.cc for the substitution cipher.
a) For the Running key cipher, each "page" of the book should be a non-empty string. If it is not,
exit with EXIT_FAILURE.
b) When encrypting with Running Key, make sure the key (not counting the spaces) is longer
than or equal to the text you are trying to encrypt (not counting the spaces). If it is not, exit with
EXIT_FAILURE. .
Substitution.cc
#include "cipher.h"
/* Cheshire smile implementation.
It only contains the cipher alphabet
*/
struct Cipher::CipherCheshire {
string cipher_alpha;
};
/* This function checks the cipher alphabet
to make sure it's valid
*/
bool is_valid_alpha(string alpha);
// -------------------------------------------------------
// Cipher implementation
/* Default constructor
This will actually not encrypt the input text
because it's using the unscrambled alphabet
*/
Cipher::Cipher()
{
// TODO: Implement this default constructor
this->smile = new CipherCheshire();
this->smile->cipher_alpha = "abcdefghijklmnopqrstuvwxyz";
}
/* This constructor initiates the object with a
input cipher key
*/
Cipher::Cipher(string cipher_alpha)
{
// TODO: Implement this constructor
if (is_valid_alpha(cipher_alpha)) {
this->smile - new CipherCheshire();
this->smile->cipher_alpha = cipher_alpha;
} else {
cout << "Invalid alpha" << endl;
exit(EXIT_FAILURE);
}
}
/* Destructor
*/
Cipher::~Cipher()
{
// TODO: Implement this constructor
delete this->smile;
}
/* This member function encrypts the input text
using the intialized cipher key
*/
string Cipher::encrypt(string raw)
{
cout << "Encrypting...";
string retStr = "";
int length = raw.length();
int pos;
string alph = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < length; i++) {
if (raw[i] == ' ') {
retStr += ' ';
} else {
pos = find_pos(smile->cipher_alpha, LOWER_CASE(raw[i]));
if (isupper(raw[i])) {
retStr += UPPER_CASE(alph[pos]);
} else {
retStr += alph[pos];
}
}
}
cout << "Done" << endl;
return retStr;
}
/* This member function decrypts the input text
using the intialized cipher key
*/
string Cipher::decrypt(string enc)
{
string retStr;
int length = enc.length();
int pos;
string alph = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < length; i++) {
if (enc[i] == ' ') {
retStr += ' ';
} else {
pos = find_pos(smile->cipher_alpha, LOWER_CASE(enc[i]));
if (isupper(enc[i])) {
retStr += UPPER_CASE(alph[pos]);
} else {
retStr += alph[pos];
}
}
}
cout << "Done" << endl;
return retStr;
}
// -------------------------------------------------------
// Helper functions
/* Find the character c's position in the cipher alphabet/key
*/
unsigned int find_pos(string alpha, char c)
{
unsigned int pos = 0;
int i;
int size = alpha.length();
// TODO: You will likely need this function. Finish it.
char ch = tolower(c);
for (i = 0; i < size; i++) {
if (ch == alpha.at(i)) {
por = i;
break;
}
}
return pos;
}
/* Make sure the cipher alphabet is valid -
a) it must contain every letter in the alphabet
b) it must contain only one of each letter
c) it must be all lower case letters
ALL of the above conditions must be met for the text to be a valid
cipher alphabet.
*/
bool is_valid_alpha(string alpha)
{
bool is_valid = true;
if(alpha.size() != ALPHABET_SIZE) {
is_valid = false;
} else {
unsigned int letter_exists[ALPHABET_SIZE];
for(unsigned int i = 0; i < ALPHABET_SIZE; i++) {
letter_exists[i] = 0;
}
for(unsigned int i = 0; i < alpha.size(); i++) {
char c = alpha[i];
if(!((c >= 'a') && (c <= 'z'))) {
is_valid = false;
} else {
letter_exists[(c - 'a')]++;
}
}
for(unsigned int i = 0; i < ALPHABET_SIZE; i++) {
if(letter_exists[i] != 1) {
is_valid = false;
}
}
}
return is_valid;
}
kcipher.h
kcipher.cc
#include <string>
#include <iostream>
#include <vector>
#include "kcipher.h"
RunningKeyCipher::RunningKeyCipher() : Cipher()
{
book_.clear();
}
RunningKeyCipher::RunningKeyCipher(const vector<string>& book) : Cipher()
{
set_book(book);
}
RunningKeyCipher::~RunningKeyCipher()
{
book_.clear();
}
void RunningKeyCipher::set_book(const vector<string>& book)
{
for (const auto& page : book) {
if (page.empty()) {
cerr << "Invalid book, empty page." << endl;
exit(EXIT_FAILURE);
}
for (char c : page) {
if(!islower(c) && c != ' ') {
cerr << "Invalid book, non-lowercase or space char." << endl;
exit(EXIT_FAILURE);
}
}
}
book_ = book;
}
string RunningKeyCipher::encrypt(string plaintext)
{
string ciphertext;
int book_index = 0;
plaintext = remove_spaces(plaintext);
if (book_.empty()) {
cerr << "No book provided" << endl;
exit(EXIT_FAILURE);
}
for (char c : plaintext) {
if (!islower(c)) {
ciphertext += c;
} else {
int shift = c - 'a' + book_[book_index].at(0) - 'a';
shift %= 26;
ciphertext += smile->cipher_alpha[shift];
++book_index;
if (book_index >= book_.size()) {
book_index = 0;
}
}
}
return ciphertext;
}
string RunningKeyCipher::decrypt(string ciphertext)
{
string plaintext;
int book_index = 0;
ciphertext = remove_spaces(ciphertext);
if (book_.empty()) {
cerr << "No book provided" << endl;
exit(EXIT_FAILURE);
}
for (char c : ciphertext) {
if (!islower(c)) {
plaintext += c;
} else {
int shift = c - book_[book_index].at(0);
if (shift < 0) {
shift += 26;
}
plaintext += smile->cipher_alpha[shift];
++book_index;
if (book_index >= book_.size()) {
book_index = 0;
}
}
}
return plaintext;
}
string RunningKeyCipher::remove_spaces(const string& str)
{
string result;
for (char c : str) {
if (c != ' ') {
result += c;
}
}
return result;
}
COMPLETE THE FOLLOWING SCRIPTS:
vcipher.h
vcipher.cc
#ifndef VCIPHER_H_ #define VCIPHER_H_ //#include "cipher. h" #include "kcipher.h"
using namespace std; /* A class that implements a Vigenere cipher class. It inherts KCipher / //
TOD0: Implement this class #endif #include #include #include

Help create the vcipher-h and vcipher-cc files for the vigenere cipher.pdf

  • 1.
    Help create thevcipher.h and vcipher.cc files for the vigenere cipher which MUST inherit from substitution and running key cipher(kcipher.h and kcipher.cc). Please follow the instructions and complete the provided code: Substitution cipher (implemented in cipher.h and cipher.cc) class has already been defined (but not implemented) for you. The other cipher classes MUST a) inherit from the substitution cipher, or b) inherit from one of the four other cipher classes (e.g., Caesar inherits from Substitution, ROT13 inherits from Caesar). 4. Each new cipher class MUST have a constructor, a default constructor (except the ROT13 cipher, as described below), and a destructor . a) Each constructor should accept the input appropriate for the cipher: i) substitution - cipher alphabet - must contain every letter in the alphabet, and only once, and they must all be lower case. It should contain no other characters (e.g., no space, punctuation, etc.). Cipher alphabet length should always be 26. iv) Running Key - a vector of strings. The vector represents the cipher "book," and each element in the vector is a "page" from the book. Each page should be a non-empty string. This string should consist of only lower case letter or spaces. v) Vigenere - a string representing the key word. The key word should consist of only lower case letters. b) Each default constructor should not accept any inputs. ii) Other ciphers: default constructor should initialize the object so that encrypting any plain text should return a cipher text that is identical to the plain text. For example, for Caesar, setting the shift to 0 will achieve this. YOU CANNOT SIMPLY RETURN THE PLAIN TEXT - IT MUST STILL ENCRYPT THE TEXT using the proper method. b) the destructor should free all memory. Valgrind will be used to make sure there are no memory leaks. 5. Each cipher must also provide encrypt and decrypt functions. They can either be implemented explicitly, or implicitly using inheritance. This is a design decision, but the decision should be made to minimize/modularize your code. i) Encrypt: Assume that the input plain text will always be a) lower case letter, b) upper case letter, or c) a space. Space should not be encrypted (i.e., if the plain text is "hello world", the encrypted text should look something like "abcde fghij". Upper case letter should be encrypted to
  • 2.
    an upper caseletter (you don't have to, but you will find that meeting the decrypt requirement below will be difficult otherwise). ii) Decrypt: This should take in the encrypted text and return the origin plain text. It should a) retain the case (i.e., if the input plain text has an upper case letter, the decrypted plain text should have that letter as upper case. b) retain the space - If the plain text had spaces, the decrypted text should still have those spaces in the correct place. 6. Data members in all cipher classes should be hidden using the Cheshire smile. 7. Each cipher should also check to make sure that the provided cipher alphabet, rotation etc. meets the requirements before initializing the object with it. For example, see the is_valid_alpha function in cipher.cc for the substitution cipher. a) For the Running key cipher, each "page" of the book should be a non-empty string. If it is not, exit with EXIT_FAILURE. b) When encrypting with Running Key, make sure the key (not counting the spaces) is longer than or equal to the text you are trying to encrypt (not counting the spaces). If it is not, exit with EXIT_FAILURE. . Substitution.cc #include "cipher.h" /* Cheshire smile implementation. It only contains the cipher alphabet */ struct Cipher::CipherCheshire { string cipher_alpha; }; /* This function checks the cipher alphabet to make sure it's valid */ bool is_valid_alpha(string alpha); // ------------------------------------------------------- // Cipher implementation /* Default constructor This will actually not encrypt the input text because it's using the unscrambled alphabet
  • 3.
    */ Cipher::Cipher() { // TODO: Implementthis default constructor this->smile = new CipherCheshire(); this->smile->cipher_alpha = "abcdefghijklmnopqrstuvwxyz"; } /* This constructor initiates the object with a input cipher key */ Cipher::Cipher(string cipher_alpha) { // TODO: Implement this constructor if (is_valid_alpha(cipher_alpha)) { this->smile - new CipherCheshire(); this->smile->cipher_alpha = cipher_alpha; } else { cout << "Invalid alpha" << endl; exit(EXIT_FAILURE); } } /* Destructor */ Cipher::~Cipher() { // TODO: Implement this constructor delete this->smile; } /* This member function encrypts the input text using the intialized cipher key */ string Cipher::encrypt(string raw) { cout << "Encrypting..."; string retStr = ""; int length = raw.length(); int pos; string alph = "abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < length; i++) { if (raw[i] == ' ') { retStr += ' '; } else {
  • 4.
    pos = find_pos(smile->cipher_alpha,LOWER_CASE(raw[i])); if (isupper(raw[i])) { retStr += UPPER_CASE(alph[pos]); } else { retStr += alph[pos]; } } } cout << "Done" << endl; return retStr; } /* This member function decrypts the input text using the intialized cipher key */ string Cipher::decrypt(string enc) { string retStr; int length = enc.length(); int pos; string alph = "abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < length; i++) { if (enc[i] == ' ') { retStr += ' '; } else { pos = find_pos(smile->cipher_alpha, LOWER_CASE(enc[i])); if (isupper(enc[i])) { retStr += UPPER_CASE(alph[pos]); } else { retStr += alph[pos]; } } } cout << "Done" << endl; return retStr; } // -------------------------------------------------------
  • 5.
    // Helper functions /*Find the character c's position in the cipher alphabet/key */ unsigned int find_pos(string alpha, char c) { unsigned int pos = 0; int i; int size = alpha.length(); // TODO: You will likely need this function. Finish it. char ch = tolower(c); for (i = 0; i < size; i++) { if (ch == alpha.at(i)) { por = i; break; } } return pos; } /* Make sure the cipher alphabet is valid - a) it must contain every letter in the alphabet b) it must contain only one of each letter c) it must be all lower case letters ALL of the above conditions must be met for the text to be a valid cipher alphabet. */ bool is_valid_alpha(string alpha) { bool is_valid = true; if(alpha.size() != ALPHABET_SIZE) { is_valid = false; } else { unsigned int letter_exists[ALPHABET_SIZE]; for(unsigned int i = 0; i < ALPHABET_SIZE; i++) { letter_exists[i] = 0; } for(unsigned int i = 0; i < alpha.size(); i++) { char c = alpha[i]; if(!((c >= 'a') && (c <= 'z'))) { is_valid = false; } else { letter_exists[(c - 'a')]++; }
  • 6.
    } for(unsigned int i= 0; i < ALPHABET_SIZE; i++) { if(letter_exists[i] != 1) { is_valid = false; } } } return is_valid; } kcipher.h kcipher.cc #include <string> #include <iostream> #include <vector> #include "kcipher.h" RunningKeyCipher::RunningKeyCipher() : Cipher() { book_.clear(); } RunningKeyCipher::RunningKeyCipher(const vector<string>& book) : Cipher() { set_book(book); } RunningKeyCipher::~RunningKeyCipher() { book_.clear(); }
  • 7.
    void RunningKeyCipher::set_book(const vector<string>&book) { for (const auto& page : book) { if (page.empty()) { cerr << "Invalid book, empty page." << endl; exit(EXIT_FAILURE); } for (char c : page) { if(!islower(c) && c != ' ') { cerr << "Invalid book, non-lowercase or space char." << endl; exit(EXIT_FAILURE); } } } book_ = book; } string RunningKeyCipher::encrypt(string plaintext) { string ciphertext; int book_index = 0; plaintext = remove_spaces(plaintext); if (book_.empty()) { cerr << "No book provided" << endl;
  • 8.
    exit(EXIT_FAILURE); } for (char c: plaintext) { if (!islower(c)) { ciphertext += c; } else { int shift = c - 'a' + book_[book_index].at(0) - 'a'; shift %= 26; ciphertext += smile->cipher_alpha[shift]; ++book_index; if (book_index >= book_.size()) { book_index = 0; } } } return ciphertext; } string RunningKeyCipher::decrypt(string ciphertext) { string plaintext; int book_index = 0; ciphertext = remove_spaces(ciphertext); if (book_.empty()) {
  • 9.
    cerr << "Nobook provided" << endl; exit(EXIT_FAILURE); } for (char c : ciphertext) { if (!islower(c)) { plaintext += c; } else { int shift = c - book_[book_index].at(0); if (shift < 0) { shift += 26; } plaintext += smile->cipher_alpha[shift]; ++book_index; if (book_index >= book_.size()) { book_index = 0; } } } return plaintext; } string RunningKeyCipher::remove_spaces(const string& str) { string result;
  • 10.
    for (char c: str) { if (c != ' ') { result += c; } } return result; } COMPLETE THE FOLLOWING SCRIPTS: vcipher.h vcipher.cc #ifndef VCIPHER_H_ #define VCIPHER_H_ //#include "cipher. h" #include "kcipher.h" using namespace std; /* A class that implements a Vigenere cipher class. It inherts KCipher / // TOD0: Implement this class #endif #include #include #include