base64编码原理
base64编码按照三个字节为一组,编码成四个字节。如果不够三个字节,则两个字节编码成三个字节加上一个‘=’,一个字节编码成两个字节加上‘==’。
首先将三个字节转换成二进制,共24位。然后,将24位分成四组,每组6个位,并在前面添加00,组成一个字节,共四个字节。由于分成的四个字节只有6位,故最大小于64。然后,按照表,将分成的四个字节代换成可打印字符。
代换表为
0 : A
1 : B
2 : C
3 : D
4 : E
5 : F
6 : G
7 : H
8 : I
9 : J
10 : K
11 : L
12 : M
13 : N
14 : O
15 : P
16 : Q
17 : R
18 : S
19 : T
20 : U
21 : V
22 : W
23 : X
24 : Y
25 : Z
26 : a
27 : b
28 : c
29 : d
30 : e
31 : f
32 : g
33 : h
34 : i
35 : j
36 : k
37 : l
38 : m
39 : n
40 : o
41 : p
42 : q
43 : r
44 : s
45 : t
46 : u
47 : v
48 : w
49 : x
50 : y
51 : z
52 : 0
53 : 1
54 : 2
55 : 3
56 : 4
57 : 5
58 : 6
59 : 7
60 : 8
61 : 9
62 : +
63 : /
当要编码的字节不够三个时,一个字节有8个位,在后面添加4个0,组成12个位,编码成两个字节;只有两个字节时,有16位,在后面添加两个0,组成18位,编码成三个字节。最后添加‘=’,形成4个字节。
c++代码实现
#include<iostream>
#include<vector>
#include<map>
using namespace std;
class base64{
public:
base64(){
char c='A';
for(int i=0;i<26;i++){
encode_table[i]=c++;
}
c='a';
for(int i=26;i<52;i++){
encode_table[i]=c++;
}
c='0';
for(int i=52;i<62;i++){
encode_table[i]=c++;
}
encode_table[62]='+';
encode_table[63]='/';
for(int i=0;i<64;i++){
decode_table[encode_table[i]]=i;
cout<<i<<" : "<<encode_table[i]<<endl;
}
}
string encode(string s){
string res;
int n=s.size();
for(int i=0;i<n-2;i+=3){
res.append(e_three(s.substr(i,3)));
}
if(n%3==2){
res.append(e_two(s.substr(n-2)));
}else if(n%3==1){
res.append(e_one(s.substr(n-1)));
}
return res;
}
string decode(string d){
string res;
while(d.back()=='='){
d.pop_back();
}
for(int i=0;i<d.size();i+=4){
res.append(d_four(d.substr(i,4)));
}
return res;
}
private:
string e_three(string source){
vector<int> dest(4);
dest[0]=source[0]>>2;
int t=source[0] & 3;
dest[1]=(source[1]>>4) | (t<<4);
t=source[1] & 0xf;
dest[2]=(source[2]>>6) | t<<2;
dest[3]=source[2] & 0x3f;
string res="====";
for(int i=0;i<4;i++){
res[i]=encode_table[dest[i]];
}
return res;
}
string e_two(string s){
vector<int> d(3);
d[0]=s[0]>>2;
int t=s[0] & 3;
d[1]=(s[1]>>4) | (t<<4);
t=s[1] & 0xf;
d[2]=t<<2;
string res="====";
for(int i=0;i<3;i++){
res[i]=encode_table[d[i]];
}
return res;
}
string e_one(string s){
vector<int> d(2);
d[0]=s[0]>>2;
int t=s[0] & 3;
d[1]=t<<4;
string res="====";
res[0]=encode_table[d[0]];
res[1]=encode_table[d[1]];
return res;
}
string d_four(string str){
vector<int > d(4);
string res;
int t2;
string t1=" ";
if(str.size()==4){
for(int i=0;i<4;i++){
d[i]=decode_table[str[i]];
}
t1[0]=(d[0]<<2) |(d[1]>>4);
res.append(t1);
t2=d[1] & 0xf;
t1[0]=(t2<<4) | (d[2]>>2);
res.append(t1);
t2=d[2] & 3;
t1[0]=(t2<<6) | d[3];
res.append(t1);
return res;
}else if(str.size()==3){
for(int i=0;i<3;i++){
d[i]=decode_table[str[i]];
}
t1[0]=(d[0]<<2) |(d[1]>>4);
res.append(t1);
t2=d[1] & 0xf;
t1[0]=(t2<<4) | (d[2]>>2);
res.append(t1);
return res;
}else if(str.size()==2){
for(int i=0;i<2;i++){
d[i]=decode_table[str[i]];
}
t1[0]=(d[0]<<2) |(d[1]>>4);
res.append(t1);
return res;
}
}
map<int,char> encode_table;
map<char,int> decode_table;
};
int main(){
base64 base;
cout<<"Input the message:"<<endl;
string mess;
cin>>mess;
string cipher=base.encode(mess);
cout<<cipher<<endl;
cout<<"The decoding:"<<endl;
cout<<base.decode(cipher)<<endl;
}