C++实现Base64编码
可以参考以下博文,写得挺详细的。
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 }