Weekly Rust Trivia is a problem-oriented series of articles that assist developers while learning Rust. Every article solves simple, everyday development tasks using the Rust standard library or leveraging popular and proven crates.
Question: How to compute a SHA256
hash of a file in Rust?
The sha2
crate is an implementation of cryptographic hash algorithms that we can use to compute hashes. We can combine functionality provided by the crate with the fs
and io
modules from Rusts standard library to solve this trivia. We also use the anyhow
crate, to streamline error handling.
First let’s add the following dependencies using cargo add
:
# Add anyhow as dependency
cargo add anyhow
# Add the sha2 crate as dependency
cargo add sha2
Having the crates added to our project, we can move on and implement creating the SHA256
hash of a file:
use std::{fs::File, io::Read};
use anyhow::Result;
use sha2::{Sha256, Digest};
fn compute_sha256_hash_of_file(file: &str) -> Result<String> {
// Open the file
let mut file = File::open(file)?;
// Create a SHA-256 "hasher"
let mut hasher = Sha256::new();
// Read the file in 4KB chunks and feed them to the hasher
let mut buffer = [0; 4096];
loop {
let bytes_read = file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
hasher.update(&buffer[..bytes_read]);
}
// Finalize the hash and get the result as a byte array
Ok(format!("{:x}", hasher.finalize()))
}
The compute_sha256_hash_of_file
function takes a file path as an argument and returns a anyhow::Result<String>
containing computed hash if the operation was successful. If any error occurs, the Error
variant is returned instead. The function starts by opening the file using the File::open()
method, and then creates a SHA-256 hasher using the Sha256::new()
method from the sha2
crate. The function then reads the file in 4KB chunks and feeds them to the hasher using the update()
method. Finally, the function finalizes the hash and gets the result as a byte array, which is then formatted as a hexadecimal string and returned as part of the Result object.
We can use the compute_sha256_hash_of_file
as shown below:
fn main() {
match compute_sha256_hash_of_file("Cargo.toml") {
Ok(hash) => println!("Hash: {}", hash),
Err(e) => println!("Error: {}", e),
}
}