1#[cfg(not(feature = "std"))]
2use alloc::vec::Vec;
3use bigint::BigUint;
4
5pub(crate) fn encode<T>(alpha: &[T], input: &[u8]) -> Vec<T>
6where
7 T: Copy,
8{
9 if input.is_empty() {
10 return Vec::new();
11 }
12
13 let base = alpha.len() as u32;
14
15 let mut big = BigUint::from_bytes_be(input);
17 let mut out = Vec::with_capacity(input.len());
18
19 let big_pow = 32 / (32 - base.leading_zeros());
21 let big_base = base.pow(big_pow);
22
23 'fast: loop {
24 let mut big_rem = big.div_mod(big_base);
31
32 if big.is_zero() {
33 loop {
34 let (result, remainder) = (big_rem / base, big_rem % base);
35 out.push(alpha[remainder as usize]);
36 big_rem = result;
37
38 if big_rem == 0 {
39 break 'fast; }
41 }
42 } else {
43 for _ in 0..big_pow {
44 let (result, remainder) = (big_rem / base, big_rem % base);
45 out.push(alpha[remainder as usize]);
46 big_rem = result;
47 }
48 }
49 }
50
51 let leaders = input
52 .iter()
53 .take(input.len() - 1)
54 .take_while(|i| **i == 0)
55 .map(|_| alpha[0]);
56
57 out.extend(leaders);
58 out
59}