From ed2fcb6c3a7eab418469c9f62160c8ec5d456fce Mon Sep 17 00:00:00 2001 From: x00010 Date: Tue, 27 Apr 2021 21:26:15 +0100 Subject: [PATCH] Completed basic functionality --- cxor.cpp | 206 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 132 insertions(+), 74 deletions(-) diff --git a/cxor.cpp b/cxor.cpp index 84e82fb..177ef41 100755 --- a/cxor.cpp +++ b/cxor.cpp @@ -1,131 +1,189 @@ -#include -#include -#include -#include -#include -#include +#include // used for cin and cout +#include // used to read files +#include // used for argument processing +#include // used for strings +#include // use for vectors +#include // used to get system time +#include // used for setw and setfill -namespace po = boost::program_options; +namespace po = boost::program_options; // use po as shorthand for boost::program_options namespace -std::string randomkey() +std::string randomkey() // function which uses system time to randomly pick 10 characters from the uppercase and lowercase alphabet { - std::string sAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + std::string sAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; // declare string containing alphabet srand(time(NULL)); // init srand with seed as current system clock time - std::string sKey; - for (int i = 0; i != 10; i++) + std::string sKey; // declare xor key + for (int i = 0; i < 11; i++) // loop 10 times { - int iRandomIndex = rand() % 51 +1; // generate a number between 1 and 26 - sKey.insert(sKey.length(), 1, sAlphabet[iRandomIndex]); + int iRandomIndex = rand() % 51 +1; // generate a number between 1 and 51 + sKey += sAlphabet[iRandomIndex]; // use this number to pick a random letter and add it to the sKey string } - return sKey; + return sKey; // return xor key } -std::vector parseargs(int argc, char* argv[]) +std::vector parseargs(int argc, char* argv[]) // function which uses boost to parse program arguments { - std::string sIFile; - std::string bInputHex = "false"; - std::string sOFile; - std::string bOutputHex = "false"; - std::string sKey; + std::string sIFile; // declare input file + std::string sInputHex = "false"; // declare str serving purpose of bool + std::string sOFile; // declare output file + std::string sOutputHex = "false"; // declare str serving purpose of bool + std::string sKey; // declare xor key po::options_description desc("Allowed options"); - desc.add_options() + desc.add_options() // define options ("help", "Print this message") ("if", po::value(), "Specify an input file") - ("ih", "Input data is in hex") + ("ix", "Input data is in hex") ("of", po::value(), "Specify an output file") - ("oh", "Output data in hex") + ("ox", "Output data in hex") ("k", po::value(), "Specify a key") ; - /*po::positional_options_description p; - p.add("input", -1);*/ + po::variables_map vm; // create map to insert options into + po::store(po::parse_command_line(argc, argv, desc), vm); // parse options + po::notify(vm); // handler for invalid options - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - if (vm.count("help")) + if (vm.count("help")) // if --help was used { - std::cout << desc << std::endl; + std::cout << desc << std::endl; // print all the options } - if (vm.count("if")) + if (vm.count("if")) // if --if was used { - sIFile = vm["if"].as(); - sIFile = sIFile.substr(1, sIFile.length()); + sIFile = vm["if"].as(); // copy the value into sIFile } - if (vm.count("ih")) + if (vm.count("ix")) // if --ix was used { - bool bInputHex = "true"; + sInputHex = "true"; } - if (vm.count("of")) + if (vm.count("of")) // if --of was used { - sOFile = vm["of"].as(); - sOFile = sOFile.substr(1, sOFile.length()); + sOFile = vm["of"].as(); // copy the value into OFile } - if (vm.count("oh")) + if (vm.count("ox")) // if --ox was used { - bool bOutputHex = "true"; + sOutputHex = "true"; } - if (vm.count("k")) + if (vm.count("k")) // if --k was used { - sKey = vm["k"].as(); + sKey = vm["k"].as(); // copy the value into sKey } else { - std::string sKey = randomkey(); + sKey = randomkey(); // use the return from the randomkey function as the xor key std::cout << "No key provided, using generated key " << sKey << std::endl; } - std::vector sParsedArgs {sIFile, bInputHex, sOFile, bOutputHex, sKey}; // init vector with parsed args + std::vector sParsedArgs {sIFile, sInputHex, sOFile, sOutputHex, sKey}; // init vector with parsed args return sParsedArgs; } -void encryptio(std::vector sParsedArgs) +std::string hexify(std::string sMessage, bool bHexToStr) // define hexify, which takes sMessage and converts it to hex or str depending on the value + // of bHexToStr +{ + std::string sReturn; // define sReturn which is used to return the converted string + if (bHexToStr) // convert hex to str + { + for (int i = 0; i < sMessage.length(); i += 2) // iterate through 2 chars at a time up until the end of the string is reached + { + std::string sSlice = sMessage.substr(i, 2); // slice the string to length of two + char cMessageChar = std::stoul(sSlice, nullptr, 16); // convert hex to base 16? + sReturn += cMessageChar; // add converted ascii char to sReturn string + } + } + else // convert str to hex + { + std::stringstream ss; + for (const auto &item : sMessage) // define auto which iterates through sMessage + { + ss << std::hex << std::setw(2) << std::setfill('0') << int(item); // convert char from string to its int counterpart, re add leading zeros + // and then convert it to hex + } + sReturn = ss.str(); // get string value from stringstream and assign it to sReturn + } + return sReturn; +} + +std::string xormessage(std::string sMessage, std::string sKey) // define xormessage, which takes sMessage and *crypts it with sKey +{ + std::string sXORMessage; // define sXORMessage which is a string used to contain the *crypted message + int iKeyIndex = 0; // define iKeyIndex which is used to iterate through sKey's chars + + for (int i = 0; i < sMessage.length(); i++) // iterate through sMessage + { + sXORMessage += sMessage[i] ^ sKey[iKeyIndex]; // perfrom the xor operation on a char in sMessage using a char in sKey + iKeyIndex++; + if (iKeyIndex == sKey.length()) // if iKeyIndex has reached the length of sKey + { + iKeyIndex = 0; // then reset iKeyIndex to zero + } + } + + return sXORMessage; +} + +void cryptio(std::vector sParsedArgs) // function handles io for *cryption { std::string sMessage; - if (sParsedArgs[0] == "") // if no file path was provided + if (sParsedArgs[0] == "") // if no input file path was provided { - std::cout << "No file path provided, please input message:"; + std::cout << "No file path provided, please input message:" << std::endl; std::cin >> sMessage; - } - else // if a file path was provided - { - // TODO WRITE HEX CASE TO CONVERT HEX BACK TO ORIGINAL FORM!!!!!! - std::ifstream IFile; - IFile.open(sParsedArgs[0]); // open file - IFile >> sMessage; - } -} - -std::vector xormessage(std::string sMessage, std::string sKey) -{ - std::vector cXORMessage; - int iKeyIndex = 0; - - for (int iMessageIndex = 0; iMessageIndex < sMessage.length(); iMessageIndex++) - { - cXORMessage.push_back(sMessage[iMessageIndex] ^ sKey[iKeyIndex]); - iKeyIndex++; - if (iKeyIndex == sKey.length()) + if (sParsedArgs[1] == "true") // if the inputted text is hex { - iKeyIndex = 0; + sMessage = hexify(sMessage, true); // convert the message from hex to str } } - return cXORMessage; + else // if an input file path was provided + { + std::ifstream IFile; // define ifstream file handler + char cMessage; // define char for usage in file reading + IFile.open(sParsedArgs[0]); // open file + while (IFile.get(cMessage)) // read file byte by byte + { + sMessage += cMessage; // add current byte to sMessage + } + IFile.close(); // close file + + if (sParsedArgs[1] == "true") // if the input file is hex + { + sMessage = hexify(sMessage, true); // dehexify the file + } + } + + std::string sXORMessage = xormessage(sMessage, sParsedArgs[4]); // *crypt the message using the key provided + + if (sParsedArgs[2] == "") // if no output file path was provided + { + std::cout << "No file path provided, outputting to stdout in hex" << std::endl; + std::cout << hexify(sXORMessage, false) << std::endl; // outputs *crypted message to stdout + } + else // if an output file path was provided + { + std::ofstream OFile; // define ofstream file handler + OFile.open(sParsedArgs[2]); // open file + if (sParsedArgs[3] == "true") // if the output should be in hex + { + sXORMessage = hexify(sXORMessage, false); // convert message to hex + OFile << sXORMessage; // write *crypted message in hex to file + OFile.close(); // close file + } + else // if the output should not be in hex + { + OFile << sXORMessage; // write *crypted message to file + OFile.close(); // close file + } + std::cout << "*crypted output has been written to " << sParsedArgs[2] << std::endl; + } } int main(int argc, char* argv[]) { std::vector sParsedArgs = parseargs(argc, argv); - encryptio(sParsedArgs); - xormessage("hello ", "key"); - - + cryptio(sParsedArgs); // call cryptio with the parsed arguments } \ No newline at end of file