diff --git a/GCryptCLI/include/ModuleDataFormatter.h b/GCryptCLI/include/ModuleDataFormatter.h index 6936158..cd84966 100644 --- a/GCryptCLI/include/ModuleDataFormatter.h +++ b/GCryptCLI/include/ModuleDataFormatter.h @@ -20,6 +20,9 @@ class ModuleDataFormatter { //! Will format a vector of blocks to a given iobase static std::string FormatBlocks(const std::vector& blocks, const Configuration::IOBASE_FORMAT base); + //! Will format a string making up multiple block in a given iobase into a vector of block + static std::vector StringToBlocks(const std::string& str, const Configuration::IOBASE_FORMAT base); + private: static std::string Bin2CustomBase(const std::string& bin, const std::vector& customSet, std::size_t minLen, const std::string& seperator = ""); diff --git a/GCryptCLI/src/ModuleDataFormatter.cpp b/GCryptCLI/src/ModuleDataFormatter.cpp index 583defb..aedccb4 100644 --- a/GCryptCLI/src/ModuleDataFormatter.cpp +++ b/GCryptCLI/src/ModuleDataFormatter.cpp @@ -25,20 +25,12 @@ namespace { std::make_pair(Configuration::IOBASE_FORMAT::BASE_8, 171), std::make_pair(Configuration::IOBASE_FORMAT::BASE_10, 155), std::make_pair(Configuration::IOBASE_FORMAT::BASE_16, 128), + std::make_pair(Configuration::IOBASE_FORMAT::BASE_64, 86), std::make_pair(Configuration::IOBASE_FORMAT::BASE_UWU, 125), std::make_pair(Configuration::IOBASE_FORMAT::BASE_UGH, 125) }); } -std::string ModuleDataFormatter::FormatBlocks( - const std::vector& blocks, - const Configuration::IOBASE_FORMAT base -) { - - - return ""; -} - std::string ModuleDataFormatter::FormatBlock( const Block& block, const Configuration::IOBASE_FORMAT base @@ -54,14 +46,14 @@ std::string ModuleDataFormatter::FormatBlock( return Bin2CustomBase( block.ToBinaryString(), BASE_8, - blockLengthByBase[Configuration::IOBASE_FORMAT::BASE_8] + blockLengthByBase[base] ); case Configuration::IOBASE_FORMAT::BASE_10: return Bin2CustomBase( block.ToBinaryString(), BASE_10, - blockLengthByBase[Configuration::IOBASE_FORMAT::BASE_10] + blockLengthByBase[base] ); case Configuration::IOBASE_FORMAT::BASE_16: @@ -71,14 +63,14 @@ std::string ModuleDataFormatter::FormatBlock( return Bin2CustomBase( block.ToBinaryString(), BASE_64, - blockLengthByBase[Configuration::IOBASE_FORMAT::BASE_64] + blockLengthByBase[base] ); case Configuration::IOBASE_FORMAT::BASE_UWU: return Bin2CustomBase( block.ToBinaryString(), BASE_UWU, - blockLengthByBase[Configuration::IOBASE_FORMAT::BASE_UWU], + blockLengthByBase[base], " " ); @@ -86,7 +78,7 @@ std::string ModuleDataFormatter::FormatBlock( return Bin2CustomBase( block.ToBinaryString(), BASE_UGH, - blockLengthByBase[Configuration::IOBASE_FORMAT::BASE_UGH], + blockLengthByBase[base], " " ); @@ -95,6 +87,31 @@ std::string ModuleDataFormatter::FormatBlock( } } +std::string ModuleDataFormatter::FormatBlocks( + const std::vector& blocks, + const Configuration::IOBASE_FORMAT base +) { + std::stringstream ss; + + std::size_t i = 0; + for (const Block& block : blocks) { + ss << FormatBlock(block, base); + + // If we are dealing with a multichar base, we must append a + // seperator (space), but only if its not the last block. + if ( + (base == Configuration::IOBASE_FORMAT::BASE_UWU) || + (base == Configuration::IOBASE_FORMAT::BASE_UGH) + ) { + if (i++ != blocks.size()) { + ss << " "; + } + } + } + + return ss.str(); +} + Block ModuleDataFormatter::StringToBlock( const std::string& str, const Configuration::IOBASE_FORMAT base @@ -169,6 +186,84 @@ Block ModuleDataFormatter::StringToBlock( return b; } +std::vector ModuleDataFormatter::StringToBlocks( + const std::string& str, + const Configuration::IOBASE_FORMAT base +) { + std::vector blocks; + + // A block is this many digits wide, in encoding + const std::size_t blockWidth = blockLengthByBase[base]; + //std::cout << "blockWidth is: " << blockWidth << std::endl; + + // How many blocks are we dealing with here? + const std::size_t n_blocks = (str.length() / blockWidth) + 1; + blocks.reserve(n_blocks); + //std::cout << "n_blocks is: " << n_blocks << std::endl; + + // Iterate over the string, and parse all blocks + // We now have to differentiate between single-char digit sets (hex), + // and multi-char digit sets (uwu): + switch (base) { + case Configuration::IOBASE_FORMAT::BASE_BYTES: + case Configuration::IOBASE_FORMAT::BASE_2: + case Configuration::IOBASE_FORMAT::BASE_8: + case Configuration::IOBASE_FORMAT::BASE_10: + case Configuration::IOBASE_FORMAT::BASE_16: + case Configuration::IOBASE_FORMAT::BASE_64: + // Easy case: Each digit is exactly one char in size. + // We can just calculate how many bits we should take. + for (std::size_t i = 0; i < str.length(); i += blockWidth) { + + const std::string subs = str.substr(i, blockWidth); + + Block newBlock = StringToBlock( + subs, + base + ); + + blocks.emplace_back(newBlock); + } + break; + + case Configuration::IOBASE_FORMAT::BASE_UWU: + case Configuration::IOBASE_FORMAT::BASE_UGH: + // Hard case: Each digit n digits long. Digits may vary in length. + // They are seperated by spaces. + // We have to parse them... + std::size_t digitsPassed = 0; + std::size_t blockStart = 0; + for (std::size_t i = 0; i < str.length(); i++) { + + if (str[i] == ' ') { + digitsPassed++; + + if (digitsPassed == blockWidth) { + const std::string subs = str.substr( + blockStart, + i - blockStart + ); + + Block newBlock = StringToBlock( + subs, + base + ); + + blocks.emplace_back(newBlock); + + digitsPassed = 0; + blockStart = i+1; + } + } + + + } + break; + } + + return blocks; +} + std::string ModuleDataFormatter::Bin2CustomBase( const std::string& bin, const std::vector& customSet, @@ -221,13 +316,11 @@ std::string ModuleDataFormatter::CustomBase2Bin( // Because a set may not perfectly fit a block, transcoding it back // to binary may yield more than 512 bit. These other bits could never // be 1. We have to trim them. - std::cout << binary << std::endl << std::endl; - if (binary.length() > Block::BLOCK_SIZE_BITS) { - binary = binary.substr(0, Block::BLOCK_SIZE_BITS); - } + //if (binary.length() > Block::BLOCK_SIZE_BITS) { + // binary = binary.substr(0, Block::BLOCK_SIZE_BITS); + //} if (binary.length() != Block::BLOCK_SIZE_BITS) { - std::cout << binary.length() << std::endl; throw std::invalid_argument("ModuleDataFormatter::CustomBase2Bin() received input that doesn't translate to a bitstring of length 512!"); } diff --git a/GCryptCLI/src/main.cpp b/GCryptCLI/src/main.cpp index ca29aac..1339ee8 100644 --- a/GCryptCLI/src/main.cpp +++ b/GCryptCLI/src/main.cpp @@ -4,6 +4,7 @@ #include "ModuleDataFormatter.h" #include "Bases.h" #include +#include int main(int argc, char* const* argv) { @@ -16,11 +17,25 @@ int main(int argc, char* const* argv) { // Prepare the key ModulePrepareKey::PrepareKey(); - Block block; - block.FromTextString("Hello World :3"); - std::cout << block.ToBinaryString() << std::endl << std::endl; - std::cout << block.ToHexString() << std::endl << std::endl; + const std::vector textblocks = StringToBitblocks("Hansel and Gretel are a brother and sister abandoned in a forest, where they fall into the hands of a witch who lives in a house made of gingerbread, cake, and candy. The cannibalistic witch intends to fatten the children before eventually eating them, but Gretel outwits the witch and kills her. The two children then escape with their lives and return home with the witch's treasure."); + const std::string formattedBlocks = + ModuleDataFormatter::FormatBlocks( + textblocks, + Configuration::iobaseFormat + ); + std::cout << "Formatted: " << formattedBlocks << std::endl << std::endl; + + const std::vector retrievedBlocks = + ModuleDataFormatter::StringToBlocks( + formattedBlocks, + Configuration::iobaseFormat + ); + + const std::string retrievedText = BitblocksToString(retrievedBlocks); + std::cout << "Retrieved: " << retrievedText << std::endl << std::endl; + + return 0; /* Block all1; @@ -77,8 +92,7 @@ int main(int argc, char* const* argv) { std::cout << ModuleDataFormatter::StringToBlock( ModuleDataFormatter::FormatBlock( - //ModulePrepareKey::GetKey(), - block, + ModulePrepareKey::GetKey(), Configuration::iobaseFormat ), Configuration::iobaseFormat