我对Base64加密的通俗理解是:对于一个字符串,一个字节有8个有效bit,转换为一个字节仅有6个有效bit的形式(剩余的高两位用0补齐)。3 x 8 = 24 = 4 x 6 意思是三个字节经过Base64加密后为4个字节。长度增长到原来的4/3。
例如: 一串字符,在内存的储存形式为
1001 1101 0110 0011 0101 1100
加密后
0010 0111 0001 0110 0000 1101 0001 1100
一个字符串的字节数,可能不是3的倍数。
当剩下4位时,我们需要补2个 = 凑齐8的倍数;当剩下的是2位时,我们需要补齐1个 = 凑齐8的倍数。
图片参考自:[https://www.cnblogs.com/chengmo/archive/2014/05/18/3735917.html]
加密代码:
string Base64(string str)
{//Mjg0NTYxMjM0NEBxcS5jb20=
int index=0;//待处理字符串str的索引
int i=0;//加密字符串ret_str的索引
char ret_str[1024];
string Base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while(index<str.size())
{
//处理三个字节
if(index+2<str.size())/** 0110 1001 1010 1001 1010 0101 1011 0100**/
{//剩余的数据不少于3个字节
ret_str[i++]=Base64[(str[index]/(2*2))];
index++;
ret_str[i++]=Base64[str[index-1]%(2*2)*16+str[index]/(16)];
index++;
ret_str[i++]=Base64[str[index-1]%16*4+str[index]/(64)];
ret_str[i++]=Base64[str[index]%64];
index++;
}else if(index+1<str.size())
{//剩余两个字节
ret_str[i++]=Base64[(str[index]/(2*2))];
index++;
ret_str[i++]=Base64[str[index-1]%(2*2)*16+str[index]/(16)];
//第三个不够6位,用0补齐
ret_str[i++]=Base64[str[index]%16*4];
ret_str[i++]='=';
index++;//跳出循环
}else
{//剩余一个字节
ret_str[i++]=Base64[(str[index]/(2*2))];
ret_str[i++]=Base64[(str[index]%(2*2))*16];
ret_str[i++]='=';
ret_str[i++]='=';
index++;//跳出循环
}
}
ret_str[i]='\0';
return ret_str;
}
解密代码:
string UnBase64(string str)
{
int index=0;//待解密字符串str的索引
int i=0;//解密字符串ret_str的索引
char ret_str[1024];
string Base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while(index<str.size())
{
//处理四个字节,肯定是四的倍数 00101010 00110011 00110101 00101011
ret_str[i++]=Base64.find(str[index])*4+Base64.find(str[index+1])/16;
index++;
if(str[index+1]=='=')break;
ret_str[i++]=Base64.find(str[index])%16*16+Base64.find(str[index+1])/4;
index++;
if(str[index+1]=='=')break;
ret_str[i++]=Base64.find(str[index])%4*64+Base64.find(str[index+1]);
index+=2;
}
ret_str[i]='\0';
return ret_str;
}
整合程序:
#include<iostream>
#include<string>
using namespace std;
string Base64(string str);
string UnBase64(string str);
int main()
{
string data;
while(1)
{
cout<<"请输入要加密的数据(exit退出)"<<endl;
cin>>data;
if(data=="exit")break;
cout<<"Base64加密后的数据是:"<<endl;
string str=(Base64(data));
cout<<str<<endl;
cout<<"Base64解密后的数据是:"<<endl;
cout<<UnBase64(str)<<endl;
}
return 0;
}
string Base64(string str)
{//Mjg0NTYxMjM0NEBxcS5jb20=
int index=0;//待处理字符串str的索引
int i=0;//加密字符串ret_str的索引
char ret_str[1024];
string Base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while(index<str.size())
{
//处理三个字节
if(index+2<str.size())/** 0110 1001 1010 1001 1010 0101 1011 0100**/
{//剩余的数据不少于3个字节
ret_str[i++]=Base64[(str[index]/(2*2))];
index++;
ret_str[i++]=Base64[str[index-1]%(2*2)*16+str[index]/(16)];
index++;
ret_str[i++]=Base64[str[index-1]%16*4+str[index]/(64)];
ret_str[i++]=Base64[str[index]%64];
index++;
}else if(index+1<str.size())
{//剩余两个字节
ret_str[i++]=Base64[(str[index]/(2*2))];
index++;
ret_str[i++]=Base64[str[index-1]%(2*2)*16+str[index]/(16)];
//第三个不够6位,用0补齐
ret_str[i++]=Base64[str[index]%16*4];
ret_str[i++]='=';
index++;//跳出循环
}else
{//剩余一个字节
ret_str[i++]=Base64[(str[index]/(2*2))];
ret_str[i++]=Base64[(str[index]%(2*2))*16];
ret_str[i++]='=';
ret_str[i++]='=';
index++;//跳出循环
}
}
ret_str[i]='\0';
return ret_str;
}
string UnBase64(string str)
{
int index=0;//待解密字符串str的索引
int i=0;//解密字符串ret_str的索引
char ret_str[1024];
string Base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while(index<str.size())
{
//处理四个字节,肯定是四的倍数 00101010 00110011 00110101 00101011
ret_str[i++]=Base64.find(str[index])*4+Base64.find(str[index+1])/16;
index++;
if(str[index+1]=='=')break;
ret_str[i++]=Base64.find(str[index])%16*16+Base64.find(str[index+1])/4;
index++;
if(str[index+1]=='=')break;
ret_str[i++]=Base64.find(str[index])%4*64+Base64.find(str[index+1]);
index+=2;
}
ret_str[i]='\0';
return ret_str;
}