Add subdirectory for cryptography examples
+ Add example using columnar transposition for encrypting / decrypting messages + Fix cmake build error from duplicate lib-bst when building from project root
This commit is contained in:
parent
23c4f0e491
commit
c8683680dd
|
@ -19,6 +19,7 @@ project(
|
|||
|
||||
add_subdirectory(algorithms)
|
||||
add_subdirectory(cmake)
|
||||
add_subdirectory(cryptography)
|
||||
add_subdirectory(datastructs)
|
||||
add_subdirectory(graphics)
|
||||
add_subdirectory(patterns)
|
||||
|
|
|
@ -15,7 +15,7 @@ project (
|
|||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
add_library(lib-bst "bst.cpp")
|
||||
add_library(lib-bst-algo "bst.cpp")
|
||||
|
||||
add_executable(test-bst "driver.cpp")
|
||||
target_link_libraries(test-bst lib-bst)
|
||||
add_executable(test-bst-algo "driver.cpp")
|
||||
target_link_libraries(test-bst-algo lib-bst)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
###############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||||
## About: A root project for practicing cryptography in C++ ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project (
|
||||
#[[NAME]] Cryptography
|
||||
VERSION 1.0
|
||||
DESCRIPTION "A project for practicing cryptography in C++"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
add_subdirectory(columnar-transposition)
|
|
@ -0,0 +1,22 @@
|
|||
################################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||||
## About: A root project for practicing columnar transposition cipher in C++ ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
################################################################################
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(
|
||||
#[[NAME]] ColumnarTransposition
|
||||
VERSION 1.0
|
||||
DESCRIPTION "Practice implementing columnar transposition in C++"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
add_library(lib-cipher "lib-cipher.cpp")
|
||||
|
||||
add_executable(columnar-transposition-test "driver.cpp")
|
||||
target_link_libraries(columnar-transposition-test lib-cipher)
|
|
@ -0,0 +1,85 @@
|
|||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||||
## About: An example of using columnar transposition cipher ##
|
||||
## + Using concept at www.braingle.com/brainteasers/codes/columnartrans.php ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
#include "lib-cipher.hpp"
|
||||
|
||||
#include<iostream>
|
||||
|
||||
// Columnar transposition cipher
|
||||
// https://www.braingle.com/brainteasers/codes/columnartrans.php#form
|
||||
// NOTE: Must check the 'irregular case' box to produce same results
|
||||
// + I only used the irregular case to encrypt and decrypt
|
||||
// + I did not write any code for testing with the regular case
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
// Main program loop
|
||||
int main (const int argc, const char * argv[]) {
|
||||
// Left some test cases I used commented out :)
|
||||
|
||||
// Using example keyword from www.braingle.com
|
||||
// + The embedded example there doesn't seem to support numbers in keywords :(
|
||||
CipherData cData("ZEBRAS");
|
||||
|
||||
// Taking user input for keyword using CipherData ctor
|
||||
// CipherData cData;
|
||||
|
||||
int choice = 0;
|
||||
bool exit = false;
|
||||
std::string message; // Message to encrypt or decrypt
|
||||
while (!exit) {
|
||||
|
||||
std::string result;
|
||||
switch (choice) {
|
||||
case 1:
|
||||
std::cout << "\nEncrypting...\n";
|
||||
|
||||
// Encrypt example from www.braingle.com
|
||||
result = cData.Encrypt("WEAREDISCOVEREDFLEEATONCE");
|
||||
|
||||
// Take input for encrypting a message
|
||||
// result = cData.Encrypt();
|
||||
|
||||
std::cout << "Encrypted message: " << result << std::endl;
|
||||
exit = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
std::cout << "\nDecrypting...\n";
|
||||
|
||||
// Encrypt, decrypt example from www.braingle.com
|
||||
result = cData.Decrypt(cData.Encrypt("WEAREDISCOVEREDFLEEATONCE"));
|
||||
|
||||
// Take input for previously encrypted message to decrypt
|
||||
// result = cData.Decrypt();
|
||||
|
||||
std::cout << "Decrypted message: " << result << std::endl;
|
||||
exit = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << "What would you like to do?\n1. Encrypt\n2. Decrypt\n";
|
||||
// Take input, handle it accordingly
|
||||
// + https://www.cplusplus.com/forum/general/207458/
|
||||
if (!(std::cin >> choice)) {
|
||||
std::cout << "Invalid character input, choose an option below\n";
|
||||
}
|
||||
else if (choice != 1 && choice != 2) {
|
||||
std::cout << "Incorrect option entered (" << choice << ")\n";
|
||||
}
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||||
## About: An example of using columnar transposition cipher ##
|
||||
## + Using concept at www.braingle.com/brainteasers/codes/columnartrans.php ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
#include "lib-cipher.hpp"
|
||||
|
||||
// Initializes orderVect to determine order columns should be used
|
||||
void CipherData::InitOrder(std::string temp)
|
||||
{
|
||||
// Create a temp value sorted lexicographically, remove duplicate characters
|
||||
// https://en.cppreference.com/w/cpp/string/basic_string/operator_cmp
|
||||
std::sort(temp.begin(), temp.end());
|
||||
auto it = std::unique(temp.begin(), temp.end());
|
||||
temp.erase(it, temp.end());
|
||||
|
||||
// Step through each character in lexicographic order
|
||||
for (int i = 0; i < temp.size(); i++) {
|
||||
// Check each character in the keyWord for the current lexicographic char
|
||||
for (int j = 0; j < keyWord_.size(); j++) {
|
||||
// If they are equal, push the index of the char in keyWord to orderVect
|
||||
if (keyWord_[j] == temp[i]) {
|
||||
orderVect_.push_back(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Allows getting keyWord when using CipherData default ctor
|
||||
std::string CipherData::GetKey()
|
||||
{
|
||||
std::string key;
|
||||
std::cout << "Enter the keyword: ";
|
||||
std::getline(std::cin, key);
|
||||
std::cout << "Keyword entered: " << key << std::endl;
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string CipherData::Encrypt(std::string message)
|
||||
{
|
||||
// If no message was provided, ask for one
|
||||
if (message.empty()) {
|
||||
std::cout << "Input message to encrypt: ";
|
||||
std::getline(std::cin, message);
|
||||
std::cout << "Encrypting message \"" << message << "\"\n";
|
||||
}
|
||||
std::string encryptedMessage;
|
||||
std::vector<std::string> rows;
|
||||
|
||||
// Split the message into rows equal to the length of our keyWord
|
||||
for (size_t i = 0; i < message.size(); i+=keyWord_.size()) {
|
||||
std::string substr = message.substr(i, keyWord_.size());
|
||||
rows.push_back(substr);
|
||||
}
|
||||
|
||||
// Transpose the matrix of characters
|
||||
std::vector<std::string> transposed;
|
||||
Transpose(rows, transposed);
|
||||
|
||||
// Append each row of the transposed matrix to our encryptedMessage
|
||||
for (const auto &val : orderVect_) encryptedMessage += transposed[val];
|
||||
return encryptedMessage;
|
||||
}
|
||||
|
||||
std::string CipherData::Decrypt(std::string message)
|
||||
{
|
||||
// If no message was provided, ask for one
|
||||
if (message.empty()) {
|
||||
std::cout << "Input message to decrypt: ";
|
||||
std::getline(std::cin, message);
|
||||
std::cout << "Decrypting message \"" << message << "\"\n";
|
||||
}
|
||||
std::string result;
|
||||
std::vector<std::string> rows;
|
||||
|
||||
// Split the message into rows equal to the length of our keyWord
|
||||
int rowLength = message.size() / keyWord_.size();
|
||||
// If dividing message and keyword size has a remainder N
|
||||
// + There will be N rows with +1 characters
|
||||
int fullRows = message.size() % keyWord_.size();
|
||||
|
||||
rows.resize(orderVect_.size());
|
||||
// Track the ending position after each substring is taken
|
||||
int lastPos = 0;
|
||||
for (int i = 0; i < orderVect_.size(); i++) {
|
||||
// If we are assigning to any row < fullRows, it should have + 1 character
|
||||
if (orderVect_[i] < fullRows) {
|
||||
rows[orderVect_[i]] = message.substr(lastPos, rowLength + 1);
|
||||
lastPos += rowLength + 1;
|
||||
}
|
||||
else {
|
||||
rows[orderVect_[i]] = message.substr(lastPos, rowLength);
|
||||
lastPos += rowLength;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> transposed;
|
||||
Transpose(rows, transposed);
|
||||
|
||||
for (const auto &row : transposed) result += row;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||||
## About: An example of using columnar transposition cipher ##
|
||||
## + Using concept at www.braingle.com/brainteasers/codes/columnartrans.php ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
################################################################################
|
||||
*/
|
||||
|
||||
#ifndef COLUMNARTRANSPOSITION_LIB_CIPHER_HPP
|
||||
#define COLUMNARTRANSPOSITION_LIB_CIPHER_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include<algorithm>
|
||||
#include<vector>
|
||||
|
||||
/******************************************************************************/
|
||||
// CipherData struct to hold data and methods related to encrypting / decrypting
|
||||
struct CipherData {
|
||||
// Can't create this object without providing a keyWord to initialize order
|
||||
explicit CipherData(std::string keyWord) : keyWord_(std::move(keyWord))
|
||||
{
|
||||
InitOrder(keyWord_);
|
||||
}
|
||||
CipherData() : keyWord_(GetKey()) { InitOrder(keyWord_);}
|
||||
|
||||
/****************************************************************************/
|
||||
// Member functions
|
||||
|
||||
// Initializes orderVect, pass by value to create local copy of keyWord
|
||||
void InitOrder(std::string temp);
|
||||
|
||||
static std::string GetKey();
|
||||
|
||||
static void
|
||||
Transpose(const std::vector<std::string> &in, std::vector<std::string> &out);
|
||||
|
||||
// Default values for param allows calling with no message
|
||||
std::string Encrypt(std::string message="");
|
||||
std::string Decrypt(std::string message="");
|
||||
|
||||
private:
|
||||
std::string keyWord_;
|
||||
std::vector<int> orderVect_;
|
||||
};
|
||||
|
||||
#endif // COLUMNARTRANSPOSITION_LIB_CIPHER_HPP
|
Loading…
Reference in New Issue