diff --git a/Cargo.lock b/Cargo.lock index b52e14a..04d8605 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -170,6 +179,16 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "once_cell_polyfill" version = "1.70.1" @@ -190,6 +209,8 @@ name = "psha" version = "0.1.0" dependencies = [ "clap", + "colored", + "md-5", "sha2", ] diff --git a/Cargo.toml b/Cargo.toml index 3e61c93..b1cf634 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" [dependencies] sha2 = "0.10.9" clap = { version = "4.5.29", features = ["derive"] } +colored = "3.0.0" +md-5 = "0.10.6" diff --git a/src/hashers.rs b/src/hashers.rs index f516cbc..8707ba0 100644 --- a/src/hashers.rs +++ b/src/hashers.rs @@ -1,7 +1,17 @@ use sha2::{Digest, Sha256, Sha384, Sha512}; +use md5::Md5; use std::fs::File; use std::io; +use crate::common; + +pub fn hash_md5(mut file: File) -> String { + let mut hasher = Md5::new(); + _ = io::copy(&mut file, &mut hasher); + + return format!("{:x}", hasher.finalize()); +} + pub fn hash_sha256(mut file: File) -> String { let mut hasher = Sha256::new(); _ = io::copy(&mut file, &mut hasher); diff --git a/src/main.rs b/src/main.rs index dcb1dec..eeafb48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,10 @@ use std::sync::{Arc, Mutex}; use std::thread::{self, available_parallelism}; mod hashers; +mod common; + +const ALGORITHMS: [&'static str; 3] = ["sha256", "sha384", "sha512"]; +const UNSECURE_ALGORITHMS: [&'static str; 1] = ["md5"]; #[derive(Parser)] #[command(name = "psha")] @@ -33,7 +37,18 @@ struct Args { long, help = "Specify an algorithm for hashing", default_value = "sha256", - value_parser = clap::builder::PossibleValuesParser::new(["sha256", "sha512"]) + value_parser = { + let mut cleaned: Vec<&str> = vec![]; + for i in ALGORITHMS { + cleaned.push(i); + } + + for i in UNSECURE_ALGORITHMS { + cleaned.push(i); + } + + clap::builder::PossibleValuesParser::new(Vec::from(cleaned)) + } )] algorithm: String, @@ -98,6 +113,7 @@ fn hash(info: ThreadInfo) -> Result<(), String> { "sha256" => hashers::hash_sha256(file), "sha384" => hashers::hash_sha384(file), "sha512" => hashers::hash_sha512(file), + "md5" => hashers::hash_md5(file), _ => panic!("Somehow did not pass a supported algorithm"), }; @@ -115,7 +131,6 @@ fn hash(info: ThreadInfo) -> Result<(), String> { fn main() { let args = Args::parse(); - let cpus = available_parallelism().unwrap().get(); let mut buffer = VecDeque::new(); let mut handles = vec![]; for file in args.files { @@ -129,6 +144,19 @@ fn main() { } } + let cpus = match args.threads { + 0 => available_parallelism().unwrap().get(), + _ => args.threads + }; + + if args.debug { + eprintln!("Starting psha using algorithm {} with {} threads", args.algorithm, cpus) + } + + if UNSECURE_ALGORITHMS.contains(&args.algorithm.as_str()) { + common::warning(format!("{} is an unsecure hashing algorithm!", &args.algorithm)); + } + let arc_buf = Arc::new(Mutex::new(buffer)); for i in 0..cpus { let safe_buf = Arc::clone(&arc_buf); @@ -152,5 +180,4 @@ fn main() { } } - // println!("{}", available_parallelism().unwrap().get()); }