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}