Skip to main content

codec_eval/corpus/
checksum.rs

1//! Checksum computation for image files.
2
3use std::fs::File;
4use std::io::{BufReader, Read};
5use std::path::Path;
6
7use crate::error::Result;
8
9/// Compute a checksum for a file.
10///
11/// Uses a fast hash (FNV-1a) suitable for deduplication.
12pub fn compute_checksum(path: &Path) -> Result<String> {
13    let file = File::open(path)?;
14    let mut reader = BufReader::new(file);
15    let mut buffer = [0u8; 8192];
16
17    // FNV-1a 64-bit hash
18    let mut hash: u64 = 0xcbf29ce484222325;
19    const FNV_PRIME: u64 = 0x100000001b3;
20
21    loop {
22        let bytes_read = reader.read(&mut buffer)?;
23        if bytes_read == 0 {
24            break;
25        }
26
27        for &byte in &buffer[..bytes_read] {
28            hash ^= u64::from(byte);
29            hash = hash.wrapping_mul(FNV_PRIME);
30        }
31    }
32
33    Ok(format!("{hash:016x}"))
34}
35
36/// Compute a checksum for in-memory data.
37#[must_use]
38#[allow(dead_code)] // Used in tests, may be useful for API consumers
39pub fn compute_checksum_bytes(data: &[u8]) -> String {
40    let mut hash: u64 = 0xcbf29ce484222325;
41    const FNV_PRIME: u64 = 0x100000001b3;
42
43    for &byte in data {
44        hash ^= u64::from(byte);
45        hash = hash.wrapping_mul(FNV_PRIME);
46    }
47
48    format!("{hash:016x}")
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_checksum_bytes() {
57        let data = b"hello world";
58        let checksum = compute_checksum_bytes(data);
59        assert_eq!(checksum.len(), 16);
60
61        // Same data should produce same checksum
62        let checksum2 = compute_checksum_bytes(data);
63        assert_eq!(checksum, checksum2);
64
65        // Different data should produce different checksum
66        let checksum3 = compute_checksum_bytes(b"hello world!");
67        assert_ne!(checksum, checksum3);
68    }
69
70    #[test]
71    fn test_checksum_empty() {
72        let checksum = compute_checksum_bytes(b"");
73        assert_eq!(checksum.len(), 16);
74    }
75}