Skip to content

Instantly share code, notes, and snippets.

@qookei
Created November 10, 2019 11:58
Show Gist options
  • Save qookei/0d0129683769cf7cd8cfe9caf63068a6 to your computer and use it in GitHub Desktop.
Save qookei/0d0129683769cf7cd8cfe9caf63068a6 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
constexpr const char *text_color_reset = "\e[0m";
constexpr const char *text_color_red = "\e[31m";
template<typename T>
size_t largest_container(const T &conts) {
size_t s = 0;
for(auto &cont : conts)
s = s < cont.size() ? cont.size() : s;
return s;
}
std::vector<uint8_t> compute_difference_mask(std::vector<std::vector<uint8_t>> v) {
size_t output_size = largest_container(v);
std::vector<uint8_t> output{};
output.resize(output_size);
for(size_t i = 0; i < output_size; i++) {
bool cont = true;
uint8_t a = 0xFF;
uint8_t b = 0xFF;
for (auto &c : v) {
if (i >= c.size()) {
cont = false;
output[i] = 0xFF;
break;
}
a &= c[i];
b &= ~c[i];
}
if (!cont)
continue;
output[i] = ~(a | b);
}
return output;
}
void format_byte_as_bits(std::ostringstream &out, uint8_t byte, uint8_t diff_mask) {
for (ssize_t i = 7; i >= 0; i--) {
int bit = (byte >> i) & 1;
if (diff_mask & (1 << i))
out << text_color_red;
out << bit;
if (diff_mask & (1 << i))
out << text_color_reset;
}
}
std::string format_vector_as_bits(std::vector<uint8_t> bytes, std::vector<uint8_t> diff_mask = {}) {
std::ostringstream out{};
for (size_t i = 0; i < bytes.size(); i++) {
uint8_t byte = bytes[i];
uint8_t diff = i < diff_mask.size() ? diff_mask[i] : 0;
format_byte_as_bits(out, byte, diff);
out << " ";
}
return out.str();
}
std::vector<std::vector<uint8_t>> load_file(const std::string &path) {
std::vector<std::vector<uint8_t>> out{};
std::string line;
std::ifstream file{path};
while(std::getline(file, line)) {
std::vector<uint8_t> bytes{};
std::istringstream in{line};
std::vector<std::string> toks((std::istream_iterator<std::string>(in)),
std::istream_iterator<std::string>());
for (auto &tok : toks) {
bytes.push_back(std::stoi(tok, nullptr, 16));
}
out.push_back(bytes);
}
return out;
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "usage: <file1> [file2] ... [filen]\n";
return 1;
}
for (int i = 1; i < argc; i++) {
auto values = load_file(argv[i]);
std::vector<uint8_t> diff = compute_difference_mask(values);
for(size_t i = 0; i < values.size(); i++) {
std::cout << (i + 1) << ":\t" << format_vector_as_bits(values[i], diff) << "\n";
}
std::cout << "diff:\t" << format_vector_as_bits(diff) << "\n";
if (i != argc - 1)
std::cout << " --------------------------- \n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment