问题
I'm trying to implement iterated SHA256. This works:
use sha2::{Digest, Sha256}; // 0.8.2
fn main() {
let preimage = [42; 80];
let hash = Sha256::digest(&Sha256::digest(&preimage));
}
This doesn't:
use sha2::{Digest, Sha256}; // 0.8.2
fn main() {
let preimage = [42; 80];
let mut hash = preimage;
for _ in 0..2 {
hash = Sha256::digest(&hash);
}
}
I get an error:
error[E0308]: mismatched types
--> src/main.rs:7:16
|
7 | hash = Sha256::digest(&hash);
| ^^^^^^^^^^^^^^^^^^^^^ expected array `[u8; 80]`, found struct `generic_array::GenericArray`
|
= note: expected array `[u8; 80]`
found struct `generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>`
I would like the second style so I can easily re-iterate more than twice.
回答1:
As the compiler tells you, the types have to match to assign a new value to a variable. You can't store a bool
where an i32
should be. An array and a GenericArray
are different types.
Your first attempt might be to make everything a GenericArray
:
use sha2::{Digest, Sha256}; // 0.8.2
use generic_array_0_12_3::GenericArray; // 0.12.3
fn main() {
let mut hash = GenericArray::clone_from_slice(&[42u8; 80]);
for _ in 0..2 {
hash = Sha256::digest(&hash);
}
}
However, this will panic because your input array is 80 elements and the returned GenericArray
must have 32 elements — that's the length of the SHA-256 digest!
Instead, you need to introduce some middle steps and a smidge of indirection:
use sha2::{Digest, Sha256}; // 0.8.2
fn main() {
let input = [42u8; 80];
let mut intermediate;
let mut hash = &input[..];
for _ in 0..2 {
intermediate = Sha256::digest(&hash);
hash = &intermediate[..];
}
}
input
is an array with 80 elements, intermediate
is a GenericArray<u8, 32>
, and hash
is a &[u8]
. Both input
and intermediate
can be viewed as a slice, so hash
counts as a common type between the two.
See also:
- Are polymorphic variables allowed?
- Creating Diesel.rs queries with a dynamic number of .and()'s
回答2:
The probably easiest solution is to pull the first iteration out of the loop:
let preimage = [42; 80];
let mut hash = Sha256::digest(&preimage);
for _ in 1..2 {
hash = Sha256::digest(&hash);
}
(Playground)
This makes hash
a GenericArray
right from the beginning, so the loop works just fine.
来源:https://stackoverflow.com/questions/62678226/how-can-i-iteratively-call-sha256digest-passing-the-previous-result-to-each-s