In: Computer Science
Please do it in C++.
Please comment on the code, and comments detail the run time in terms of total operations and Big O complexities.
1. Implement a class, SubstitutionCipher, with a constructor that takes a string with the 26 uppercase letters in an arbitrary order and uses that as the encoder for a cipher (that is, A is mapped to the first character of the parameter, B is mapped to the second, and so on.) Please derive the decoding map from the forward version.
2. Redesign the CaesarCipher class as a subclass of the SubstitutionCipher from the previous problem.
3. Design a RandomCipher class as a subclass of the SubstitutionCipher from number one so that each instance of the class relies on a random permutation of letters for its mapping.
part-1
SubstitutionCipher.h
#include <string>
#include <vector>
#include <iostream>
#include <cctype>
class SubstitutionCipher
{
public:
static constexpr int MAX = 26;
protected:
std::vector<wchar_t> encoder; // Encryption array
std::vector<wchar_t> decoder; // Decryption array
/**
* Constructor
*/
public:
SubstitutionCipher();
/**
* Sets the encoder string and generates the decoder
* @param encoderString
*/
virtual void setEncoder(const std::wstring &encoderString);
/**
* Returns String representing encrypted message.
*/
virtual std::wstring encrypt(const std::wstring &message);
/**
* Returns decrypted message given encrypted secret.
*/
virtual std::wstring decrypt(const std::wstring &secret);
/**
* Returns transformation of original String using given code.
*/
private:
std::wstring transform(const std::wstring &original,
std::vector<wchar_t> &code);
public:
static void main(std::vector<std::wstring> &args);
};
SubstitutionCipher.cpp
#include "SubstitutionCipher.h"
SubstitutionCipher::SubstitutionCipher()
{
this->encoder = std::vector<wchar_t>(MAX); //
Encryption array
this->decoder = std::vector<wchar_t>(MAX); //
Decryption array
}
void SubstitutionCipher::setEncoder(const std::wstring
&encoderString)
{
this->encoder =
std::vector<wchar_t>(encoderString.begin(),
encoderString.end());
// Generate decoder
for (int i = 0; i < MAX; i++)
{
wchar_t ch =
static_cast<wchar_t>(L'A' + i); // For each iteration ch will
hold a value from A - Z
// Find ch in the
encoderString
int pos =
(int)encoderString.find(ch);
// If pos is not found display
error
if (pos == -1)
{
std::wcout
<< L"Invalid encoder string" << std::endl;
exit(1);
}
// If index is found
// get the char at the pos in the
original alphabet order
// assign the char to
decoder[i]
this->decoder[i] =
static_cast<wchar_t>(L'A' + pos);
}
}
std::wstring SubstitutionCipher::encrypt(const std::wstring
&message)
{
return transform(message, encoder); // use encoder
array
}
std::wstring SubstitutionCipher::decrypt(const std::wstring
&secret)
{
return transform(secret, decoder); // use decoder
array
}
std::wstring SubstitutionCipher::transform(const std::wstring
&original, std::vector<wchar_t> &code)
{
std::vector<wchar_t> msg(original.begin(),
original.end());
for (int k = 0; k < msg.size(); k++)
{
if (std::isupper(msg[k]))
{ // we have a letter to
change
int j = msg[k] -
L'A'; // will be value from 0 to 25
msg[k] =
code[j]; // replace the character
}
}
return std::wstring(msg);
}
void SubstitutionCipher::main(std::vector<std::wstring>
&args)
{
std::wstring encoderString = std::wstring(L"SIEXHVGFUDJTRZNPCLQBKAYWOM");
// Create SubstitutionCipher object
SubstitutionCipher *subCipher = new
SubstitutionCipher();
// Set encoder
subCipher->setEncoder(encoderString);
std::wcout << L"Encryption code = " <<
std::wstring(subCipher->encoder) << std::endl;
std::wcout << L"Decryption code = " <<
std::wstring(subCipher->decoder) << std::endl;
std::wstring message = L"THE EAGLE IS IN PLAY; MEET AT
JOE'S.";
std::wstring coded =
subCipher->encrypt(message);
std::wcout << L"Secret: " << coded
<< std::endl;
std::wstring answer =
subCipher->decrypt(coded);
std::wcout << L"Message: " << answer
<< std::endl;
delete subCipher;
}
substitutioncipher_main.cpp
#include <string>
#include <vector>
#include "SubstitutionCipher.h"
int main(int argc, char **argv)
{
std::vector<std::wstring> args(argv + 1, argv + argc);
SubstitutionCipher::main(args);
}
Part 2
CaesarCipherRedesign.h
#include "SubstitutionCipher.h"
#include <string>
#include <vector>
#include <iostream>
class CaesarCipherRedesign : public SubstitutionCipher
{
/**
* Constructor that initializes the encryption and decryption
arrays
*/
public:
CaesarCipherRedesign(int rotation);
static void main(std::vector<std::wstring>
&args);
};
CaesarCipherRedesign.cpp
#include "CaesarCipherRedesign.h"
CaesarCipherRedesign::CaesarCipherRedesign(int rotation)
{
// For upper case
for (int k = 0; k < 26; k++)
{
encoder[k] =
static_cast<wchar_t>(L'A' + (k + rotation) %
SubstitutionCipher::MAX);
}
}
void CaesarCipherRedesign::main(std::vector<std::wstring>
&args)
{
CaesarCipher *cipher = new CaesarCipher(1);
std::wcout << L"Encryption code = " <<
std::wstring(cipher->encoder) << std::endl;
std::wcout << L"Decryption code = " <<
std::wstring(cipher->decoder) << std::endl;
std::wstring message = L"THE EAGLE IS IN PLAY; MEET AT
JOE'S.";
std::wstring coded =
cipher->encrypt(message);
std::wcout << L"Secret: " << coded
<< std::endl;
std::wstring answer = cipher->decrypt(coded);
std::wcout << L"Message: " << answer
<< std::endl; // should be plain text again
delete cipher;
}