Skip to main content

diskr/scanner/
hash.rs

1use anyhow::Result;
2use std::fs::File;
3use std::io::{Read, Seek, SeekFrom};
4use std::path::Path;
5
6const QUICK_HASH_BYTES: usize = 64 * 1024;
7
8pub fn quick_hash(path: &Path) -> Result<blake3::Hash> {
9    let mut f = File::open(path)?;
10    let mut buf = vec![0u8; QUICK_HASH_BYTES];
11    let n = f.read(&mut buf)?;
12    Ok(blake3::hash(&buf[..n]))
13}
14
15pub fn full_hash(path: &Path) -> Result<blake3::Hash> {
16    let mut f = File::open(path)?;
17    let mut hasher = blake3::Hasher::new();
18    std::io::copy(&mut f, &mut hasher)?;
19    Ok(hasher.finalize())
20}
21
22pub fn bytes_equal(a: &Path, b: &Path) -> Result<bool> {
23    const CHUNK: usize = 256 * 1024;
24    let mut fa = File::open(a)?;
25    let mut fb = File::open(b)?;
26    fa.seek(SeekFrom::Start(0))?;
27    fb.seek(SeekFrom::Start(0))?;
28    let mut ba = vec![0u8; CHUNK];
29    let mut bb = vec![0u8; CHUNK];
30    loop {
31        let na = fa.read(&mut ba)?;
32        let nb = fb.read(&mut bb)?;
33        if na != nb { return Ok(false); }
34        if na == 0 { return Ok(true); }
35        if ba[..na] != bb[..nb] { return Ok(false); }
36    }
37}