Last active
April 17, 2020 23:54
-
-
Save jRimbault/83c378bebb85d2ef1606e0c3d97fde3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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