mirror of
https://bitbucket.org/Mattrixwv/cipherstream.git
synced 2025-12-06 18:33:58 -05:00
429 lines
11 KiB
C++
429 lines
11 KiB
C++
//Ciphers/helperFunctions.hpp
|
|
//Matthew Ellison
|
|
// Created: 4-29-18
|
|
//Modified: 5-8-18
|
|
//This file contains the driver function and the test functions for the Cipher program
|
|
//This program will use some simple ciphers that are no longer widely used but still fun to play with
|
|
/*
|
|
Copyright (C) 2018 Matthew Ellison
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#ifndef HELPER_FUNCTIONS_HPP
|
|
#define HELPER_FUNCTIONS_HPP
|
|
|
|
|
|
#include "Headers/Caesar.hpp"
|
|
#include "Headers/Playfair.hpp"
|
|
#include "Headers/Vigenere.hpp"
|
|
#include "Headers/Atbash.hpp"
|
|
#include "Headers/Morse.hpp"
|
|
#include "Headers/Autokey.hpp"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
|
|
|
|
enum CipherFlagLocation { CAESAR, PLAYFAIR, VIGENERE, ATBASH, MORSE, AUTOKEY, NUM_CIPHERS,
|
|
ENCODE, DECODE, INPUT_FILE, OUTPUT_FILE, SIZE };
|
|
std::string flagStrings[SIZE];
|
|
//Error handling
|
|
bool failFlag = false; //Set if something fails
|
|
|
|
//For the getCipher function
|
|
typedef std::string (*Fn)(std::ifstream&, bool);
|
|
|
|
|
|
|
|
/**
|
|
* @brief Takes all of the arguments that were given to the program and sets boolean flags inside the program that will change behavior
|
|
*
|
|
* @param argc The number of arguments given
|
|
* @param argv The arguments given
|
|
* @param cipherFlags The array of booleans that represent the possible options passed in
|
|
* @param inputFileString The name of the input file, if given
|
|
* @param outputFileString The name of the output file if given
|
|
*/
|
|
void getFlags(int argc, char** argv, bool cipherFlags[], std::string& inputFileString, std::string& outputFileString){
|
|
//Cycle through every argument
|
|
bool valid = false;
|
|
for(int cnt = 1;cnt < argc;++cnt){
|
|
//Step through every element in the flagStrings and compare the flags. If the flags do not match or you go out of bounds in argv throw an error
|
|
for(int stringcnt = 0;stringcnt < SIZE;++stringcnt){
|
|
if(argv[cnt] == flagStrings[stringcnt]){
|
|
valid = cipherFlags[stringcnt] = true;
|
|
//If the flag showed an input file get the file name if possible
|
|
if(stringcnt == INPUT_FILE){
|
|
//Make sure there is enough room in argv for the file name
|
|
if((cnt + 1) < argc){
|
|
inputFileString = argv[++cnt];
|
|
}
|
|
}
|
|
//If the flag showed an output file get the file name if possible
|
|
else if(stringcnt == OUTPUT_FILE){
|
|
//Make sure there is enough room in argv for the file name
|
|
if((cnt + 1) < argc){
|
|
outputFileString = argv[++cnt];
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
//If the flag was not valid throw an error
|
|
if(!valid){
|
|
std::cout << argv[cnt] << " is an invalid flag" << std::endl;
|
|
return;
|
|
}
|
|
valid = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Checks that the flags given are valid
|
|
*
|
|
* @param flags All of the flags that the program can have
|
|
* @return true If valid options were chosen
|
|
* @return false If invalid options were chosen
|
|
*/
|
|
bool checkFlags(bool flags[]){
|
|
int counter = 0;
|
|
bool correct = false;
|
|
//Run through each flag and counter how many are true
|
|
for(int cnt = 0;cnt < NUM_CIPHERS;++cnt){
|
|
if(flags[cnt]){
|
|
++counter;
|
|
}
|
|
}
|
|
|
|
//Check if a valid number of flags were true
|
|
if(counter == 1){
|
|
correct = true;
|
|
}
|
|
|
|
//Check if either encode or decode is set, but not both
|
|
if((flags[ENCODE] && flags[DECODE]) || (!flags[ENCODE] && !flags[DECODE])){
|
|
correct = false;
|
|
}
|
|
|
|
return correct;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the array of strings that controls what each flag should look
|
|
*
|
|
*/
|
|
void setFlagStrings(){
|
|
flagStrings[CAESAR] = "-c";
|
|
flagStrings[PLAYFAIR] = "-p";
|
|
flagStrings[VIGENERE] = "-v";
|
|
flagStrings[ATBASH] = "-a";
|
|
flagStrings[MORSE] = "-m";
|
|
flagStrings[AUTOKEY] = "-u";
|
|
flagStrings[ENCODE] = "-e";
|
|
flagStrings[DECODE] = "-d";
|
|
flagStrings[INPUT_FILE] = "-i";
|
|
flagStrings[OUTPUT_FILE] = "-o";
|
|
}
|
|
|
|
/**
|
|
* @brief Run the appropriate commands to use a Caesar cipher
|
|
*
|
|
* @param infile The input file if one was provided
|
|
* @param encode Whether the encoding flag was set. True if encoding, false if decoding
|
|
* @return The new message
|
|
*/
|
|
std::string runCaesar(std::ifstream& infile, bool encode){
|
|
std::string inputString, cipherString;
|
|
int offset;
|
|
Caesar cipher;
|
|
//Check if the input file is open
|
|
if(infile.is_open()){
|
|
infile >> offset;
|
|
infile.ignore(10000, '\n'); //Get rid of the \n that is right after the offset
|
|
std::getline(infile, inputString);
|
|
if(infile.fail()){
|
|
failFlag = true;
|
|
cipherString = "Input file has an incorrect format\n";
|
|
}
|
|
}
|
|
//Otherwise prompt for the appropriate strings
|
|
else{
|
|
std::cout << "Enter the cipher offset: ";
|
|
std::cin >> offset;
|
|
if(std::cin.fail()){
|
|
std::cin.ignore(10000, '\n');
|
|
std::cin.clear();
|
|
std::cout << "That is an invalid offset\nEnter the cipher offset: ";
|
|
std::cin >> offset;
|
|
}
|
|
std::cout << "Enter the input string: ";
|
|
std::cin.ignore(10000, '\n');
|
|
std::getline(std::cin, inputString);
|
|
}
|
|
|
|
//Check if there was an error reading the file
|
|
if(failFlag){
|
|
return cipherString;
|
|
}
|
|
//Run the correct cipher
|
|
if(encode){
|
|
cipherString = cipher.encode(offset, inputString);
|
|
}
|
|
else{
|
|
cipherString = cipher.decode(offset, inputString);
|
|
}
|
|
|
|
return cipherString;
|
|
}
|
|
|
|
/**
|
|
* @brief Run the appropriate commands to use a Playfair cipher
|
|
*
|
|
* @param infile The input file if one was provided
|
|
* @param encode Whether the encoding flag was set. True if encoding, false if decoding
|
|
* @return The new message
|
|
*/
|
|
std::string runPlayfair(std::ifstream& infile, bool encode){
|
|
std::string keyword, inputString, cipherString;
|
|
Playfair cipher;
|
|
//Check if the input file is open
|
|
if(infile.is_open()){
|
|
std::getline(infile, keyword);
|
|
std::getline(infile, inputString);
|
|
if(infile.fail()){
|
|
failFlag = true;
|
|
cipherString = "Input file has an incorrect format\n";
|
|
}
|
|
}
|
|
//Otherwise prompt for the appropriate strings
|
|
else{
|
|
std::cout << "Enter the keyword: ";
|
|
std::getline(std::cin, keyword);
|
|
std::cout << "Enter the input string: ";
|
|
std::getline(std::cin, inputString);
|
|
}
|
|
|
|
//Check if there was an error reading the file
|
|
if(failFlag){
|
|
return cipherString;
|
|
}
|
|
//Run the correct cipher
|
|
if(encode){
|
|
cipherString = cipher.encode(keyword, inputString);
|
|
}
|
|
else{
|
|
cipherString = cipher.decode(keyword, inputString);
|
|
}
|
|
|
|
return cipherString;
|
|
}
|
|
|
|
/**
|
|
* @brief Run the appropriate commands to use a Vigenere cipher
|
|
*
|
|
* @param infile The input file if one was provided
|
|
* @param encode Whether the encoding flag was set. True if encoding, false if decoding
|
|
* @return The new message
|
|
*/
|
|
std::string runVigenere(std::ifstream& infile, bool encode){
|
|
std::string keyword, inputString, cipherString;
|
|
Vigenere cipher;
|
|
//Check if the input file is open
|
|
if(infile.is_open()){
|
|
std::getline(infile, keyword);
|
|
std::getline(infile, inputString);
|
|
if(infile.fail()){
|
|
failFlag = true;
|
|
cipherString = "Input file has an incorrect format\n";
|
|
}
|
|
}
|
|
//Otherwise prompt for the appropriate strings
|
|
else{
|
|
std::cout << "Enter the keyword: ";
|
|
std::getline(std::cin, keyword);
|
|
std::cout << "Enter the input string: ";
|
|
std::getline(std::cin, inputString);
|
|
}
|
|
|
|
//Check if there was an error reading the file
|
|
if(failFlag){
|
|
return cipherString;
|
|
}
|
|
//Run the correct cipher
|
|
if(encode){
|
|
cipherString = cipher.encode(keyword, inputString);
|
|
}
|
|
else{
|
|
cipherString = cipher.decode(keyword, inputString);
|
|
}
|
|
|
|
return cipherString;
|
|
}
|
|
|
|
/**
|
|
* @brief Run the appropriate commands to use an Atbash cipher
|
|
*
|
|
* @param infile The input file if one was provided
|
|
* @param encode Whether the encoding flag was set. True if encoding, false if decoding
|
|
* @return The new message
|
|
*/
|
|
std::string runAtbash(std::ifstream& infile, bool encode){
|
|
std::string inputString, cipherString;
|
|
Atbash cipher;
|
|
//Check if the input file is open
|
|
if(infile.is_open()){
|
|
std::getline(infile, inputString);
|
|
if(infile.fail()){
|
|
failFlag = true;
|
|
cipherString = "Input file has an incorrect format\n";
|
|
}
|
|
}
|
|
//Otherwise prompt for the appropriate strings
|
|
else{
|
|
std::cout << "Enter the input string: ";
|
|
std::getline(std::cin, inputString);
|
|
}
|
|
|
|
//Check if there was an error reading the file
|
|
if(failFlag){
|
|
return cipherString;
|
|
}
|
|
//Run the correct cipher
|
|
if(encode){
|
|
cipherString = cipher.encode(inputString);
|
|
}
|
|
else{
|
|
cipherString = cipher.decode(inputString);
|
|
}
|
|
|
|
return cipherString;
|
|
}
|
|
|
|
/**
|
|
* @brief Run the appropriate commands to use Morse code
|
|
*
|
|
* @param infile The input file if one was provided
|
|
* @param encode Whether the encoding flag was set. True if encoding, false if decoding
|
|
* @return The new message
|
|
*/
|
|
std::string runMorse(std::ifstream& infile, bool encode){
|
|
std::string inputString, cipherString;
|
|
Morse cipher;
|
|
//Check if the input file is open
|
|
if(infile.is_open()){
|
|
std::getline(infile, inputString);
|
|
if(infile.fail()){
|
|
failFlag = true;
|
|
cipherString = "Input file has an incorrect format\n";
|
|
}
|
|
}
|
|
//Otherwise prompt for the appropriate strings
|
|
else{
|
|
std::cout << "Enter the input string: ";
|
|
std::getline(std::cin, inputString);
|
|
}
|
|
|
|
//Check if there was an error reading the file
|
|
if(failFlag){
|
|
return cipherString;
|
|
}
|
|
//Run the correct cipher
|
|
if(encode){
|
|
cipherString = cipher.encode(inputString);
|
|
}
|
|
else{
|
|
cipherString = cipher.decode(inputString);
|
|
}
|
|
|
|
return cipherString;
|
|
}
|
|
|
|
/**
|
|
* @brief Run the appropriate commands to use an Autokey cipher
|
|
*
|
|
* @param infile The input file if one was provided
|
|
* @param encode Whether the encoding flag was set. True if encoding, false if decoding
|
|
* @return The new message
|
|
*/
|
|
std::string runAutokey(std::ifstream& infile, bool encode){
|
|
std::string keyword, inputString, cipherString;
|
|
Autokey cipher;
|
|
//Check if the input file is open
|
|
if(infile.is_open()){
|
|
std::getline(infile, keyword);
|
|
std::getline(infile, inputString);
|
|
if(infile.fail()){
|
|
failFlag = true;
|
|
cipherString = "Input file has an incorrect format\n";
|
|
}
|
|
}
|
|
//Otherwise prompt for the appropriate strings
|
|
else{
|
|
std::cout << "Enter the keyword: ";
|
|
std::getline(std::cin, keyword);
|
|
std::cout << "Enter the input string: ";
|
|
std::getline(std::cin, inputString);
|
|
}
|
|
|
|
//Check if there was an error reading the file
|
|
if(failFlag){
|
|
return cipherString;
|
|
}
|
|
//Run the correct cipher
|
|
if(encode){
|
|
cipherString = cipher.encode(keyword, inputString);
|
|
}
|
|
else{
|
|
cipherString = cipher.decode(keyword, inputString);
|
|
}
|
|
|
|
return cipherString;
|
|
}
|
|
|
|
/**
|
|
* @brief Uses the flags to determine which cipher needs to be run
|
|
*
|
|
* @param cipherFlags The possible flags given to the program
|
|
* @return The appropriate run___ function based on the flags
|
|
*/
|
|
//Returns the correct function for the flags that are set
|
|
Fn getCipher(const bool cipherFlags[]){
|
|
if(cipherFlags[CAESAR]){
|
|
return runCaesar;
|
|
}
|
|
else if(cipherFlags[PLAYFAIR]){
|
|
return runPlayfair;
|
|
}
|
|
else if(cipherFlags[VIGENERE]){
|
|
return runVigenere;
|
|
}
|
|
else if(cipherFlags[ATBASH]){
|
|
return runAtbash;
|
|
}
|
|
else if(cipherFlags[MORSE]){
|
|
return runMorse;
|
|
}
|
|
else if(cipherFlags[AUTOKEY]){
|
|
return runAutokey;
|
|
}
|
|
//If it didn't trip one of the flags, there was an error before this
|
|
else{
|
|
std::cout << "There was an error selecting the appropriate function";
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
#endif //HELPER_FUNCTIONS_HPP
|