base_encode/
utils.rs

1#![allow(dead_code)]
2
3pub type Digit = u32;
4pub type DoubleDigit = u64;
5pub const BYTES: usize = 4;
6pub const BITS: usize = BYTES * 8;
7
8pub fn from_bytes_le(bytes: &[u8]) -> Vec<Digit> {
9    bytes.chunks(BYTES).map(|c| {
10        c.iter().rev().fold(0, |a, &x| (a << 8) | x as Digit)
11    }).collect()
12}
13
14pub fn from_bytes_be(bytes: &[u8]) -> Vec<Digit> {
15    let mut bytes = bytes.to_vec();
16    bytes.reverse();
17    from_bytes_le(&bytes)
18}
19
20pub fn to_bytes_le(num: &[Digit]) -> Vec<u8> {
21    let mut bytes: Vec<_> = num.iter().map(|c| {
22        (0..BYTES).map(move |i| (c >> (i * 8)) as u8 & 0xff)
23    }).flatten().collect();
24    bytes.truncate(bytes.iter().rposition(|x| *x != 0).unwrap_or(0) + 1);
25    bytes
26}
27
28pub fn to_bytes_be(num: &[Digit]) -> Vec<u8> {
29    let mut bytes = to_bytes_le(num);
30    bytes.reverse();
31    bytes
32}
33
34pub fn add(num: &mut Vec<Digit>, x: DoubleDigit) {
35    let mut carry = x;
36    for d in num.iter_mut() {
37        carry += *d as DoubleDigit;
38        *d = carry as Digit;
39        carry >>= BITS;
40        if carry == 0 { break }
41    }
42    if carry != 0 { num.push(carry as Digit) }
43}
44
45pub fn mul(num: &mut Vec<Digit>, x: DoubleDigit) {
46    let mut carry = 0;
47    for d in num.iter_mut() {
48        carry += *d as DoubleDigit * x;
49        *d = carry as Digit;
50        carry >>= BITS;
51    }
52    if carry != 0 { num.push(carry as Digit) }
53}
54
55pub fn div_rem(num: &mut Vec<Digit>, x: DoubleDigit) -> Digit {
56    let mut rem = 0;
57    for d in num.iter_mut().rev() {
58        let a = *d as DoubleDigit | (rem << BITS);
59        *d = (a / x) as Digit;
60        rem = a % x;
61    }
62    num.truncate(num.iter().rposition(|x| *x != 0).unwrap_or(0) + 1);
63    rem as Digit
64}