1use crate::prelude::*;
4pub const BASE64_ALPHABET: &str =
6 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7
8pub fn encode(bytes: &[u8]) -> String {
19 let mut digits = vec![255, 255, 255]
20 .into_iter()
21 .chain(bytes.into_iter().copied().map(Digit::from))
22 .collect::<Vec<_>>();
23 let padding = 3 - ((digits.len() - 1) % 3) - 1;
24 digits.extend(vec![0; padding]);
25 let data_as_int: Loose<256> = digits.iter().copied().collect();
26 let base64_data: Loose<64> = unsafe { data_as_int.convert::<64, Loose<64>>().unsafe_into() };
27 let base64_string = base64_data.display(BASE64_ALPHABET).unwrap();
28 base64_string[4..base64_string.len() - padding].to_string()
29}
30
31pub fn decode(b64_string: impl Into<String>) -> Result<Vec<u8>, BigIntError> {
42 let mut b64_string = b64_string.into();
43 b64_string = format!("////{b64_string}");
44 let padding = 4 - ((b64_string.len() - 1) % 4) - 1;
45 b64_string.extend(vec!['A'; padding]);
46 let string_as_int: Loose<64> = unsafe {
47 Loose::<64>::parse(&b64_string, BASE64_ALPHABET)
48 .map_err(BigIntError::ParseFailed)?
49 .unsafe_into()
50 };
51 let bytes_int: Loose<256> = unsafe { string_as_int.convert::<256, Loose<256>>().unsafe_into() };
52 let bytes = bytes_int
53 .iter()
54 .map(u8::try_from)
55 .collect::<Result<Vec<_>, _>>()
56 .unwrap();
57 let bytes = bytes[3..bytes.len() - padding].to_vec();
58 Ok(bytes)
59}