1use crate::types::DecodingError;
9#[cfg(not(feature = "std"))]
10use alloc::vec::Vec;
11
12pub fn polymod(v: &[u8]) -> u64 {
14 let mut c = 1;
15 for d in v {
16 let c0 = (c >> 35) as u8;
17 c = ((c & 0x07ffffffff) << 5) ^ u64::from(*d);
18 if c0 & 0x01 != 0 {
19 c ^= 0x98f2bc8e61;
20 }
21 if c0 & 0x02 != 0 {
22 c ^= 0x79b76d99e2;
23 }
24 if c0 & 0x04 != 0 {
25 c ^= 0xf33e5fb3c4;
26 }
27 if c0 & 0x08 != 0 {
28 c ^= 0xae2eabe2a8;
29 }
30 if c0 & 0x10 != 0 {
31 c ^= 0x1e4f43e470;
32 }
33 }
34 c ^ 1
35}
36
37pub fn expand_prefix(prefix: &str) -> Vec<u8> {
42 let mut ret: Vec<u8> = prefix.chars().map(|c| (c as u8) & 0x1f).collect();
43 ret.push(0);
44 ret
45}
46
47pub fn convert_bits(
51 data: &[u8], inbits: u8, outbits: u8, pad: bool,
52) -> Result<Vec<u8>, DecodingError> {
53 assert!(inbits <= 8 && outbits <= 8);
54 let num_bytes = (data.len() * inbits as usize + outbits as usize - 1)
55 / outbits as usize;
56 let mut ret = Vec::with_capacity(num_bytes);
57 let mut acc: u16 = 0; let mut num: u8 = 0; let groupmask = (1 << outbits) - 1;
60 for d in data.iter() {
61 acc = (acc << inbits) | u16::from(*d);
63 num += inbits;
64 while num >= outbits {
66 ret.push((acc >> (num - outbits)) as u8);
68 acc &= !(groupmask << (num - outbits));
70 num -= outbits;
71 }
72 }
73 if pad {
74 if num > 0 {
76 ret.push((acc << (outbits - num)) as u8);
77 }
78 } else {
79 let padding = ((data.len() * inbits as usize) % outbits as usize) as u8;
83 if num >= inbits || acc != 0 {
84 return Err(DecodingError::InvalidPadding {
85 from_bits: inbits,
86 padding_bits: padding,
87 padding: acc,
88 });
89 }
90 }
91 Ok(ret)
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 #[cfg(not(feature = "std"))]
98 extern crate alloc;
99 #[cfg(not(feature = "std"))]
100 use alloc::vec;
101
102 #[test]
103 fn test_expand_prefix() {
104 assert_eq!(expand_prefix("cfx"), vec![0x03, 0x06, 0x18, 0x00]);
105
106 assert_eq!(
107 expand_prefix("cfxtest"),
108 vec![0x03, 0x06, 0x18, 0x14, 0x05, 0x13, 0x14, 0x00]
109 );
110
111 assert_eq!(
112 expand_prefix("net17"),
113 vec![0x0e, 0x05, 0x14, 0x11, 0x17, 0x00]
114 );
115 }
116
117 #[test]
118 fn test_convert_bits() {
119 assert_eq!(convert_bits(&[0], 8, 1, false), Ok(vec![0; 8]));
121
122 assert_eq!(convert_bits(&[0], 8, 3, false), Ok(vec![0, 0])); assert_eq!(convert_bits(&[0], 8, 3, true), Ok(vec![0, 0, 0])); assert!(convert_bits(&[1], 8, 3, false).is_err()); assert_eq!(convert_bits(&[1], 8, 3, true), Ok(vec![0, 0, 2])); assert_eq!(convert_bits(&[1], 8, 7, true), Ok(vec![0, 64])); assert_eq!(convert_bits(&[0; 8], 1, 8, false), Ok(vec![0]));
135
136 assert_eq!(convert_bits(&[0, 0, 2], 3, 8, false), Ok(vec![1])); assert_eq!(convert_bits(&[0, 0, 2], 3, 8, true), Ok(vec![1, 0])); assert!(convert_bits(&[0, 0, 3], 3, 8, false).is_err()); assert_eq!(
146 convert_bits(&[0, 1, 2, 3, 4], 8, 5, false),
147 Ok(vec![0, 0, 0, 16, 4, 0, 24, 4])
148 );
149
150 assert!(convert_bits(&[0, 1, 2], 8, 5, false).is_err()); assert_eq!(
155 convert_bits(&[0, 1, 2], 8, 5, true),
156 Ok(vec![0, 0, 0, 16, 4])
157 ); assert_eq!(
162 convert_bits(&[0, 0, 0, 16, 4, 0, 24, 4], 5, 8, false),
163 Ok(vec![0, 1, 2, 3, 4])
164 );
165
166 assert_eq!(
169 convert_bits(&[0, 0, 0, 16, 4], 5, 8, false),
170 Ok(vec![0, 1, 2])
171 ); assert_eq!(
174 convert_bits(&[0, 0, 0, 16, 4], 5, 8, true),
175 Ok(vec![0, 1, 2, 0])
176 ); }
178}