use sha2::{Digest as _, Sha256};
const HEX_TABLE: &[u8; 16] = b"0123456789abcdef";
pub fn encode(bytes: &[u8]) -> String {
let mut buf = Vec::with_capacity(bytes.len() * 2);
for &b in bytes {
buf.push(HEX_TABLE[(b >> 4) as usize]);
buf.push(HEX_TABLE[(b & 0x0f) as usize]);
}
unsafe { String::from_utf8_unchecked(buf) }
}
pub fn sha256(data: impl AsRef<[u8]>) -> String {
encode(&Sha256::digest(data.as_ref()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encode_empty() {
assert_eq!(encode(b""), "");
}
#[test]
fn encode_known_bytes() {
assert_eq!(encode(b"\xde\xad\xbe\xef"), "deadbeef");
}
#[test]
fn encode_all_zeros() {
assert_eq!(encode(&[0u8; 4]), "00000000");
}
#[test]
fn encode_sequential() {
assert_eq!(
encode(&[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]),
"0123456789abcdef"
);
}
}