gpt4 book ai didi

rust - 将存储在 u32 数组中的大数转换为字节并返回

转载 作者:行者123 更新时间:2023-11-29 08:02:27 25 4
gpt4 key购买 nike

我正在用 Rust 做一些计算数学,我有一些大数字存储在一个包含 24 个值的数组中。我有将它们转换为字节并返回的函数,但它对 u32 值效果不佳,而对 u64 效果很好。代码示例如下:

fn main() {
let mut bytes = [0u8; 96]; // since u32 is 4 bytes in my system, 4*24 = 96
let mut j;
let mut k: u32;

let mut num: [u32; 24] = [1335565270, 4203813549, 2020505583, 2839365494, 2315860270, 442833049, 1854500981, 2254414916, 4192631541, 2072826612, 1479410393, 718887683, 1421359821, 733943433, 4073545728, 4141847560, 1761299410, 3068851576, 1582484065, 1882676300, 1565750229, 4185060747, 1883946895, 4146];
println!("original_num: {:?}", num);

for i in 0..96 {
j = i / 4;
k = (i % 4) as u32;
bytes[i as usize] = (num[j as usize] >> (4 * k)) as u8;
}

println!("num_to_ytes: {:?}", &bytes[..]);
num = [0u32; 24];

for i in 0..96 {
j = i / 4;
k = (i % 4) as u32;
num[j as usize] |= (bytes[i as usize] as u32) << (4 * k);
}

println!("recovered_num: {:?}", num);
}

Rust playground

上面的代码没有从字节数组中检索到正确的数字。但是,如果我将所有 u32 更改为 u64,将所有 4 更改为 8,并减小num 从 24 个值到 12 个,一切正常。我假设我对 u32 版本有一些逻辑问题。可以在 this Rust playground 中找到正确工作的 u64 版本.

最佳答案

学习如何创建 MCVE是编程时的一项重要技能。例如,你为什么要有一个数组?为什么要重用变量?

你原来的第一个数字是0x4F9B1BD6,输出的第一个数字是0x000B1BD6

比较中间字节表明你有垃圾:

let num = 0x4F9B1BD6_u32;
println!("{:08X}", num);

let mut bytes = [0u8; BYTES_PER_U32];
for i in 0..bytes.len() {
let k = (i % BYTES_PER_U32) as u32;
bytes[i] = (num >> (4 * k)) as u8;
}

for b in &bytes {
print!("{:X}", b);
}
println!();
4F9B1BD6
D6BD1BB1

打印出 k 的值:

for i in 0..bytes.len() {
let k = (i % BYTES_PER_U32) as u32;
println!("{} / {}", k, 4 * k);
bytes[i] = (num >> (4 * k)) as u8;
}

显示您正在尝试移动 4 位的倍数:

0 / 0
1 / 4
2 / 8
3 / 12

我很确定当今每个常见平台都使用 8 位来表示一个字节,而不是 4

这就是为什么魔数(Magic Number)不好。如果您对这些值使用常量,您会更快地注意到这个问题。

since u32 is 4 bytes in my system

u32更好每个系统上都是 4 个字节 — 这就是为什么它是 u32/em>。


总的来说,不要重新发明轮子。使用 byteorder crate 或等价物:

extern crate byteorder;

use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

const LENGTH: usize = 24;
const BYTES_PER_U32: usize = 4;

fn main() {
let num: [u32; LENGTH] = [
1335565270, 4203813549, 2020505583, 2839365494, 2315860270, 442833049, 1854500981,
2254414916, 4192631541, 2072826612, 1479410393, 718887683, 1421359821, 733943433,
4073545728, 4141847560, 1761299410, 3068851576, 1582484065, 1882676300, 1565750229,
4185060747, 1883946895, 4146,
];
println!("original_num: {:?}", num);

let mut bytes = [0u8; LENGTH * BYTES_PER_U32];
{
let mut bytes = &mut bytes[..];
for &n in &num {
bytes.write_u32::<BigEndian>(n).unwrap();
}
}

let mut num = [0u32; LENGTH];
{
let mut bytes = &bytes[..];
for n in &mut num {
*n = bytes.read_u32::<BigEndian>().unwrap();
}
}

println!("recovered_num: {:?}", num);
}

关于rust - 将存储在 u32 数组中的大数转换为字节并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48158788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com