10

I'm computing the SHA256 of a given data:

let hashvalue = sha2::Sha256::digest(&data);

After computing it, I want to put this value into a field of my struct:

let x = Hash { value: hashvalue };

However, the Hash struct expects the type of value [u8; 32], while my hashvalue variable is of type GenericArray<u8, ?>. How can I convert hashvalue into the correct type? I tried to use as [u8; 32] and arr! but it didn't work.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ziva
  • 3,181
  • 15
  • 48
  • 80
  • 1
    It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Dec 17 '19 at 14:50

2 Answers2

12

If you don't know the length of the array, convert the GenericArray into a slice and then convert the slice into an array (only for arrays of length 32 or less before Rust 1.47):

use sha2::Digest; // 0.9.3
use std::convert::TryInto;

fn main() {
    let hashvalue = sha2::Sha256::digest(&[3, 2, 6, 4, 3]);
    let x: [u8; 32] = hashvalue.as_slice().try_into().expect("Wrong length");
    println!("{:?}", x);
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
1

As per the documentation for GenericArray, I assumed that you could use hashvalue.into(), but I did not manage to get it to compile.

Non-idiomatic alternative:

use digest::Digest; // 0.7.6
use generic_array; // 0.13.2
use sha2; // 0.7.1

fn main() {
    let hashvalue = sha2::Sha256::digest(&[3, 2, 6, 4, 3]);
    let x: [u8; 32] = [
        hashvalue[0],
        hashvalue[1],
        hashvalue[2],
        hashvalue[3],
        hashvalue[4],
        hashvalue[5],
        hashvalue[6],
        hashvalue[7],
        hashvalue[8],
        hashvalue[9],
        hashvalue[10],
        hashvalue[11],
        hashvalue[12],
        hashvalue[13],
        hashvalue[14],
        hashvalue[15],
        hashvalue[16],
        hashvalue[17],
        hashvalue[18],
        hashvalue[19],
        hashvalue[20],
        hashvalue[21],
        hashvalue[22],
        hashvalue[23],
        hashvalue[24],
        hashvalue[25],
        hashvalue[26],
        hashvalue[27],
        hashvalue[28],
        hashvalue[29],
        hashvalue[30],
        hashvalue[31],
    ];
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
phimuemue
  • 34,669
  • 9
  • 84
  • 115
  • 1
    That's because `sha2` 0.8 uses `digest` 0.8, which uses `generic-array` 0.12.0 which does not implement `Into` — that's only 0.13. Likely another case of people not specifying the most compatible versions of crates in their Cargo.toml but instead just always picking the newest (even when they could support multiple). – Shepmaster Dec 17 '19 at 16:19
  • 1
    Also, I added versions to your imports assuming you were using the playground. However, note that the playground doesn't have the newest versions of all these crates. If you weren't using the playground, please fix my corrections so that they are accurate. – Shepmaster Dec 17 '19 at 16:22