summaryrefslogtreecommitdiff
path: root/server/src/util.rs
blob: 6a0d8d905da9714ab69e15b7ab18a7710939ce52 (plain)
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
26
27
28
29
30
pub fn base64_encode(bytes: &[u8]) -> String {
    const ALPHABET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    let len = (bytes.len() + 2) / 3 * 4;
    let mut dest = Vec::with_capacity(len);
    dest.resize(len, 0u8);
    for i in 0 .. bytes.len() / 3 {
        dest[4 * i + 0] = ALPHABET[(bytes[3 * i + 0] & 0x3f) as usize];
        dest[4 * i + 1] = ALPHABET[(((bytes[3 * i + 0] & 0xc0) >> 6) | ((bytes[3 * i + 1] & 0x0f) << 2)) as usize];
        dest[4 * i + 2] = ALPHABET[(((bytes[3 * i + 1] & 0xf0) >> 4) | ((bytes[3 * i + 2] & 0x03) << 4)) as usize];
        dest[4 * i + 3] = ALPHABET[((bytes[3 * i + 1] & 0xfc) >> 2) as usize];
    }
    let last = bytes.len() / 3;
    match bytes.len() % 3 {
        1 => {
            dest[4 * last + 0] = ALPHABET[(bytes[3 * last + 0] & 0x3f) as usize];
            dest[4 * last + 1] = ALPHABET[((bytes[3 * last + 0] & 0xc0) >> 6) as usize];
            dest[4 * last + 2] = b'=';
            dest[4 * last + 3] = b'=';
        }
        2 => {
            dest[4 * last + 0] = ALPHABET[(bytes[3 * last + 0] & 0x3f) as usize];
            dest[4 * last + 1] = ALPHABET[(((bytes[3 * last + 0] & 0xc0) >> 6) | ((bytes[3 * last + 1] & 0x0f) << 2)) as usize];
            dest[4 * last + 2] = ALPHABET[((bytes[3 * last + 1] & 0xf0) >> 4) as usize];
            dest[4 * last + 3] = b'=';
        }
        _0 => {}
    }
    String::from_utf8(dest).unwrap()
}