use std::path::Path;
use sha2::{Digest, Sha256};
use tokio::{fs::File, io::AsyncReadExt};
use crate::constants::hash as hash_const;
use crate::error::Result;
pub async fn compute_file_hash(path: &Path) -> Result<String> {
let mut file = File::open(path).await?;
let mut hasher = Sha256::new();
let mut buf = vec![0u8; hash_const::HASH_BUFFER_SIZE];
loop {
let n = file.read(&mut buf).await?;
if n == 0 {
break;
}
hasher.update(&buf[..n]);
}
let result = hasher.finalize();
Ok(hex::encode(result))
}
pub fn compute_hash(data: &[u8]) -> String {
let mut hasher = Sha256::new();
hasher.update(data);
hex::encode(hasher.finalize())
}
pub fn hashes_match(hash1: &str, hash2: &str) -> bool {
hash1.eq_ignore_ascii_case(hash2)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_compute_hash() {
let data = b"hello world";
let hash = compute_hash(data);
assert_eq!(
hash,
"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
);
}
#[test]
fn test_hashes_match() {
assert!(hashes_match("ABC123", "abc123"));
assert!(hashes_match("abc123", "ABC123"));
assert!(!hashes_match("abc123", "abc124"));
}
}