1const BASE64_DEC: [u8; 256] = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 62, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 0, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 63, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,];
2pub const BASE64_STANDARD: [u8; 64] = [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F];
3pub const BASE64_URL_SAFE: [u8; 64] = [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F];
4
5pub fn base64_encode(inp: &[u8], table: &[u8; 64]) -> Vec<u8> {
6 let mut out = Vec::new();
7 let mut i = 0;
8 out.resize(inp.len() + inp.len() / 3 + 4, 0u8);
9 let mut o = 0;
10 while i + 2 < inp.len() { let out = &mut out[o..o + 4]; out[0] = table[(inp[i + 0] >> 2) as usize];
13 out[1] = table[((inp[i + 0] & 0x3) << 4 | inp[i + 1] >> 4) as usize];
14 out[2] = table[((inp[i + 1] & 0xf) << 2 | inp[i + 2] >> 6) as usize];
15 out[3] = table[((inp[i + 2] & 0x3f)) as usize];
16 i += 3;
17 o += 4;
18 }
19 out.resize(o, 0u8);
20 let bytes_left = inp.len() - i;
21 if bytes_left == 1 {
22 out.push(table[(inp[i + 0] >> 2) as usize]);
23 out.push(table[((inp[i + 0] & 0x3) << 4) as usize]);
24 }
25 else if bytes_left == 2 {
26 out.push(table[(inp[i + 0] >> 2) as usize]);
27 out.push(table[((inp[i + 0] & 0x3) << 4 | inp[i + 1] >> 4) as usize]);
28 out.push(table[((inp[i + 1] & 0xf) << 2) as usize]);
29 }
30 let end_pad = 3 - inp.len() % 3;
31 if end_pad == 1 {
32 out.push('=' as u8);
33 }
34 else if end_pad == 2 {
35 out.push('=' as u8);
36 out.push('=' as u8);
37 }
38
39 out
40}
41
42#[derive(Debug)]
43pub enum Base64DecodeError {
44 WrongPadding,
45 InvalidCharacter
46}
47
48pub fn base64_decode(input: &[u8]) -> Result<Vec<u8>, Base64DecodeError> {
49 let mut out = Vec::new();
50 out.resize(input.len() * 3 / 4, 0u8);
51 if input.len() & 3 != 0 { return Err(Base64DecodeError::WrongPadding)
53 }
54 let mut o = 0;
55 let mut i = 0;
56 while i < input.len() {
57 let inp = &input[i..i + 4]; let out = &mut out[o..o + 3];
59 let b0 = BASE64_DEC[inp[0] as usize];
60 let b1 = BASE64_DEC[inp[1] as usize];
61 let b2 = BASE64_DEC[inp[2] as usize];
62 let b3 = BASE64_DEC[inp[3] as usize];
63 if b0 == 64 || b1 == 64 || b2 == 64 || b3 == 64 {
64 return Err(Base64DecodeError::InvalidCharacter) }
66 out[0] = (b0 << 2) | (b1 >> 4);
67 out[1] = (b1 & 0xf) << 4 | (b2 >> 2);
68 out[2] = ((b2 & 0x3) << 6) | b3;
69 i += 4;
70 o += 3;
71 }
72 if input[input.len()-2] == '=' as u8{
73 o -= 1;
74 }
75 out.resize(o, 0u8);
76 Ok(out)
77}