1use crate::binarytext::BinaryText;
2use crate::error::BinTxtError;
3
4#[derive(Clone, Debug)]
6pub struct Base32 {
7 name: String,
8 lut_enc: [u8; 32],
9 lut_dec: [u8; 128],
10}
11
12impl Base32 {
13 pub fn new() -> Self {
15 let name = "Base32".to_string();
16 let lut_enc = [
17 b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N',
18 b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'2', b'3',
19 b'4', b'5', b'6', b'7',
20 ];
21 let lut_dec = [
22 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
23 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
24 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26, 27,
25 28, 29, 30, 31, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8,
26 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255,
27 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
28 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
29 ];
30 Self {
31 name,
32 lut_enc,
33 lut_dec,
34 }
35 }
36
37 pub fn base32hex() -> Self {
39 let name = "Base32Hex".to_string();
40 let lut_enc = [
41 b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D',
42 b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R',
43 b'S', b'T', b'U', b'V',
44 ];
45 let lut_dec = [
46 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
47 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5,
49 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
50 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53 ];
54 Self {
55 name,
56 lut_enc,
57 lut_dec,
58 }
59 }
60}
61
62impl BinaryText for Base32 {
63 fn base(&self) -> usize {
64 32
65 }
66
67 fn name(&self) -> &str {
68 self.name.as_str()
69 }
70
71 fn n_bytes_encode(&self) -> usize {
72 5
73 }
74
75 fn n_bytes_decode(&self) -> usize {
76 8
77 }
78
79 fn encode_byte(&self, byte: u8) -> Result<u8, BinTxtError> {
80 if byte >= 32 {
81 let msg = format!("Byte {byte} exceeds maximum {}", 32);
82 return Err(BinTxtError::EncodingErr(msg));
83 }
84 Ok(self.lut_enc[byte as usize])
85 }
86
87 fn encode_into_vec(&self, input: &[u8], res: &mut Vec<u8>) -> Result<(), BinTxtError> {
88 let encode_block = |bytes_in: &[u8], bytes_out: &mut [u8]| -> Result<(), BinTxtError> {
89 let pos = bytes_in[0] >> 3;
91 bytes_out[0] = self.encode_byte(pos)?;
92 let pos = ((bytes_in[0] & 0b111) << 2) | (bytes_in[1] >> 6);
93 bytes_out[1] = self.encode_byte(pos)?;
94 let pos = (bytes_in[1] & 0b111110) >> 1;
95 bytes_out[2] = self.encode_byte(pos)?;
96 let pos = ((bytes_in[1] & 0b1) << 4) | (bytes_in[2] >> 4);
97 bytes_out[3] = self.encode_byte(pos)?;
98 let pos = ((bytes_in[2] & 0b1111) << 1) | (bytes_in[3] >> 7);
99 bytes_out[4] = self.encode_byte(pos)?;
100 let pos = (bytes_in[3] & 0b1111100) >> 2;
101 bytes_out[5] = self.encode_byte(pos)?;
102 let pos = ((bytes_in[3] & 0b11) << 3) | (bytes_in[4] >> 5);
103 bytes_out[6] = self.encode_byte(pos)?;
104 let pos = bytes_in[4] & 0b11111;
105 bytes_out[7] = self.encode_byte(pos)?;
106 Ok(())
107 };
108 res.clear();
109 let iter = input.chunks_exact(5);
111 let bytes_rem = iter.remainder();
112 let mut bytes_enc = [0u8; 8];
113 for bytes in iter {
114 encode_block(&bytes, &mut bytes_enc)?;
115 res.extend(&bytes_enc);
116 }
117 if bytes_rem.len() > 0 {
119 let mut bytes = [0u8; 5];
120 for i in 0..bytes_rem.len() {
121 bytes[i] = bytes_rem[i];
122 }
123 encode_block(&bytes, &mut bytes_enc)?;
124 let n_bytes_enc = (bytes_rem.len() * 8) / 5 + 1;
126 for i in n_bytes_enc..8 {
127 bytes_enc[i] = b'=';
128 }
129 res.extend(&bytes_enc);
130 }
131 Ok(())
132 }
133
134 fn decode_byte(&self, byte: u8) -> Result<u8, BinTxtError> {
135 let b = if byte < 128 {
136 self.lut_dec[byte as usize]
137 } else {
138 255
139 };
140 if b < 255 {
141 Ok(b)
142 } else {
143 let errmsg = format!("Invalid byte \"{}\" in Base32 string", byte);
144 Err(BinTxtError::DecodingErr(errmsg))
145 }
146 }
147
148 fn decode_into_vec(&self, input: &[u8], res: &mut Vec<u8>) -> Result<(), BinTxtError> {
149 res.clear();
150 if input.len() == 0 {
151 return Ok(());
152 }
153 let decode_block = |bytes_in: &[u8], bytes_out: &mut [u8]| -> Result<(), BinTxtError> {
155 let dec0 = self.decode_byte(bytes_in[0])?;
157 let dec1 = self.decode_byte(bytes_in[1])?;
158 let dec2 = self.decode_byte(bytes_in[2])?;
159 let dec3 = self.decode_byte(bytes_in[3])?;
160 let dec4 = self.decode_byte(bytes_in[4])?;
161 let dec5 = self.decode_byte(bytes_in[5])?;
162 let dec6 = self.decode_byte(bytes_in[6])?;
163 let dec7 = self.decode_byte(bytes_in[7])?;
164 bytes_out[0] = (dec0 << 3) | (dec1 >> 2);
165 bytes_out[1] = (dec1 << 6) | (dec2 << 1) | (dec3 >> 4);
166 bytes_out[2] = (dec3 << 4) | (dec4 >> 1);
167 bytes_out[3] = (dec4 << 7) | (dec5 << 2) | (dec6 >> 3);
168 bytes_out[4] = (dec6 << 5) | dec7;
169 Ok(())
170 };
171 let rem = input.len() % 8;
173 let pos_last = if rem == 0 {
174 input.len() - 8
175 } else {
176 input.len() - rem
177 };
178 let mut bytes_dec = [0u8; 5];
179 for bytes in input[0..pos_last].chunks_exact(8) {
182 decode_block(&bytes, &mut bytes_dec)?;
183 res.extend(&bytes_dec);
184 }
185 let bytes_rem = &input[pos_last..];
187 let pos_padding = bytes_rem.iter().position(|&x| x == b'=');
189 let bytes = {
191 let mut ret = bytes_rem
192 .iter()
193 .cloned()
194 .map(|x| if x == b'=' { b'A' } else { x })
195 .collect::<Vec<u8>>();
196 ret.resize(8, b'A');
197 ret
198 };
199 decode_block(&bytes, &mut bytes_dec)?;
200 match pos_padding {
201 Some(2) => {
202 res.extend(&bytes_dec[0..1]);
203 }
204 Some(3) => {
205 res.extend(&bytes_dec[0..2]);
206 }
207 Some(4) => {
208 res.extend(&bytes_dec[0..2]);
209 }
210 Some(5) => {
211 res.extend(&bytes_dec[0..3]);
212 }
213 Some(6) => {
214 res.extend(&bytes_dec[0..3]);
215 }
216 Some(7) => {
217 res.extend(&bytes_dec[0..4]);
218 }
219 _ => {
220 res.extend(&bytes_dec);
221 }
222 }
223 Ok(())
224 }
225
226 fn is_decodable(&self, input: &str) -> bool {
227 let rem = input.len() % 8;
228 let pos_last = if rem == 0 {
229 input.len() - 8
230 } else {
231 input.len() - rem
232 };
233 for &byte in input[0..pos_last].as_bytes() {
234 if self.decode_byte(byte).is_err() {
235 return false;
236 }
237 }
238 for &byte in input[pos_last..].as_bytes() {
240 if byte != b'=' && self.decode_byte(byte).is_err() {
241 return false;
242 }
243 }
244 true
245 }
246}