Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restructure #13

Merged
merged 2 commits into from
Jun 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 2.6)
project(iching)
cmake_minimum_required(VERSION 3.1)
project(iching VERSION 1.0.0 LANGUAGES CXX)
add_subdirectory(src)
#add_subdirectory(tests)

2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -g")
find_package(Boost 1.66 COMPONENTS system program_options REQUIRED)
include_directories(${Boost_INCLUDE_DIR})

add_executable(iching main.cc hexagram.cc translator.cc)
add_executable(iching main.cc hexagram.cc translator.cc util.cc)
target_link_libraries(iching LINK_PUBLIC ${Boost_LIBRARIES})

install(TARGETS iching RUNTIME DESTINATION bin)
4 changes: 2 additions & 2 deletions src/hexagram.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ const char* TRIGRAMS[NUM_TRIGRAMS][NUM_TRIGRAM_LINES] =
[ EARTH ] = { BROKEN, BROKEN, BROKEN }
};

Trigram Hexagram::lower()
Trigram Hexagram::lower() const
{
return this->_lower;
}

Trigram Hexagram::upper()
Trigram Hexagram::upper() const
{
return this->_upper;
}
Expand Down
8 changes: 6 additions & 2 deletions src/hexagram.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ class Hexagram
_upper(upper),
_lower(lower),
_value(value) {}
Trigram upper();
Trigram lower();
Hexagram(const Hexagram& hexagram) :
_upper(hexagram.upper()),
_lower(hexagram.lower()),
_value(hexagram.value()) {}
Trigram upper()const;
Trigram lower() const;
unsigned value() const;
bool operator <(const Hexagram& hexagram) const;
string str();
Expand Down
23 changes: 23 additions & 0 deletions src/lexer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <vector>
#include <sstream>
#include <string>

using std::vector;
using std::string;

namespace Lexer
{
vector<string> strip_lines(const string& encoded_or_fname)
{
vector<string> lines;
std::stringstream ss(encoded_or_fname);
string line = "";

while (std::getline(ss, line, '\n'))
lines.push_back(line);

return lines;
}
}
7 changes: 4 additions & 3 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "translator.h"

using std::cerr;
using std::cout;
using std::endl;

Expand Down Expand Up @@ -56,12 +57,12 @@ int main(int argc, char** argv)

po::notify(vm);
} catch(po::error& e) {
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << desc << std::endl;
cerr << "ERROR: " << e.what() << std::endl << std::endl;
cerr << desc << std::endl;
return ERROR_IN_COMMAND_LINE;
}
} catch(std::exception& e) {
std::cerr << "Unhandled Exception reached the top of main: "
cerr << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit" << std::endl;
return ERROR_UNHANDLED_EXCEPTION;

Expand Down
34 changes: 34 additions & 0 deletions src/parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <vector>

#include "hexagram.h"

using std::vector;

namespace Parser
{
static vector<string> lines_to_hexagrams(const vector<string>& lines)
{
vector<string> continuous_hexagrams(NUM_HEXAGRAM_LINES);
int i = 0;
for (const string& line : lines) {
i = i % NUM_HEXAGRAM_LINES == 0 ? 0 : i;
continuous_hexagrams[i] += line;
i += 1;
}

vector<string> hexagrams;
for (size_t offset = 0; offset < continuous_hexagrams[0].length(); offset += HEXAGRAM_WIDTH) {
string hexagram = "";
for (const string& line : continuous_hexagrams) {
for (size_t j = offset; j < offset + HEXAGRAM_WIDTH; j++)
hexagram += line[j];
hexagram += "\n";
}
hexagrams.push_back(hexagram);
}

return hexagrams;
}
}
123 changes: 24 additions & 99 deletions src/translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,48 @@
#include <ctime>
#include <iostream>
#include <map>
#include <vector>
#include <sstream>

#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>

#include "hexagram.h"
#include "lexer.h"
#include "parser.h"

using namespace boost::archive::iterators;

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::map;
using std::pair;
using std::vector;

static size_t MAX_WIDTH = 80;
static string B64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static map<char, Hexagram> KEYMAP;
string BASE64_CHARACTER_ORDERING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static void build_keymap()
{
int i = 0;
for (const char& c : B64_CHARACTERS) {
for (const char& c : BASE64_CHARACTER_ORDERING) {
KEYMAP.insert(pair<char, Hexagram>(c, HEXAGRAMS[i]));
i += 1;
}
}

static string b64_encode(string msg)
{
std::stringstream os;
typedef base64_from_binary<transform_width<const char*, 6, 8>> base64_text;

std::copy(
base64_text(msg.c_str()),
base64_text(msg.c_str() + msg.size()),
std::ostream_iterator<char>(os));
return os.str();
}

static string b64_decode(const string& msg)
{
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
string output = "";
string padded = msg;

try {
size_t num_pad_chars((4 - msg.size() % 4) % 4);
padded.append(num_pad_chars, '=');
size_t pad_chars(std::count(padded.begin(), padded.end(), '='));
std::replace(padded.begin(), padded.end(), '=', 'A');
std::string output(ItBinaryT(padded.begin()), ItBinaryT(padded.end()));
output.erase(output.end() - pad_chars, output.end());
return output;
} catch (std::exception const& e) {
cerr << "Exception caught: " << e.what() << endl;
}

return output;
}

string build_hexagram_output(vector<Hexagram>& hexagrams, const string& delimiter)
string build_hexagram_output(const vector<Hexagram>& hexagrams, const string& delimiter)
{
string repr = "";
vector<string> continuous_hexagrams(NUM_HEXAGRAM_LINES);
size_t offset = 0;
size_t line_pos = 0;

for (Hexagram& hexagram: hexagrams) {
for (const Hexagram& hexagram: hexagrams) {
if (line_pos >= MAX_WIDTH) {
for (int i = 0; i < NUM_HEXAGRAM_LINES; i++)
for (int i = 0; i < NUM_HEXAGRAM_LINES; i++) {
continuous_hexagrams.push_back("");
}

offset += NUM_HEXAGRAM_LINES;
line_pos = 0;
}

string h = hexagram.str();
string h = Hexagram(hexagram).str();
size_t pos = 0;
string token;

Expand All @@ -99,29 +59,28 @@ string build_hexagram_output(vector<Hexagram>& hexagrams, const string& delimite
line_pos += HEXAGRAM_WIDTH;
}

for (const string& line: continuous_hexagrams)
for (const string& line: continuous_hexagrams) {
repr += line + "\n";
}

return repr;
}

static int random_generator(int i)
{
return std::rand() % i;
}

string Translator::encode(const string& input, bool shuffle)
{
if (shuffle) {
std::srand(unsigned(std::time(0)));
std::random_shuffle(B64_CHARACTERS.begin(), B64_CHARACTERS.end(), random_generator);
cout << "KEY: " << B64_CHARACTERS << endl;
std::random_shuffle(
BASE64_CHARACTER_ORDERING.begin(),
BASE64_CHARACTER_ORDERING.end(),
Util::Random::random_generator);
cout << "KEY: " << BASE64_CHARACTER_ORDERING << endl;
build_keymap();
} else {
build_keymap();
}

string b64_encoded = b64_encode(input);
string b64_encoded = Util::Base64::b64_encode(input);
vector<Hexagram> hexagrams;

for (const char& c : b64_encoded) {
Expand All @@ -131,62 +90,28 @@ string Translator::encode(const string& input, bool shuffle)
return build_hexagram_output(hexagrams, "\n");
}

static vector<string> strip_lines(const string& encoded_or_fname)
{
vector<string> lines;
std::stringstream ss(encoded_or_fname);
string line = "";

while (std::getline(ss, line, '\n'))
lines.push_back(line);

return lines;
}

static vector<string> lines_to_hexagrams(const vector<string>& lines)
{
vector<string> continuous_hexagrams(NUM_HEXAGRAM_LINES);
int i = 0;
for (const string& line : lines) {
i = i % NUM_HEXAGRAM_LINES == 0 ? 0 : i;
continuous_hexagrams[i] += line;
i += 1;
}

vector<string> hexagrams;
for (size_t offset = 0; offset < continuous_hexagrams[0].length(); offset += HEXAGRAM_WIDTH) {
string hexagram = "";
for (const string& line : continuous_hexagrams) {
for (size_t j = offset; j < offset + HEXAGRAM_WIDTH; j++)
hexagram += line[j];
hexagram += "\n";
}
hexagrams.push_back(hexagram);
}

return hexagrams;
}

string Translator::decode(const string& input, string key)
string Translator::decode(const string& input, const string& key)
{
if (key != "") {
B64_CHARACTERS = key;
BASE64_CHARACTER_ORDERING = key;
build_keymap();
} else {
build_keymap();
}
vector<string> hexagrams = lines_to_hexagrams(strip_lines(input));

vector<string> hexagrams = Parser::lines_to_hexagrams(Lexer::strip_lines(input));
string b64 = "";

for (const string& hexagram: hexagrams) {
map<char, Hexagram>::iterator it;
for (it = KEYMAP.begin(); it != KEYMAP.end(); it++) {
string hex_str = it->second.str();

if (hex_str != "" && hex_str == hexagram) {
b64 += it->first;
}
}
}

return b64_decode(b64);
return Util::Base64::b64_decode(b64);
}
4 changes: 3 additions & 1 deletion src/translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

#include <string>

#include "util.h"

using std::string;

namespace Translator
{
string encode(const string& input, bool shuffle = false);
string decode(const string& input, string key = "");
string decode(const string& input, const string& key = "");
}
Loading