I am writing an application that needs to calculate a sha256 digest of some data. The typical way I would do this would be to use a for loop, but since the digest is mutable, I'm running into problems with the borrow checker with the code below. I have no idea how to solve it. Can anyone provide assistance please?
I understand why the problem is occurring (if my understanding is correct, it's multiple borrows of a mutable reference without leaving the loop scope, which is not allowed). I just don't know how to fix it. For other solutions I would collect the values in a vector, then iterate over the vector. In this case, the code needs to run for a value specified by the user. I don't want to collect 10 billion i64 values in a vector before I start iterating.
Note that I haven't managed to compile the code yet, so there may be additional compilation issues. Any assistance would be appreciated.
use std::env;
use std::time::{SystemTime, UNIX_EPOCH};
use sha2::{Sha256,Digest};
use sha2::digest::{Reset, Update};
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Usage: {} num", args[0]);
std::process::exit(1);
}
let val: i64 = args[1].parse().unwrap();
let mut hasher = Sha256::new();
let start_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let mut count: i64 = 0;
for j in 0 .. val {
count = count + j + 1;
let count_string = count.to_string();
let bytes = count_string.as_bytes();
Digest::update(&mut hasher, bytes);
if (j % 1000) == 0 {
let result = hasher.finalize();
if result.len() != 32 {
println!("Error with sha256 algorithm");
} else {
Digest::reset(&mut hasher);
}
}
}
let end_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let diff = end_time - start_time;
println!("count is {} and time taken was {}ms", count, diff);
}
And the compiler says:
error[E0382]: borrow of moved value: `hasher`
--> src/main.rs:22:24
|
14 | let mut hasher = Sha256::new();
| ---------- move occurs because `hasher` has type `CoreWrapper<CtVariableCoreWrapper<Sha256VarCore, UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>, B0>>>`, which does not implement the `Copy` trait
...
22 | Digest::update(&mut hasher, bytes);
| ^^^^^^^^^^^ value borrowed here after move
23 | if (j % 1000) == 0 {
24 | let result = hasher.finalize();
| ---------- `hasher` moved due to this method call, in previous iteration of loop
|
note: this function takes ownership of the receiver `self`, which moves `hasher`
--> /home/fali/.cargo/registry/src/github.com-1ecc6299db9ec823/digest-0.10.3/src/digest.rs:30:17
|
30 | fn finalize(self) -> Output<Self>;
| ^^^^