use rand::RngCore;
use sha2::{Digest, Sha256};
pub fn hash(input: &str) -> String {
let digest = Sha256::digest(input.as_bytes());
hex(&digest)
}
pub fn random_hex(bytes: usize) -> String {
let mut buf = vec![0u8; bytes];
rand::thread_rng().fill_bytes(&mut buf);
hex(&buf)
}
pub fn generate_code() -> String {
let mut buf = [0u8; 4];
rand::thread_rng().fill_bytes(&mut buf);
let n = u32::from_be_bytes(buf) % 100_000_000;
format!("{n:08}")
}
fn hex(bytes: &[u8]) -> String {
use std::fmt::Write;
let mut s = String::with_capacity(bytes.len() * 2);
for b in bytes {
let _ = write!(s, "{b:02x}");
}
s
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hash_is_stable_and_hex() {
let h = hash("hello");
assert_eq!(h.len(), 64);
assert_eq!(h, hash("hello"));
assert_ne!(h, hash("hell0"));
}
#[test]
fn code_is_8_digits() {
let c = generate_code();
assert_eq!(c.len(), 8);
assert!(c.chars().all(|c| c.is_ascii_digit()));
}
#[test]
fn random_hex_len() {
assert_eq!(random_hex(32).len(), 64);
assert_ne!(random_hex(16), random_hex(16));
}
}