Skip to main content

neco_base64/
encode.rs

1const STANDARD_TABLE: &[u8; 64] =
2    b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3const URL_TABLE: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
4
5fn encode_with_table(input: &[u8], table: &[u8; 64], pad: bool) -> String {
6    let mut output = String::with_capacity(input.len().div_ceil(3) * 4);
7    let mut i = 0;
8
9    while i + 3 <= input.len() {
10        let block =
11            ((input[i] as u32) << 16) | ((input[i + 1] as u32) << 8) | (input[i + 2] as u32);
12        output.push(table[((block >> 18) & 0x3f) as usize] as char);
13        output.push(table[((block >> 12) & 0x3f) as usize] as char);
14        output.push(table[((block >> 6) & 0x3f) as usize] as char);
15        output.push(table[(block & 0x3f) as usize] as char);
16        i += 3;
17    }
18
19    let remainder = input.len() - i;
20    if remainder == 1 {
21        let block = (input[i] as u32) << 16;
22        output.push(table[((block >> 18) & 0x3f) as usize] as char);
23        output.push(table[((block >> 12) & 0x3f) as usize] as char);
24        if pad {
25            output.push_str("==");
26        }
27    } else if remainder == 2 {
28        let block = ((input[i] as u32) << 16) | ((input[i + 1] as u32) << 8);
29        output.push(table[((block >> 18) & 0x3f) as usize] as char);
30        output.push(table[((block >> 12) & 0x3f) as usize] as char);
31        output.push(table[((block >> 6) & 0x3f) as usize] as char);
32        if pad {
33            output.push('=');
34        }
35    }
36
37    output
38}
39
40/// Encode bytes as standard Base64 with padding.
41pub fn encode(input: &[u8]) -> String {
42    encode_with_table(input, STANDARD_TABLE, true)
43}
44
45/// Encode bytes as URL-safe Base64 without padding.
46pub fn encode_url(input: &[u8]) -> String {
47    encode_with_table(input, URL_TABLE, false)
48}
49
50/// Encode bytes as URL-safe Base64 with padding.
51pub fn encode_url_padded(input: &[u8]) -> String {
52    encode_with_table(input, URL_TABLE, true)
53}