Change mapping function to iterators only

master
Trivernis 5 years ago
parent 813ac09607
commit 38569e632e

@ -1,27 +1,15 @@
use rayon::prelude::*;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
pub type PassKey = (String, Vec<u8>); pub type PassKey = (String, Vec<u8>);
/// Hashes a text to a 32 bytes long key. /// Hashes a text to a 32 bytes long key.
pub fn create_key(pw: String) -> Vec<u8> { pub fn create_key(pw: &str) -> Vec<u8> {
let mut hasher = Sha256::default(); let mut hasher = Sha256::default();
hasher.input(pw); hasher.input(pw);
let result = hasher.result(); let result = hasher.result();
let key = &result[0..8]; let key = &result[0..8];
key.to_vec() key.to_vec().clone()
}
/// Maps a list of passwords to keys and returns a vector of pairs
pub fn map_to_keys(passwords: Vec<String>) -> Vec<PassKey> {
passwords
.par_iter()
.map(|pw| {
let pw_str = (*pw).clone();
(pw_str.clone(), create_key(pw_str))
})
.collect()
} }
/// Creates a sha256 hashsum from the input data /// Creates a sha256 hashsum from the input data

@ -3,7 +3,7 @@ pub mod lib;
use crate::lib::crypt::{ use crate::lib::crypt::{
decrypt_brute_brute_force, decrypt_data, decrypt_with_dictionary, encrypt_data, decrypt_brute_brute_force, decrypt_data, decrypt_with_dictionary, encrypt_data,
}; };
use crate::lib::hash::{create_key, map_to_keys, sha_checksum, PassKey}; use crate::lib::hash::{create_key, sha_checksum, PassKey};
use pbr::ProgressBar; use pbr::ProgressBar;
use rayon::prelude::*; use rayon::prelude::*;
use rpassword; use rpassword;
@ -12,6 +12,8 @@ use spinners::{Spinner, Spinners};
use std::fs; use std::fs;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::sync::mpsc::channel;
use std::thread;
use std::time::Duration; use std::time::Duration;
use structopt::StructOpt; use structopt::StructOpt;
@ -106,7 +108,7 @@ fn encrypt(_opts: &Opts, args: &Encrypt) {
.expect("Failed to write checksum file!"); .expect("Failed to write checksum file!");
} }
let pass = read_password_from_tty(Some("Password: ")).unwrap(); let pass = read_password_from_tty(Some("Password: ")).unwrap();
let key = create_key(pass); let key = create_key(&pass);
let enc_data = encrypt_data(data.as_slice(), key.as_slice()); let enc_data = encrypt_data(data.as_slice(), key.as_slice());
fs::write(output, enc_data.as_slice()).expect("Failed to write output file!"); fs::write(output, enc_data.as_slice()).expect("Failed to write output file!");
} }
@ -161,7 +163,7 @@ fn decrypt(_opts: &Opts, args: &Decrypt) {
} }
} else { } else {
let pass = read_password_from_tty(Some("Password: ")).unwrap(); let pass = read_password_from_tty(Some("Password: ")).unwrap();
let key = create_key(pass); let key = create_key(&pass);
let result = decrypt_data(&data, key.as_slice()); let result = decrypt_data(&data, key.as_slice());
fs::write(output, &result).expect("Failed to write output file!"); fs::write(output, &result).expect("Failed to write output file!");
} }
@ -171,43 +173,40 @@ fn decrypt(_opts: &Opts, args: &Decrypt) {
fn create_dictionary(_opts: &Opts, args: &CreateDictionary) { fn create_dictionary(_opts: &Opts, args: &CreateDictionary) {
let input: String = (*args.input).parse().unwrap(); let input: String = (*args.input).parse().unwrap();
let sp = spinner("Parsing passwords..."); let sp = spinner("Parsing passwords...");
let dictionary: Vec<PassKey>; let contents = fs::read_to_string(input).expect("Failed to read input file!");
{ let passwords = contents.lines().collect::<Vec<&str>>();
let passwords = get_lines(&input); // TODO: Some form of removing duplicates (without itertools)
// TODO: Some form of removing duplicates (without itertools)
sp.message("Mapping passwords to keys".into());
dictionary = map_to_keys(passwords);
}
sp.message("Encoding data to lines".into());
let dict_lines: Vec<String> = dictionary
.par_iter()
.map(|(pw, key): &PassKey| -> String {
let key_base64 = base64::encode(key.as_slice());
format!("{},{}\n", pw, key_base64)
})
.collect();
sp.stop(); sp.stop();
println!("\rWriting passwords to file...");
let mut fout = File::create(args.output.clone()).unwrap(); let mut fout = File::create(args.output.clone()).unwrap();
let mut pb = ProgressBar::new(dict_lines.len() as u64); let handle;
pb.set_max_refresh_rate(Some(Duration::from_millis(200))); {
for line in dict_lines { let mut pb = ProgressBar::new(passwords.len() as u64);
fout.write(&line.into_bytes()).unwrap(); pb.set_max_refresh_rate(Some(Duration::from_millis(200)));
pb.inc(); let (rx, tx) = channel::<String>();
handle = thread::spawn(move || {
for line in tx {
fout.write(&line.as_bytes()).unwrap();
pb.inc();
}
pb.finish();
});
passwords
.par_iter()
.map(|pw| -> String {
let key = create_key(pw);
let key_base64 = base64::encode(key.as_slice());
format!("{},{}\n", pw, key_base64)
})
.for_each_with(rx, |rx, line| {
rx.send(line).expect("Failed to send value to channel.");
});
}
if let Err(_err) = handle.join() {
println!("Failed to join!");
} }
pb.finish();
println!("Finished!"); println!("Finished!");
} }
fn get_lines(filename: &str) -> Vec<String> {
let contents = fs::read_to_string(filename).expect("Failed to read input file!");
let lines = contents.lines().collect::<Vec<&str>>();
lines
.par_iter()
.map(|s| -> String { s.parse().unwrap() })
.collect()
}
/// Creates a new spinner with a given text /// Creates a new spinner with a given text
fn spinner(text: &str) -> Spinner { fn spinner(text: &str) -> Spinner {
Spinner::new(Spinners::Dots2, text.into()) Spinner::new(Spinners::Dots2, text.into())

Loading…
Cancel
Save