如何将 u32 数组就地转换为 u8 数组?

lig*_*ity 0 rust

我想将 a 转换[u32; 4]为 a [u8; 16]

我知道可以使用按位运算u8从 4 中得到 16 u32。但我想就地转换数组。如何使用安全 Rust 或不安全 Rust 来做到这一点?

let buffer: [u32; 4] = [1, 2, 3, 4];
let hash: [u8; 16]; // how to convert from buffer to hash?
Run Code Online (Sandbox Code Playgroud)

背景信息:我正在计算一个 128 位哈希值,其中[u32; 4]是一个保存 4 的缓冲区u32。我想将数组转换为 a [u8; 16],作为最终的哈希值。

rod*_*igo 7

您可能想做一个转换,但我建议不要这样做,主要是因为字节序,即最终输出将取决于您的机器是大端还是小端:

pub fn convert(data: &[u32; 4]) -> [u8; 16] {
    unsafe { std::mem::transmute(*data) }
}
Run Code Online (Sandbox Code Playgroud)

相反,我只是用无聊的方式来做(游乐场)

pub fn convert(data: &[u32; 4]) -> [u8; 16] {
    let mut res = [0; 16];
    for i in 0..4 {
        res[4*i..][..4].copy_from_slice(&data[i].to_le_bytes());
    }
    res
}
Run Code Online (Sandbox Code Playgroud)

如果您需要大端字节序,请更改to_le_bytes()为。to_be_bytes()或者to_ne_bytes()如果您不关心的话,可以使用它来获取本机字节序。

如果您担心性能(但为什么要担心呢?),x86_64使用本机字节序生成的代码是最好的:

playground::convert:
    movq    %rdi, %rax
    movups  (%rsi), %xmm0
    movups  %xmm0, (%rdi)
    retq
Run Code Online (Sandbox Code Playgroud)