]> code.octet-stream.net Git - hashgood/commitdiff
Add support for SHA512 and make colours brighter
authorThomas Karpiniec <tom.karpiniec@outlook.com>
Sat, 7 Dec 2024 00:27:08 +0000 (13:27 +1300)
committerThomas Karpiniec <tom.karpiniec@outlook.com>
Sat, 7 Dec 2024 00:27:08 +0000 (13:27 +1300)
src/calculate.rs
src/display.rs
src/main.rs
src/verify.rs

index 5928c52fa30bf2dda063c26866dedd4af783504b..3ba5a7d0538be39b45a5616386e8082aebbb566f 100644 (file)
@@ -2,6 +2,7 @@ use super::Algorithm;
 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::*;
@@ -57,6 +58,11 @@ pub fn create_digests(algorithms: &[Algorithm], mut input: Box<dyn Read>) -> Cal
         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
@@ -115,6 +121,18 @@ fn sha256_digest(rx: Receiver<Arc<Vec<u8>>>) -> JoinHandle<(Algorithm, Vec<u8>)>
     })
 }
 
+/// 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::*;
index b886a111f909f5705140226cce010e4330ee2ba2..fe43dd79cb53240fa887810bd9e68c66473b5f1e 100644 (file)
@@ -21,7 +21,7 @@ fn get_stdout(no_colour: bool) -> StandardStream {
 }
 
 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(())
@@ -30,17 +30,21 @@ fn write_filename(mut stdout: &mut StandardStream, filename: &str) -> PrintResul
 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(())
@@ -49,9 +53,9 @@ fn write_algorithm(mut stdout: &mut StandardStream, alg: Algorithm) -> PrintResu
 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)?;
     }
@@ -65,7 +69,7 @@ fn write_source(
     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")?;
@@ -170,15 +174,15 @@ pub fn print_match_level(match_level: MatchLevel, no_colour: bool) -> PrintResul
     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")?;
         }
     }
index ff5a00cbf83d5d64861c8f3deaab1a6be84e6c42..cc9c570f37520c1e2b355f18ed21ded06f02693c 100644 (file)
@@ -43,6 +43,7 @@ pub enum Algorithm {
     Md5,
     Sha1,
     Sha256,
+    Sha512,
 }
 
 impl Algorithm {
@@ -52,6 +53,7 @@ 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)),
         }
     }
@@ -168,7 +170,12 @@ fn hashgood() -> Result<(), Box<dyn Error>> {
     } 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 {
index e655d1a5052024a33d82079098f3edc82614be9c..77120da502a441d7d3ca656f4cf26c2b50e80f0c 100644 (file)
@@ -254,6 +254,7 @@ mod tests {
         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";
@@ -289,6 +290,13 @@ mod tests {
                 ..
             })
         ));
+        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());