首页 > 解决方案 > 如何迭代地调用 Sha256::digest,将先前的结果传递给每个后续调用?

问题描述

我正在尝试实现迭代的 SHA256。这有效:

use sha2::{Digest, Sha256}; // 0.8.2

fn main() {
    let preimage = [42; 80];
    let hash = Sha256::digest(&Sha256::digest(&preimage));
}

这不会:

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);
    }
}

我收到一个错误:

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>>`

我想要第二种风格,这样我就可以轻松地重复两次以上。

标签: rust

解决方案


正如编译器告诉您的那样,类型必须匹配才能为变量分配新值。你不能存储 a应该在的bool地方。i32数组和 aGenericArray是不同的类型。

您的第一次尝试可能是让一切都成为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);
    }
}

但是,这会引起恐慌,因为您的输入数组是 80 个元素,并且返回的GenericArray必须有 32 个元素——这就是 SHA-256 摘要的长度!

相反,您需要引入一些中间步骤和一点间接性:

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是一个包含 80 个元素的数组,intermediate是 a GenericArray<u8, 32>,并且hash是 a &[u8]。两者inputintermediate都可以看成一个切片,所以hash算作两者之间的共同类型。

也可以看看:


推荐阅读