b2sum_rust/
lib.rs

1use blake2_rfc::blake2b::Blake2b;
2use filebuffer::FileBuffer;
3use std::path::Path;
4
5// For Reading Files without use FileBuffer
6use std::fs;
7
8// For Developer:
9// * All outputs are in upper hexadecimal
10// * You can use `as_bytes()` to convert from hexadecimal string to bytes
11// * Blake2b digest size is between 1 and 64 bytes and will always be returned in hexadecimal format as a `String`
12// * One function `read_using_fs()` uses the standard library as opposed to filebuffer to read files.
13
14/// ## Blake2b File Hash Constructor
15/// 
16/// This is the official constructor used to call the new() function with the parameter of the intended digest size.
17/// 
18/// ## Example
19/// 
20/// ```no_run
21/// use b2sum_rust::Blake2bSum;
22/// 
23/// fn main() {
24///     // Creates a new File Instance
25///     let context = Blake2bSum::new(64);
26///     
27///     // Outputs a Hexadecimal String
28///     let hash = context.read("example_file.txt");
29/// 
30///     // Converts the hexadecimal string to a vector of bytes
31///     let _bytes = Blake2bSum::as_bytes(&hash);
32/// 
33///     // Prints The Hexadecimal Representation
34///     println!("Hash: {}",hash);
35/// 
36///     // Asserts That These Are Equal
37///     assert_eq!(hash,"33B20D15383F97EB46D4FA69442596170CCA01008963A7D0E47210C33AEEF991C78323850C012550C227954A40B3D7AD612568ABC73DB9233FAB9EA4F002B0CB");
38/// }
39/// 
40/// ```
41/// 
42/// All outputs are in **UPPER Hexadecimal** and between 1 and 64 bytes.
43#[derive(Debug)]
44pub struct Blake2bSum {
45    digest_size: usize,
46}
47
48impl Blake2bSum {
49    pub fn new(digest: usize) -> Self {
50        if digest > 0 && digest <= 64 {
51            return Blake2bSum {
52                digest_size: digest,
53            }
54        }
55        else {
56            panic!("Digest Size is either too large or too small. It should be 1-64.")
57        }
58    }
59    /// ## Hash File
60    /// This is a function that hashes a file using **Blake2b** and returns the **Hexadecimal Representation** of it as a **String**. It takes as input any reference to Path.
61    /// 
62    /// It should be noted that changes to the file during hashing, such as truncating the file may cause problems.
63    /// 
64    /// ### About Filebuffer
65    /// 
66    /// > Filebuffer can map files into memory. This is often faster than using the primitives in std::io, and also more convenient. Furthermore this crate offers prefetching and checking whether file data is resident in physical memory (so access will not incur a page fault). This enables non-blocking file reading.
67    pub fn read<T: AsRef<Path>>(&self, path: T) -> String {
68
69        // Opens File Using File Buffer
70        let fbuffer = FileBuffer::open(path).expect("failed to open file");
71        
72        // Sets Blake2b Context at the given digest size
73        let mut context = Blake2b::new(self.digest_size);
74        context.update(&fbuffer);
75        let hash = context.finalize();
76        
77        // Return as Upper Hexadecimal Encoded String
78        return hex::encode_upper(hash.as_bytes());
79    }
80    /// ## Hash File (Using Key)
81    /// This is a function that hashes a file (using a key) with **Blake2b** and then returns the **Hexadecimal Representation** of it as a **String**. It takes as input any reference to Path.
82    pub fn read_with_key<T: AsRef<Path>>(&self, path: T, key: &[u8]) -> String {
83
84        // Opens File Using File Buffer
85        let fbuffer = FileBuffer::open(path).expect("failed to open file");
86        
87        // Sets Blake2b Context at the given digest size and hashes with the provided key
88        let mut context = Blake2b::with_key(self.digest_size, key);
89        context.update(&fbuffer);
90        let hash = context.finalize();
91        
92        // Return as Upper Hexadecimal Encoded String
93        return hex::encode_upper(hash.as_bytes());
94    }
95    /// ## Hash File (using standard library)
96    /// **Note: `read()` or `read_with_key()` should be used as opposed to this function.**
97    /// 
98    /// This is a function that hashes a file using **Blake2b** and returns the **Hexadecimal Representation** of it as a **String**. It takes as input any reference to Path.
99    /// 
100    /// This does not use `filebuffer` and instead uses the standard library. Filebuffer is much faster.
101    #[deprecated(
102        note = "Please use the `read()` function instead which uses Filebuffer. This function uses the standard library."
103    )]
104    pub fn read_using_fs<T: AsRef<Path>>(&self, path: T) -> String {
105
106        // Opens File Using Standard Library (fs) and read file to string
107        let fbuffer = fs::read_to_string(path).expect("failed to open file");
108
109        
110        // Sets Blake2b Context at the given digest size
111        let mut context = Blake2b::new(self.digest_size);
112        // Convert str to bytes and updated context
113        context.update(&fbuffer.as_bytes());
114        let hash = context.finalize();
115        
116        // Return as Upper Hexadecimal Encoded String
117        return hex::encode_upper(hash.as_bytes());
118    }
119    /// # Read String
120    /// This function will allow you to take a `String` or `str`, convert it to bytes, then hash it.
121    pub fn read_str<T: AsRef<str>>(&self, string: T) -> String {
122        
123        // Sets Blake2b Context at the given digest size
124        let mut context = Blake2b::new(self.digest_size);
125        // Convert str to bytes
126        context.update(string.as_ref().as_bytes());
127        let hash = context.finalize();
128
129        return hex::encode_upper(hash.as_bytes())
130    }
131    /// # Read Bytes
132    /// This function will allow you to **read bytes** and then **hash the bytes** given the digest size.
133    pub fn read_bytes(&self, bytes: &[u8]) -> String {
134        
135        // Sets Blake2b Context at the given digest size
136        let mut context = Blake2b::new(self.digest_size);
137        context.update(bytes);
138        let hash = context.finalize();
139
140        // Return encoded in upper hexadecimal
141        return hex::encode_upper(hash.as_bytes())
142    }
143    /// ## as_bytes()
144    /// `as_bytes()` converts from a **Hexadecimal String** to a **Vector of Bytes**
145    pub fn as_bytes(s: &str) -> Vec<u8> {
146        return hex::decode(s).unwrap()
147    }
148    /// ## Return Digest Size
149    /// This method will return the provided digest size that the struct contains. It should be between 1 and 64 of type `usize`.
150    pub fn return_digest_size(&self) -> usize {
151        return self.digest_size
152    }
153}