I have a HashMap with different hashing algorithms which implement digest::DynDigest, but when they are looped over and update()d the final hash is always the same (Sha224 d14a...) (you can change the file PathBuf parameter to anything and get the exact same hash every time). So the update() and/or finalize() is not updating the instance in the HashMap.
What is the correct way to loop over the different hashers so that HashMap keeps correct updated state?
use digest::{Digest, DynDigest}; // https://crates.io/crates/digest/reverse_dependencies
use sha2; // implements digest::DynDigest
use std::collections::HashMap;
use std::fs::File;
use std::io;
use std::io::{BufReader, Read};
use std::path::PathBuf;
fn checksum_to_hex(bytes: &[u8]) -> String {
let mut s: String = String::new();
for b in bytes {
s.push_str(format!("{:02x}", b).as_str());
}
s
}
pub fn hash_file(
fpath: PathBuf,
hashers: HashMap<&str, Box<dyn DynDigest>>,
) -> io::Result<HashMap<&str, String>> {
let f = File::open(fpath).expect("failed to open file for hashing");
let mut buffer = [0u8; 1048576];
let mut reader = BufReader::new(f);
loop {
let count = reader.read(&mut buffer)?;
if count == 0 {
break;
}
for (_, mut hasher) in hashers.to_owned() {
hasher.update(&buffer[..count]);
}
}
// Hash results per hasher
let mut hashes: HashMap<&str, String> = HashMap::new();
for (k, hasher) in hashers.to_owned() {
let res = checksum_to_hex(hasher.finalize().to_vec().as_slice());
hashes.insert(k, res);
}
Ok(hashes)
}
fn main() {
let mut hashers: HashMap<&str, Box<dyn DynDigest>> = HashMap::new();
hashers.insert("Sha224", Box::new(sha2::Sha224::new()));
hashers.insert("Sha256", Box::new(sha2::Sha256::new()));
hashers.insert("Sha512", Box::new(sha2::Sha512::new()));
for (htype, hashres) in hash_file(PathBuf::from("/bin/ls"), hashers).expect("") {
println!(" {} {}", htype, hashres);
}
}