ohash/
lib.rs

1use std::fs::File;
2use std::io::{Read, Seek, SeekFrom, BufReader};
3use std::mem;
4
5/// Defines the size of the blocks used to create the hash
6pub const HASH_BLK_SIZE: u64 = 65536;
7
8/// Creates a hash for a file
9/// # Example:
10/// ```
11/// use std::fs::File;
12/// use media_hasher::{HASH_BLK_SIZE, create_hash};
13/// let file = File::open("breakdance.avi").unwrap();
14/// let fsize = file.metadata().unwrap().len();
15/// let fhash = create_hash(file, fsize).unwrap();
16/// assert_eq!(fhash, "8e245d9679d31e12");
17/// ```
18
19pub fn create_hash(file: File, fsize: u64) -> Result<String, std::io::Error> {
20
21    let mut buf = [0u8; 8];
22    let mut word: u64;
23
24    let mut hash_val: u64 = fsize;  // seed hash with file size
25
26    let iterations = HASH_BLK_SIZE /  8;
27
28    let mut reader = BufReader::with_capacity(HASH_BLK_SIZE as usize, file);
29
30    for _ in 0..iterations {
31        reader.read(&mut buf)?;
32        unsafe { word = mem::transmute(buf); };
33        hash_val = hash_val.wrapping_add(word);
34    }
35
36    reader.seek(SeekFrom::Start(fsize - HASH_BLK_SIZE))?;
37
38    for _ in 0..iterations {
39        reader.read(&mut buf)?;
40        unsafe { word = mem::transmute( buf); };
41        hash_val = hash_val.wrapping_add(word);
42    }
43
44    let hash_string = format!("{:01$x}", hash_val, 16);
45
46    Ok(hash_string)
47}
48