42 lines
1.2 KiB
Rust
42 lines
1.2 KiB
Rust
use digest::{Digest, DynDigest};
|
|
use std::{fs::File, io::Read, path::Path};
|
|
|
|
pub const DEFAULT_HASHER: &str = "sha3-512";
|
|
|
|
pub fn find_hasher(s: &str) -> std::io::Result<Box<dyn DynDigest>> {
|
|
match s {
|
|
"sha3-512" => Ok(Box::new(sha3::Sha3_512::new())),
|
|
_ => Err(std::io::ErrorKind::InvalidInput.into()),
|
|
}
|
|
}
|
|
|
|
pub fn hash_reader<R: Read>(hasher_name: &str, reader: &mut R) -> std::io::Result<String> {
|
|
let mut buf = [0u8; 1024];
|
|
let mut hasher = find_hasher(hasher_name)?;
|
|
loop {
|
|
let n = reader.read(&mut buf)?;
|
|
hasher.update(&buf[..n]);
|
|
if n == 0 {
|
|
break;
|
|
}
|
|
}
|
|
Ok(format!(
|
|
"{hasher_name}:{}",
|
|
const_hex::encode(hasher.finalize()),
|
|
))
|
|
}
|
|
|
|
pub fn verify_reader<R: Read>(reader: &mut R, expected: &str) -> std::io::Result<bool> {
|
|
let hasher = expected.split(':').next().unwrap();
|
|
let hash = hash_reader(hasher, reader)?;
|
|
Ok(hash == expected)
|
|
}
|
|
|
|
pub fn hash_file<P: AsRef<Path>>(hasher: &str, path: P) -> std::io::Result<String> {
|
|
hash_reader(hasher, &mut File::open(path)?)
|
|
}
|
|
|
|
pub fn verify_file<P: AsRef<Path>>(path: P, expected: &str) -> std::io::Result<bool> {
|
|
verify_reader(&mut File::open(path)?, expected)
|
|
}
|