base64解码详解

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xbk123123/article/details/53513957

上一节详细的解释了编码的过程,本节将介绍一下解码的过程。可以说解码就是编码的你过程,具体的代码如下:

int FindPos(const char needChar)
{//base64的ascii表和一般的ascii表不同
	const char *chKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64的ascii表
	for (int i=0;i<64;++i)
	{
		if (needChar == chKey[i])
		{
			break;
		}
	}
	return i;
}
std::string Basic_64::GetPeriorStr(std::string& readyChangeStr)
{//解码的过程只是编码的逆过程
	if (readyChangeStr.empty())
	{
		return "";
	}
	/**************************
	如果遇到==,就不用处理该字节,处理其余的字节即可
	**************************/
	std::string sNeedString=readyChangeStr;//保留原来的字符串(不能改变用户传递的参数)
	while(sNeedString.find("=")!=-1)
	{
		sNeedString.replace(sNeedString.length()-1,sNeedString.length()-1,"");
	}
	int stringLen=sNeedString.length();
	if (stringLen <= 0)
	{
		return "";
	}
	char tempchar='\0';
	int byteArray[5]={0};//将字符的ascii存放在数组中
	int posNum=0;//编码的4个字节,刚好是源码的3个字节
	std::string sResourceStr="";//存放源码的字符串
	for (int i=0;i<stringLen;++i)
	{
		if (i!=0 && i%4==0)
		{
			posNum+=4;
		}
		switch(i-posNum)
		{
		case 0:
			byteArray[0]=FindPos(sNeedString[i]);
			byteArray[4]=(byteArray[0]<<2) & 0xfc;//得到第一个字符的前6位
			break;
		case 1:
			byteArray[1]=FindPos(sNeedString[i]);
			byteArray[4]=byteArray[4] | ( (byteArray[1]>>4) & 0x03);//将前6位和后2位按位或,得到源字符串的第一个字节
			tempchar=byteArray[4];
			sResourceStr+=tempchar;
			break;
		case 2:
			byteArray[4]=0;
			byteArray[4]=(byteArray[1] << 4) & 0xF0;//获得第二个字节的后四位
			byteArray[2]=FindPos(sNeedString[i]);
			byteArray[4]=byteArray[4] | ( (byteArray[2]>>2) & 0x0f );////将第二个字节后4位和第三个字节前4位按位或,得到源码的第二个字符
			tempchar=byteArray[4];
			sResourceStr+=tempchar;
			break;
		case 3:
			byteArray[4]=0;
			byteArray[4]=(byteArray[2] << 6) & 0xc0;//获得第三个字节的后2位
			byteArray[3]=FindPos(sNeedString[i]);
			byteArray[4]=byteArray[4] | (byteArray[3] & 0x3f);//第3个字节的后两位和第4个自己的前6位,构成了源字符串的第3个字节
			tempchar=byteArray[4];
			sResourceStr+=tempchar;
			break;
		}
	}
	return sResourceStr;
}

上面的代码就是解码的详细过程,当然可以将某些过程合并,但是为了便于理解,暂不合并处理。

解码的具体过程:

编码的4个字节刚好对应源码的3个字节,因此在解码时,每4个字节处理一次。

如例:源码ABC,通过编码之后的字符串为:QUJD,通过对照base64的ascii表,我们可以得知,编码的二进制表示形式为:00010000  00010100  00001001  00000011

注意编码的最高两位和源码没有关系,只是每一个字节后六位才和源码有关,因此编码中的每个字符我们只处理该字符的后6位二级制编码。

由编码的过程可以得知:1)第一个字节的前6位,即010000,就是源码第一个字节的前六位;编码第二个字节的前2位,即01是源码第一个字节的后两位;这样就可以得到源码第一个字节的二级制表示形式为01000001,即就是A。

对应的代码为:

byteArray[4]=(buteArray[0]<<2) & 0xfc;//得到第一个字符的前6位

byteArray[4]=byteArray[4] | (buteArray[1]>>4) & 0x03;//将前6位和第二个字节前2位按位或,得到源字符串的第一个字节


2)编码第二个字节的后4位,即0100,就是源码第二个字节的前4位;编码第3个字节的前4位,即0010,就是源码第二个字节的后4位;这样就可以得到源码第2个字节的二进制表示形式为01000010,即就是B。

对应的代码为:

byteArray[4]=(buteArray[1]<<4) & 0xf0;//得到第2个字符的后4位

byteArray[4]=byteArray[4] | (buteArray[2]>>2) & 0x0f;//将第二个字节后4位和第三个自己的前4位按位或,得到源字符串的第2个字节

3)编码第三个字节的后2位,即01,就是源码第3个字节的前3位;编码第4个字节的前6位,即000011,就是源码第3个字节的后6位;这样就可以得到源码第3个字节的二进制表示形式为01000011,即就是C。

对应的代码为:

byteArray[4]=(buteArray[2]<<6) & 0xc0;//得到第3个字符的后2位

byteArray[4]=byteArray[4] | (buteArray[3]>>2) & 0x3f;//将第3个字节后2位和第4个自己的前6位按位或,得到源字符串的第3个字节

编码共四个字节,处理完成,最终得到的解码字符串为ABC。

对于编码中的=,我们不需要去处理它,这是因为该字符只是base64编码时加的一个字符,其实的编码时在最后一个字符加了00,因此不用去处理。而且这个字符如果存在,只可能在编码字符串的后两个字节或一个字节才有的,因此在解码之前,就将该字符剔除。

展开阅读全文
博主设置当前文章不允许评论。

没有更多推荐了,返回首页