可以参考以下博文,写得挺详细的。
https://www.cnblogs.com/zhangmingda/p/14124282.html
大概理解就是:
编码的时候:每3个字节,也就是24个bit分为分配到4个字节中去,充当每个字节的后6个bit位,每个字节的前2个bit都是0。
如过不是3字节的整数倍,差几个字节,就末尾补充几个字节0,最后编码的结果,就替换末尾几个字节为几个字节的'='。
解码的时候:首先看末尾有几个==,最后去掉几个字节的数据即可。
解码就是把4字节重新转换为3字节而已。规则类似。
下面是本人的实现,效率不太高的样子,也就练练手。
仅仅测试1M文件的例子,和php编码、解码一样,就认为没问题了。
1 #include<iostream>
2 #include<string.h>
3 #include<map>
4 #include<time.h>
5 using namespace std;
6 char base64str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
7 map<unsigned char,unsigned char> m;
8 void test()
9 {
10 unsigned char h = 'h';
11 unsigned char e = 'e';
12 unsigned char l = 'l';
13 char s[10];
14
15 itoa(h,s,2);
16 cout<<"h = "<<s<<endl;
17 itoa(e,s,2);
18 cout<<"e = "<<s<<endl;
19 itoa(l,s,2);
20 cout<<"l = "<<s<<endl;
21 unsigned char tmp = h>>2;
22 itoa(tmp,s,2);
23 tmp = (h<<6);
24 tmp >>=2;
25 itoa(tmp,s,2);
26 tmp = ((h<<6)>>2)^(e>>4);
27 itoa(tmp,s,2);
28
29 cout<<(((h<<6)>>2)==(h<<4))<<endl;
30 }
31 void decode(unsigned char str[],int len)
32 {
33 int extra = 0;
34 if(str[len-1]=='=')
35 {
36 extra++;
37 if(str[len-2]=='=')
38 {
39 extra++;
40 }
41 cout<<"extra = "<<extra<<endl;
42 }
43 len-=4;
44 string s = "";
45 unsigned char temp[4];
46 for(int i=0;i<=len;i+=4)
47 {
48 memcpy(temp,str+i,4);
49 unsigned char t;
50 temp[0] = m[temp[0]];
51 temp[1] = m[temp[1]];
52 temp[2] = m[temp[2]];
53 temp[3] = m[temp[3]];
54 t = temp[0]<<2;
55 unsigned char t2;
56 t2 = temp[1]<<2;
57 t2>>=6;
58 t^=t2;
59 s+=t;
60
61 t = temp[1]<<4;
62 t2 = temp[2]>>2;
63 t2<<=4;
64 t2>>=4;
65 t^=t2;
66 s+=t;
67
68 t = temp[2]<<6;
69 t2 = temp[3]<<2;
70 t2>>=2;
71 t^=t2;
72 s+=t;
73
74 }
75 FILE* fp;
76 fp = fopen("C:\\Users\\17724\\Desktop\\10_1\\c++_old","wb");
77 if(fp==NULL)
78 {
79 cout<<"cannot write!"<<endl;
80 return;
81 }
82 fwrite(s.c_str(),1,s.length()-extra,fp);
83 fclose(fp);
84 }
85 void encode(unsigned char str[],int len)
86 {
87 cout<<"no"<<endl;
88 char a[10];
89 int left = 3-len%3;
90 cout<<"left = "<<left<<endl;
91 if(left==0)
92 {
93 len-=3;
94 }
95 else
96 {
97 unsigned char* tmp;
98 tmp = (unsigned char*)malloc(len+left);
99 memset(tmp,0,len+left);
100 memcpy(tmp,str,len);
101 str = (unsigned char*)tmp;
102 }
103 string s = "";
104 unsigned char tmp[3];
105 unsigned char t[4];
106 for(int i=0;i<=len;i+=3)
107 {
108 memcpy(tmp,str+i,3);
109
110 memset(t,0,4);
111 itoa(tmp[0],a,2);
112 itoa(tmp[1],a,2);
113 itoa(tmp[2],a,2);
114 t[0] = tmp[0]>>2;
115 itoa(t[0],a,2);
116
117 unsigned char f1 = tmp[0]<<6;
118 f1>>=2;
119 t[1] = (f1)^(tmp[1]>>4);
120 itoa(t[1],a,2);
121
122 f1 = tmp[1]<<4;
123 f1>>=2;
124 t[2] = (f1)^(tmp[2]>>6);
125 itoa(t[2],a,2);
126
127 f1 = tmp[2]<<2;
128 f1 >>=2;
129 t[3] = f1;
130 itoa(t[3],a,2);
131
132 t[0] = base64str[t[0]];
133 t[1] = base64str[t[1]];
134 t[2] = base64str[t[2]];
135 t[3] = base64str[t[3]];
136 for(int i=0;i<4;i++)
137 {
138 s+=t[i];
139 }
140 }
141 cout<<s.length()<<endl;
142 for(int i=0;i<left;i++)
143 {
144 s[s.length()-1-i] = '=';
145 }
146 FILE* fp;
147 fp = fopen("C:\\Users\\17724\\Desktop\\10_1\\c++","wb");
148 if(fp==NULL)
149 {
150 cout<<"cannot write!"<<endl;
151 return;
152 }
153 fwrite(s.c_str(),1,s.length(),fp);
154 fclose(fp);
155 cout<<"endl"<<endl;
156 }
157 int main()
158 {
159 for(int i=0;i<64;i++)
160 {
161 m[base64str[i]]=i;
162 }
163 // unsigned char str[] = "hello";
164 FILE* fp;
165 fp = fopen("C:\\Users\\17724\\Desktop\\10_1\\0.mp4","rb");
166 fseek(fp,0,SEEK_END);
167 int len = ftell(fp);
168 cout<<"len = "<<len<<endl;
169 fseek(fp,0,SEEK_SET);
170 unsigned char *str;
171 str = (unsigned char*)malloc(len);
172 fread(str,1,len,fp);
173 fclose(fp);
174 clock_t t1 = clock();
175 encode(str,len);
176 clock_t t2 = clock();
177 cout<<"use time = "<<(t2-t1)<<endl;
178 return 0;
179 }
原文链接: https://www.cnblogs.com/dayq/p/15361487.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/214105
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!