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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
static ALPHABET64:&'static[char]=&[
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
    'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
    '0','1','2','3','4','5','6','7','8','9','+','/'
];

pub struct B64<T>(T);

pub trait B64Encode<I,O>{
    fn encode(data:I)->O;
}

pub trait B64Decode<I,O>{
    fn decode(data:I)->O;
}

impl B64Encode<String,String> for B64<String>{
    fn encode(data:String)->String{
        let n=data.into_bytes();
        let mut s=String::with_capacity(n.len()/3*4+if n.len()%3!=0 {1} else {0});
        let mut index=0;

        for _ in 0..n.len()/3{
            s.push(ALPHABET64[(n[index]>>2) as usize]);
            s.push(ALPHABET64[(((n[index]&0b00000011)<<4)|{index+=1;((n[index]&0b11110000)>>4)}) as usize]);
            s.push(ALPHABET64[(((n[index]&0b00001111)<<2)|{index+=1;((n[index]&0b11000000)>>6)}) as usize]);
            s.push(ALPHABET64[(n[index]&0b00111111) as usize]);
            index+=1;
        }

        match n.len()%3{
            1 => {
                s.push(ALPHABET64[(n[index]>>2) as usize]);
                s.push(ALPHABET64[((n[index]&0b00000011)<<4) as usize]);
                s.push('=');
                s.push('=');
            },
            2 => {
                s.push(ALPHABET64[(n[index]>>2) as usize]);
                s.push(ALPHABET64[(((n[index]&0b00000011)<<4)|{index+=1;((n[index]&0b11110000)>>4)}) as usize]);
                s.push(ALPHABET64[((n[index]&0b00001111)<<2) as usize]);
                s.push('=');
            },
            _ => {}
        }
        return  s;
    }
}