use digest::{Digest, FixedOutputReset};
use md5::Md5;
use sha1::Sha1;
use sha2::Sha256;
use sha2::Sha512;
pub trait Hash {
type Hasher: Digest + FixedOutputReset;
fn hasher(&mut self) -> &mut Self::Hasher;
fn generate_from_buf(&mut self, buf: &[u8]) -> String {
let hasher = self.hasher();
hasher.update(buf);
hex::encode(hasher.finalize_reset())
}
fn generate_from_file(&mut self, path: &std::path::Path) -> Result<String, std::io::Error> {
Ok(self.generate_from_buf(std::fs::read(path)?.as_slice()))
}
}
pub struct Md5Hash {
hasher: Md5,
}
impl Md5Hash {
pub fn new() -> Self {
Self { hasher: Md5::new() }
}
}
impl Hash for Md5Hash {
type Hasher = Md5;
fn hasher(&mut self) -> &mut Md5 {
&mut self.hasher
}
}
pub struct Sha1Hash {
hasher: Sha1,
}
impl Sha1Hash {
pub fn new() -> Self {
Self {
hasher: Sha1::new(),
}
}
}
impl Hash for Sha1Hash {
type Hasher = Sha1;
fn hasher(&mut self) -> &mut Sha1 {
&mut self.hasher
}
}
pub struct Sha256Hash {
hasher: Sha256,
}
impl Sha256Hash {
pub fn new() -> Self {
Self {
hasher: Sha256::new(),
}
}
}
impl Hash for Sha256Hash {
type Hasher = Sha256;
fn hasher(&mut self) -> &mut Sha256 {
&mut self.hasher
}
}
pub struct Sha512Hash {
hasher: Sha512,
}
impl Sha512Hash {
pub fn new() -> Self {
Self {
hasher: Sha512::new(),
}
}
}
impl Hash for Sha512Hash {
type Hasher = Sha512;
fn hasher(&mut self) -> &mut Sha512 {
&mut self.hasher
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn generate_md5_from_buf() {
let mut md5 = Md5Hash::new();
let hash_str = md5.generate_from_buf(b"Hello World!");
assert_eq!(hash_str, "ed076287532e86365e841e92bfc50d8c");
}
#[test]
fn generate_sha1_from_buf() {
let mut sha1 = Sha1Hash::new();
let hash_str = sha1.generate_from_buf(b"Hello World!");
assert_eq!(hash_str, "2ef7bde608ce5404e97d5f042f95f89f1c232871");
}
#[test]
fn generate_sha256_from_buf() {
let mut sha256 = Sha256Hash::new();
let hash_str = sha256.generate_from_buf(b"Hello World!");
assert_eq!(
hash_str,
"7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"
);
}
#[test]
fn generate_sha512_from_buf() {
let mut sha512 = Sha512Hash::new();
let hash_str = sha512.generate_from_buf(b"Hello World!");
assert_eq!(
hash_str,
"861844d6704e8573fec34d967e20bcfef3d424cf48be04e6dc08f2bd58c729743371015ead891cc3cf1c9d34b49264b510751b1ff9e537937bc46b5d6ff4ecc8"
);
}
}