如何在没有结果的情况下将 sha256 的前 128 位作为 u128 获取?

How to get first 128 bits of sha256 as u128, without a Result?

这可行,但非常复杂:

let mut hasher = Sha256::new();
hasher.update(foo);
hasher.update(bar);
let hash = hasher.finalize();
let hash_array: [u8; 16] = hash[0..16].try_into().expect("slice with incorrect length");
let hash128 = u128::from_le_bytes(hash_array);

有没有办法做到这一点而无需:

let hash_array: [u8; 16] = hash[0..16].try_into().expect("slice with incorrect length");

我正在处理一个不可能发生的情况,因为我知道 sha256 会产生 32 个字节。我怎样才能告诉编译器?

有一种方法,但目前有点复杂:Rust 数组和 GenericArray deref' 到切片,所以这就是你切片时得到的 (hash[..16]),然后需要一个由于编译时长度信息丢失,无法转换回数组。

但是 GenericArray<T,N>实现了AsRef<[T;N]>并且数组是Copy,所以从GenericArray你可以很容易地得到一个相同大小的数组(通过取消引用引用),因此问题是当切片不起作用时如何获得适当大小的 GenericArray

原来 generic_array 提供了 a split。我想我在使用它时遗漏了一些东西,因为它有点粗糙,但你去吧:

    let hasher = Sha256::new();
    let hash = hasher.finalize();
    let (head, _): (GenericArray<_, U16>, _) = Split::split(hash);
    let hash128 = u128::from_le_bytes(*head.as_ref());

(注意:我故意使用 Split::split 的 UFCS 形式而不是方法形式来限制与 slice::split 的混淆)。