chromium_base64_rs/
decode.rs1pub fn base64_decode(data: &[u8]) -> Vec<u8> {
3 let length = data.len();
4
5 let mut data = data.to_vec();
6 if length % 4 == 0 {
7 if data[length - 1] == 61 && data[length - 2] == 61 {
9 data.truncate(length - 2);
10 } else if data[length - 1] == 61 {
11 data.truncate(length - 1);
12 }
13 }
14
15 let allowed_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".as_bytes();
16 let atob_lookup = |ch: i32| {
17 for (i, k) in allowed_chars.iter().enumerate() {
18 if ch == *k as i32 {
19 return i as i32
20 }
21 }
22
23 unreachable!()
24 };
25
26 let mut output: Vec<u8> = Vec::new();
27
28 let mut buffer: i32 = 0;
29 let mut accumulated_bits = 0;
30
31 for ch in data {
32 buffer <<= 6;
33 buffer |= atob_lookup(ch.into());
34
35 accumulated_bits += 6;
36
37 if accumulated_bits == 24 {
38 output.push(((buffer & 0xff0000) >> 16) as u8);
39 output.push(((buffer & 0xff00) >> 8) as u8);
40 output.push((buffer & 0xff) as u8);
41
42 buffer = 0;
43 accumulated_bits = 0;
44 }
45 }
46
47 if accumulated_bits == 12 {
48 buffer >>= 4;
49 output.push(buffer as u8);
50 } else if accumulated_bits == 18 {
51 buffer >>= 2;
52 output.push(((buffer & 0xff00) >> 8) as u8);
53 output.push((buffer & 0xff) as u8);
54 }
55
56 return output;
57}
58
59pub fn base64_decode_to_string(data: &[u8]) -> String {
61 return String::from_utf8_lossy(base64_decode(data).as_slice()).to_string()
62}