use md5::{Digest, Md5};
use sha1::Sha1;
use sha2::Sha256;
+use sha2::Sha512;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
senders.push(s);
handles.push(sha256_digest(r));
}
+ if algorithms.contains(&Algorithm::Sha512) {
+ let (s, r) = channel();
+ senders.push(s);
+ handles.push(sha512_digest(r));
+ }
// 64 KB chunks will be read from the input at 64 KB and supplied to all hashing threads at once
// Right now that could be up to three threads. If CPU-bound, the other threads will mostly block while the slowest one finishes
})
}
+/// Calculate the sha512 digest of some data on the given channel
+fn sha512_digest(rx: Receiver<Arc<Vec<u8>>>) -> JoinHandle<(Algorithm, Vec<u8>)> {
+ thread::spawn(move || {
+ let mut sha512 = Sha512::new();
+ while let Ok(chunk) = rx.recv() {
+ sha512.update(&*chunk);
+ }
+ let result = sha512.finalize();
+ (Algorithm::Sha512, result.to_vec())
+ })
+}
+
#[cfg(test)]
mod tests {
use super::*;
}
fn write_filename(mut stdout: &mut StandardStream, filename: &str) -> PrintResult {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?;
write!(&mut stdout, "{}", filename_display(filename))?;
stdout.reset()?;
Ok(())
fn write_algorithm(mut stdout: &mut StandardStream, alg: Algorithm) -> PrintResult {
match alg {
Algorithm::Md5 => {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Magenta)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Magenta)).set_bold(true))?;
write!(&mut stdout, "MD5")?;
}
Algorithm::Sha1 => {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)).set_bold(true))?;
write!(&mut stdout, "SHA-1")?;
}
Algorithm::Sha256 => {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
write!(&mut stdout, "SHA-256")?;
}
+ Algorithm::Sha512 => {
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Blue)).set_bold(true))?;
+ write!(&mut stdout, "SHA-512")?;
+ }
}
stdout.reset()?;
Ok(())
fn print_hex_compare(print: &str, against: &str, mut stdout: &mut StandardStream) -> PrintResult {
for (p, a) in print.chars().zip(against.chars()) {
if p == a {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
} else {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)).set_bold(true))?;
}
write!(&mut stdout, "{}", p)?;
}
verify_source: &VerificationSource,
candidate_filename: &Option<String>,
) -> PrintResult {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?;
match &verify_source {
VerificationSource::CommandArgument => {
writeln!(&mut stdout, "command line argument")?;
write!(&mut stdout, "Result: ")?;
match match_level {
MatchLevel::Ok => {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
writeln!(&mut stdout, "OK")?;
}
MatchLevel::Maybe => {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?;
writeln!(&mut stdout, "MAYBE")?;
}
MatchLevel::Fail => {
- stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?;
+ stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)).set_bold(true))?;
writeln!(&mut stdout, "FAIL")?;
}
}
Md5,
Sha1,
Sha256,
+ Sha512,
}
impl Algorithm {
16 => Ok(Algorithm::Md5),
20 => Ok(Algorithm::Sha1),
32 => Ok(Algorithm::Sha256),
+ 64 => Ok(Algorithm::Sha512),
_ => Err(format!("Unrecognised hash length: {} bytes", len)),
}
}
} else {
// If no candidate, calculate all three common digest types for output
let hashes = calculate::create_digests(
- &[Algorithm::Md5, Algorithm::Sha1, Algorithm::Sha256],
+ &[
+ Algorithm::Md5,
+ Algorithm::Sha1,
+ Algorithm::Sha256,
+ Algorithm::Sha512,
+ ],
input,
)?;
for (alg, bytes) in hashes {
let valid_sha1 = "b314c7ebb7d599944981908b7f3ed33a30e78f3a";
let valid_sha1_2 = valid_sha1.to_uppercase();
let valid_sha256 = "1eb85fc97224598dad1852b5d6483bbcf0aa8608790dcc657a5a2a761ae9c8c6";
+ let valid_sha512 = "f4f7de1665cdcd00b2e526da6876f3e06a37da3549e9f880602f64407f602983a571c142eb0de0eacfc9c1d0f534e9339cdce04eb9daddc6ddfa8cf34853beed";
let invalid1 = "x";
let invalid2 = "a";
..
})
));
+ assert!(matches!(
+ read_raw_candidate_from_file(valid_sha512, example_path),
+ Some(CandidateHashes {
+ alg: Algorithm::Sha512,
+ ..
+ })
+ ));
for i in &[invalid1, invalid2, invalid3, invalid4, invalid5] {
assert!(read_raw_candidate_from_file(*i, example_path).is_none());