use sha2::{Digest, Sha256};
use std::fmt::Write as _;
#[derive(Clone, Default)]
pub struct Sha256Hasher {
inner: Sha256,
}
impl Sha256Hasher {
#[must_use]
pub fn new() -> Self {
Self {
inner: Sha256::new(),
}
}
pub fn update(&mut self, bytes: &[u8]) {
self.inner.update(bytes);
}
#[must_use]
pub fn finalize_hex(self) -> String {
let digest = self.inner.finalize();
let mut out = String::with_capacity(digest.len() * 2);
for byte in digest {
let _ = write!(out, "{byte:02x}");
}
out
}
}
#[must_use]
pub fn sha256_hex(bytes: &[u8]) -> String {
let mut hasher = Sha256Hasher::new();
hasher.update(bytes);
hasher.finalize_hex()
}
#[cfg(test)]
mod tests {
use super::sha256_hex;
#[test]
fn sha256_hex_matches_known_vector() {
assert_eq!(
sha256_hex(b"abc"),
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
);
}
#[test]
fn sha256_hex_is_64_hex_chars() {
let digest = sha256_hex(b"toven");
assert_eq!(digest.len(), 64);
assert!(
digest
.bytes()
.all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b))
);
}
}