将值添加到存储为字节数组的整数

时间:2015-12-31 10:54:25

标签: arrays byte rust

添加(不是追加)值的最佳方法是将数组视为单个整数的字节数组?

例如:

let arr = [0xFF, 0x01, 0xC3, 0x43];

假设arr可以是任何长度。例如,如果我向此添加350,则新数组应为:[0xFF, 0x01, 0xC4, 0xA1]。我提出的解决方案只有在我们递增1时才有效,因此我需要在循环amount次调用该方法,这对于大amount来说效率很低(此示例使用Vec而不是数组):

fn increment_byte_vec(vec: Vec<u8>) -> Vec<u8> {
    let mut done = false;

    vec.iter().rev().map(|&v| {
        if done {
            v
        } else if v == 0xFF {
            0
        } else {
            done = true;
            v + 1
        }
    }).rev().collect::<Vec<_>>()
}

我如何调整上述内容,以便该函数可以采用amount参数?

2 个答案:

答案 0 :(得分:4)

这里不多说;只需添加并携带矢量,就可以回到前面。

数字可能会溢出。我选择了退货;您可能更喜欢扩展矢量。我的解决方案使用了变异,因为它比分配一个新的向量更有效,而且由于我没有改变长度,我认为在一个可变的切片上使用泛型更好。

/// Increments the bytes, assuming the most significant
/// bit is first, and returns the carry.
fn increment_bytes(b256: &mut [u8], mut amount: u64) -> u64 {
    let mut i = b256.len() - 1;

    while amount > 0 {
        amount += b256[i] as u64;
        b256[i] = amount as u8;
        amount /= 256;

        if i == 0 { break; }
        i -= 1;
    }

    amount
}

fn main() {
    let mut input = vec![0xFF, 0x01, 0xC3, 0x43];
    println!("{}", increment_bytes(&mut input, 350));
    println!("{:?}", input);
}

答案 1 :(得分:0)

你基本上是在256中实现和。解决这个问题的一种方法是转换为十进制,添加350并将结果重新转换为256。

即。 [0xFF, 0x01, 0xC3, 0x43]是:

255 (FF) * 256^3 +
1        * 256^2 +
195 (C3) * 256^1 +
67  (43) * 256^0 = 4,278,305,603 (base10)

4,278,305,603 + 350 = 4_278_305_953

现在你需要将它重新转换为基数256.最后一点可能在Rust中看起来像这样:

// warning, does not handle overflows
fn base10_to_256(n: u64) -> [u8; 4] {
    let mut converted_number = [0u8; 4];
    let mut number_to_convert = n;
    let base = 256u64;

    for index in 0.. {
         converted_number[3-index] = (number_to_convert % base) as u8;
         number_to_convert = number_to_convert / base;
         if number_to_convert == 0 { break; }
    }

    converted_number
}

playground