Update columnar-transposition example
+ Use inheritance to provide base class for key based ciphers
This commit is contained in:
parent
b5a97de9ff
commit
58adbfc473
|
@ -4,6 +4,7 @@
|
||||||
shaunrd0/klips/cpp/
|
shaunrd0/klips/cpp/
|
||||||
├── algorithms # Examples of various algorithms written in C++
|
├── algorithms # Examples of various algorithms written in C++
|
||||||
├── cmake # Example of using cmake to build and organize larger projects
|
├── cmake # Example of using cmake to build and organize larger projects
|
||||||
|
├── cryptography# Examples of encrypting / decrypting using ciphers in C++
|
||||||
├── datastructs # Collection of useful datastructures written in C++
|
├── datastructs # Collection of useful datastructures written in C++
|
||||||
├── graphics # Examples of graphics projects written in C++
|
├── graphics # Examples of graphics projects written in C++
|
||||||
├── patterns # Examples of various design patterns written in C++
|
├── patterns # Examples of various design patterns written in C++
|
||||||
|
|
|
@ -27,10 +27,10 @@ int main (const int argc, const char * argv[]) {
|
||||||
|
|
||||||
// Using example keyword from www.braingle.com
|
// Using example keyword from www.braingle.com
|
||||||
// + The embedded example there doesn't seem to support numbers in keywords :(
|
// + The embedded example there doesn't seem to support numbers in keywords :(
|
||||||
CipherData cData("ZEBRAS");
|
Columnar cData("ZEBRAS");
|
||||||
|
|
||||||
// Taking user input for keyword using CipherData ctor
|
// Taking user input for keyword using Columnar ctor
|
||||||
// CipherData cData;
|
// Columnar cData;
|
||||||
|
|
||||||
int choice = 0;
|
int choice = 0;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
|
|
||||||
#include "lib-cipher.hpp"
|
#include "lib-cipher.hpp"
|
||||||
|
|
||||||
// Initializes orderVect to determine order columns should be used
|
KeyData::~KeyData() {}
|
||||||
void CipherData::InitOrder(std::string temp)
|
|
||||||
|
void Columnar::InitOrder(std::string temp)
|
||||||
{
|
{
|
||||||
// Create a temp value sorted lexicographically, remove duplicate characters
|
// Create a temp value sorted lexicographically, remove duplicate characters
|
||||||
// https://en.cppreference.com/w/cpp/string/basic_string/operator_cmp
|
// https://en.cppreference.com/w/cpp/string/basic_string/operator_cmp
|
||||||
|
@ -32,38 +33,8 @@ void CipherData::InitOrder(std::string temp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows getting keyWord when using CipherData default ctor
|
void Columnar::ValidateKeyword(const std::string &message)
|
||||||
std::string CipherData::GetKey()
|
|
||||||
{
|
{
|
||||||
std::string key;
|
|
||||||
std::cout << "Enter the keyword: ";
|
|
||||||
std::getline(std::cin, key);
|
|
||||||
std::cout << "Keyword entered: \"" << key << "\"\n";
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transpose a character matrix, using a vector of strings
|
|
||||||
void CipherData::Transpose(const std::vector<std::string> &in,
|
|
||||||
std::vector<std::string> &out)
|
|
||||||
{
|
|
||||||
int cols = in[0].size();
|
|
||||||
// JIC some other row is larger than the first
|
|
||||||
for (const auto &row : in) cols = (row.size() > cols) ? row.size() : cols;
|
|
||||||
int rows = in.size();
|
|
||||||
|
|
||||||
out.resize(cols);
|
|
||||||
|
|
||||||
for (int i = 0; i < cols; i++) {
|
|
||||||
for (int j = 0; j < rows; j++) {
|
|
||||||
if (in[j].size() <= i) continue;
|
|
||||||
out[i] += in[j][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CipherData::ValidateKeyword(const std::string &message)
|
|
||||||
{
|
|
||||||
if (keyWord_.size() < message.size()) return;
|
|
||||||
// Pop letters from keyWord until it is < message.size()
|
// Pop letters from keyWord until it is < message.size()
|
||||||
while (keyWord_.size() >= message.size()) keyWord_.pop_back();
|
while (keyWord_.size() >= message.size()) keyWord_.pop_back();
|
||||||
// Do not append order to a previous orderVect; Erase it first
|
// Do not append order to a previous orderVect; Erase it first
|
||||||
|
@ -72,7 +43,25 @@ void CipherData::ValidateKeyword(const std::string &message)
|
||||||
InitOrder(keyWord_);
|
InitOrder(keyWord_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CipherData::Encrypt(std::string message)
|
void Columnar::Transpose(const std::vector<std::string> &in,
|
||||||
|
std::vector<std::string> &out)
|
||||||
|
{
|
||||||
|
size_t cols = in[0].size();
|
||||||
|
// JIC some other row is larger than the first
|
||||||
|
for (const auto &row : in) cols = (row.size() > cols) ? row.size() : cols;
|
||||||
|
size_t rows = in.size();
|
||||||
|
|
||||||
|
out.resize(cols);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cols; i++) {
|
||||||
|
for (size_t j = 0; j < rows; j++) {
|
||||||
|
if (in[j].size() <= i) continue;
|
||||||
|
out[i] += in[j][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Columnar::Encrypt(std::string message)
|
||||||
{
|
{
|
||||||
// If no message was provided, ask for one
|
// If no message was provided, ask for one
|
||||||
if (message.empty()) {
|
if (message.empty()) {
|
||||||
|
@ -80,7 +69,7 @@ std::string CipherData::Encrypt(std::string message)
|
||||||
std::getline(std::cin, message);
|
std::getline(std::cin, message);
|
||||||
std::cout << "Encrypting message \"" << message << "\"\n";
|
std::cout << "Encrypting message \"" << message << "\"\n";
|
||||||
}
|
}
|
||||||
ValidateKeyword(message);
|
if (keyWord_.size() >= message.size()) ValidateKeyword(message);
|
||||||
std::string encryptedMessage;
|
std::string encryptedMessage;
|
||||||
std::vector<std::string> rows;
|
std::vector<std::string> rows;
|
||||||
|
|
||||||
|
@ -99,7 +88,7 @@ std::string CipherData::Encrypt(std::string message)
|
||||||
return encryptedMessage;
|
return encryptedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CipherData::Decrypt(std::string message)
|
std::string Columnar::Decrypt(std::string message)
|
||||||
{
|
{
|
||||||
// If no message was provided, ask for one
|
// If no message was provided, ask for one
|
||||||
if (message.empty()) {
|
if (message.empty()) {
|
||||||
|
@ -107,7 +96,7 @@ std::string CipherData::Decrypt(std::string message)
|
||||||
std::getline(std::cin, message);
|
std::getline(std::cin, message);
|
||||||
std::cout << "Decrypting message \"" << message << "\"\n";
|
std::cout << "Decrypting message \"" << message << "\"\n";
|
||||||
}
|
}
|
||||||
ValidateKeyword(message);
|
if (keyWord_.size() >= message.size()) ValidateKeyword(message);
|
||||||
std::string decryptedMessage;
|
std::string decryptedMessage;
|
||||||
std::vector<std::string> rows;
|
std::vector<std::string> rows;
|
||||||
|
|
||||||
|
|
|
@ -16,37 +16,58 @@
|
||||||
#include<vector>
|
#include<vector>
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// CipherData struct to hold data and methods related to encrypting / decrypting
|
// KeyData struct to hold data related to key ciphers
|
||||||
struct CipherData {
|
struct KeyData {
|
||||||
|
explicit KeyData(std::string key) : keyWord_(std::move(key)) {};
|
||||||
|
explicit KeyData() : keyWord_(GetKey()) {};
|
||||||
|
// Pure virtual dtor to make abstract class despite no pure virtual members
|
||||||
|
virtual ~KeyData() = 0;
|
||||||
|
|
||||||
|
// Allows getting keyWord when using KeyData default ctor
|
||||||
|
static std::string GetKey()
|
||||||
|
{
|
||||||
|
std::string key;
|
||||||
|
std::cout << "Enter the keyword: ";
|
||||||
|
std::getline(std::cin, key);
|
||||||
|
std::cout << "Keyword entered: \"" << key << "\"\n";
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string keyWord_;
|
||||||
|
};
|
||||||
|
// Definition of pure virtual dtor
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
// Columnar struct to define methods related to columnar transposition
|
||||||
|
struct Columnar : KeyData {
|
||||||
// Can't create this object without providing a keyWord to initialize order
|
// Can't create this object without providing a keyWord to initialize order
|
||||||
explicit CipherData(std::string keyWord) : keyWord_(std::move(keyWord))
|
explicit Columnar(std::string keyWord) : KeyData(std::move(keyWord))
|
||||||
{
|
{
|
||||||
InitOrder(keyWord_);
|
InitOrder(keyWord_);
|
||||||
}
|
}
|
||||||
CipherData() : keyWord_(GetKey()) { InitOrder(keyWord_);}
|
// Inherit call to GetKey() from KeyData default ctor
|
||||||
|
Columnar() { InitOrder(keyWord_);}
|
||||||
|
|
||||||
/****************************************************************************/
|
// Initializes orderVect to determine order columns should be used
|
||||||
// Member functions
|
|
||||||
|
|
||||||
// Initializes orderVect, pass by value to create local copy of keyWord
|
|
||||||
void InitOrder(std::string temp);
|
void InitOrder(std::string temp);
|
||||||
|
|
||||||
static std::string GetKey();
|
|
||||||
|
|
||||||
static void
|
/****************************************************************************/
|
||||||
Transpose(const std::vector<std::string> &in, std::vector<std::string> &out);
|
// Member function definitions
|
||||||
|
|
||||||
// Default values for param allows calling with no message
|
void ValidateKeyword(const std::string &message);
|
||||||
|
|
||||||
|
// Transpose a character matrix, using a vector of strings
|
||||||
|
static void Transpose(const std::vector<std::string> &in,
|
||||||
|
std::vector<std::string> &out);
|
||||||
|
|
||||||
|
// Default parameter allows calling Encrypt() to take message input
|
||||||
std::string Encrypt(std::string message="");
|
std::string Encrypt(std::string message="");
|
||||||
|
// Default parameter allows calling Decrypt() to take message input
|
||||||
std::string Decrypt(std::string message="");
|
std::string Decrypt(std::string message="");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Used to make a valid keyword from an invalid keyWord
|
|
||||||
// + Still encrypts / decrypts with whatever the user inputs as keyWord
|
|
||||||
// + But technically the keyword is modified without the user knowing :)
|
|
||||||
void ValidateKeyword(const std::string &message);
|
|
||||||
|
|
||||||
std::string keyWord_;
|
|
||||||
std::vector<int> orderVect_;
|
std::vector<int> orderVect_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue