欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++实现base64编码解码

程序员文章站 2022-05-16 19:54:10
...

base64编码是将3个字符(共24位2进制)分成一组,然后每6位2进制编成一个新的字符。
也就是3 x 8 = 6 x 4
6位2进制可以表示2的6次方个数,也就是64个,所以叫base64编码。
贴一张base64编码表,由A-Z、a-z、0-9、+、/共64个字符组成
C++实现base64编码解码
需要注意的是,base64编码后的长度一定是4的倍数。

当需要转换的字符个数正好是3的倍数时,可以直接转换,转换后的长度为len(str)/3 x 4

当字符个数为除3余1时,前面按照常规,多出那一个字符就需要在后面补0(2进制),表示出2个base64字符,然后剩下两个用=填充。

当字符个数为除3余2时,前面按照常规,多出那两个字符就需要在后面补0(2进制), 表示出3个base64字符,然后剩下两个用=填充。

C++实现base64编码解码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

string base64_encode(string str){
	string base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	int str_len = str.length();
	string res="";
	//注意这里str_len/3*3 
	//通过字符的ascii二进制位运算组合成base64编码二进制 
	for (int strp=0; strp<str_len/3*3; strp+=3){
		res+=base64_table[str[strp]>>2];
		res+=base64_table[(str[strp]&0x3)<<4 | (str[strp+1])>>4];
		res+=base64_table[(str[strp+1]&0xf)<<2 | (str[strp+2])>>6];
		res+=base64_table[(str[strp+2])&0x3f]; 
		//cout<<res<<endl; 
	}
	if (str_len%3==1){
		int pos=str_len/3 * 3;
		res += base64_table[str[pos]>>2];
		res += base64_table[(str[pos]&0x3)<<4];
		res += "=";	res += "=";
	}else if (str_len%3==2){
		int pos=str_len/3 * 3;
		res += base64_table[str[pos]>>2];
		res += base64_table[(str[pos]&0x3)<<4 | (str[pos+1])>>4];
		res += base64_table[(str[pos+1]&0xf)<<2];
		res += "=";
	}
	return res;
}
 
char a_to_c(int x){
//int转char 
	char ch=x;
	return ch;
}

int find_int(char ch){ 
//找base64表中字符对应的int值 
//string base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	if (ch>='A' && ch<='Z')		return ch-'A'+0;
	else if (ch>='a' && ch<='z')	return ch-'a'+26;
	else if (ch>='0' && ch<='9')	return ch-'0'+52;
	else if (ch=='+')	return 62;
	else if (ch=='/')	return 63;
}
string base64_decode(string str){
	int str_len = str.length();
	string res="";
	int flag;
	if (str[str_len-1]=='=' && str[str_len-2]=='=')		flag=2;
	else if (str[str_len-1]=='=' && str[str_len-2]!='=')	flag = 1;
	else	flag = 0;
	//cout<<flag<<" "<<str;
	for (int strp=0; strp<str_len-4; strp+=4){
		res += a_to_c(find_int(str[strp])<<2 | find_int(str[strp+1])>>4);
		res += a_to_c(find_int(str[strp+1])<<4 | find_int(str[strp+2])>>2);
		res += a_to_c(find_int(str[strp+2])<<6 | find_int(str[strp+3]));
	}
	int pos = str_len-4;
	if (flag==1){	//原字符串模3余2 
		res += a_to_c(find_int(str[pos])<<2 | find_int(str[pos+1])>>4);
		res += a_to_c(find_int(str[pos+1])<<4 | find_int(str[pos+2])>>2); 
	}else if (flag==2){	//原字符串模3余1 
		res += a_to_c(find_int(str[pos])<<2 | find_int(str[pos+1])>>4);
	}else if (flag==0){
		res += a_to_c(find_int(str[pos])<<2 | find_int(str[pos+1])>>4);
		res += a_to_c(find_int(str[pos+1])<<4 | find_int(str[pos+2])>>2);
		res += a_to_c(find_int(str[pos+2])<<6 | find_int(str[pos+3]));
	}
	return res; 
} 
int main(){
	string str="hellowo sorlds";
	//cout<<base64_encode(str);
	cout<<base64_decode(base64_encode(str));
	return 0;
}
相关标签: CTF crypto