Skip to content

Instantly share code, notes, and snippets.

@jRimbault
Last active April 17, 2020 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jRimbault/83c378bebb85d2ef1606e0c3d97fde3c to your computer and use it in GitHub Desktop.
Save jRimbault/83c378bebb85d2ef1606e0c3d97fde3c to your computer and use it in GitHub Desktop.
use std::fs;
use std::io;
use std::path::PathBuf;
use structopt::{clap::ArgGroup, StructOpt};
#[derive(Clone, StructOpt, Debug)]
#[structopt(group = ArgGroup::with_name("action").required(true))]
struct Arguments {
/// File containing a G4C key
key_file: PathBuf,
/// File to encode or decode
source: PathBuf,
/// Output file
dest: PathBuf,
/// Action to execute on the source file
#[structopt(short, long, group = "action")]
encode: bool,
/// Action to execute on the source file
#[structopt(short, long, group = "action")]
decode: bool,
}
fn main() -> io::Result<()> {
let args = Arguments::from_args();
let key = fs::read_to_string(args.key_file)?;
let key: Vec<u8> = key[5..40]
.split_ascii_whitespace()
.filter_map(|s| u8::from_str_radix(&s, 2).ok())
.collect();
let encode_lookup = [
key[0] ^ key[1] ^ key[2] ^ key[3],
key[3],
key[2],
key[2] ^ key[3],
key[1],
key[1] ^ key[3],
key[1] ^ key[2],
key[1] ^ key[2] ^ key[3],
key[0],
key[0] ^ key[3],
key[0] ^ key[2],
key[0] ^ key[2] ^ key[3],
key[0] ^ key[1],
key[0] ^ key[1] ^ key[3],
key[0] ^ key[1] ^ key[2],
0,
];
let source = fs::read(args.source)?;
const SHIFT: u8 = 4;
let result = if args.encode {
let mut encoded = Vec::with_capacity(source.len() * 2);
const MASK: u8 = 0x0f;
for byte in source {
encoded.push(encode_lookup[(byte & MASK) as usize]);
encoded.push(encode_lookup[(byte >> SHIFT) as usize]);
}
encoded
} else {
let mut decoded = Vec::with_capacity(source.len() / 2);
let mut lookup = [0; 256];
for (i, val) in encode_lookup.iter().enumerate() {
lookup[*val as usize] = i as u8;
}
let decode_lookup = lookup;
for bytes in source.chunks(2) {
decoded.push(
decode_lookup[bytes[0] as usize] | (decode_lookup[bytes[1] as usize] << SHIFT),
);
}
decoded
};
fs::write(args.dest, &result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment