236 lines
5.7 KiB
C++
236 lines
5.7 KiB
C++
#include "StdAfx.h"
|
||
#include "Base64.h"
|
||
|
||
char Base64::code[65]={
|
||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/','='};
|
||
|
||
std::string Base64::Encode(const std::string& plaintext)
|
||
{
|
||
int textSize=plaintext.size(); //明文长度
|
||
int resultSize=(plaintext.size()+2)/3*4;//密文长度
|
||
char* pText=new char[textSize+1]; //多开辟一个内存空间用于存储'\0'
|
||
char* pResult=new char[resultSize+1]; //多开辟一个内存空间用于存储'\0'
|
||
|
||
plaintext.copy(pText,textSize,0);
|
||
pText[textSize]='\0';
|
||
pResult[resultSize]='\0';
|
||
|
||
int textIndex=0;//pText的下标
|
||
int resultIndex;//pResult的下标
|
||
|
||
//加密明文,但不包括密文的最后四个字符,因为明文长度可能不是 3 的整数倍,密文会以‘=’结尾
|
||
for (resultIndex=0;resultIndex<resultSize-4;resultIndex+=4,textIndex+=3)
|
||
{
|
||
char a,b,c;
|
||
a=pText[textIndex];
|
||
b=pText[textIndex+1];
|
||
c=pText[textIndex+2];
|
||
for (int i=0;i<4;i++)
|
||
{
|
||
int index;
|
||
switch(i)
|
||
{
|
||
case 0:index=(a>>2 & 0x3F);break;
|
||
case 1:index=(a<<4 & 0x30)|(b>>4 & 0x0F);break;
|
||
case 2:index=(b<<2 & 0x3C)|(c>>6 & 0x03);break;
|
||
case 3:index=(c & 0x3F);break;
|
||
}
|
||
pResult[resultIndex+i]=code[index];
|
||
}
|
||
}
|
||
|
||
//判断明文剩余几个字符,并加密
|
||
if (textIndex==textSize-1)//余一个字符,密文末尾有两个‘=’
|
||
{
|
||
char a,b;
|
||
a=pText[textIndex];
|
||
b=0;
|
||
for (int j=0;j<4;j++)
|
||
{
|
||
int index;
|
||
switch(j)
|
||
{
|
||
case 0:index=(a>>2 & 0x3F);break;
|
||
case 1:index=(a<<4 & 0x30)|(b>>4 & 0x0F);break;
|
||
case 2:index=64;break;
|
||
case 3:index=64;break;
|
||
}
|
||
pResult[resultIndex+j]=code[index];
|
||
}
|
||
|
||
}
|
||
else if ((textIndex+1)==textSize-1)//余两个字符,密文末尾有一个‘=’
|
||
{
|
||
char a,b,c;
|
||
a=pText[textIndex];
|
||
b=pText[textIndex+1];
|
||
c=0;
|
||
for (int j=0;j<4;j++)
|
||
{
|
||
int index;
|
||
switch(j)
|
||
{
|
||
case 0:index=(a>>2 & 0x3F);break;
|
||
case 1:index=(a<<4 & 0x30)|(b>>4 & 0x0F);break;
|
||
case 2:index=(b<<2 & 0x3C)|(c>>6 & 0x03);break;
|
||
case 3:index=64;break;
|
||
}
|
||
pResult[resultIndex+j]=code[index];
|
||
}
|
||
}
|
||
else//是三的整数倍,密文末尾没有‘=’
|
||
{
|
||
char a,b,c;
|
||
a=pText[textIndex];
|
||
b=pText[textIndex+1];
|
||
c=pText[textIndex+2];
|
||
for (int j=0;j<4;j++)
|
||
{
|
||
int index;
|
||
switch(j)
|
||
{
|
||
case 0:index=(a>>2 & 0x3F);break;
|
||
case 1:index=(a<<4 & 0x30)|(b>>4 & 0x0F);break;
|
||
case 2:index=(b<<2 & 0x3C)|(c>>6 & 0x03);break;
|
||
case 3:index=(c & 0x3F);break;
|
||
}
|
||
pResult[resultIndex+j]=code[index];
|
||
}
|
||
}
|
||
|
||
std::string result=pResult;
|
||
delete [] pText;
|
||
delete [] pResult;
|
||
pText=NULL;
|
||
pResult=NULL;
|
||
|
||
return result;
|
||
}
|
||
|
||
std::string Base64::Decode(const std::string& ciphertext)
|
||
{
|
||
int textSize=ciphertext.size();
|
||
|
||
if (textSize%4!=0)//Base64密文的长度应该是4的倍数
|
||
{
|
||
return "Base64 cipher text error!";
|
||
}
|
||
|
||
int resultSize=ciphertext.size()/4*3;//明文的长度
|
||
char* pText=new char[textSize+1];
|
||
char* pResult=new char[resultSize+1];
|
||
|
||
ciphertext.copy(pText,textSize,0);
|
||
pText[textSize]='\0';
|
||
pResult[resultSize]='\0';
|
||
|
||
int textIndex=0;//pText的下标
|
||
int resultIndex;//pResult的下标
|
||
|
||
int index[4];//存储字符在code种的位置
|
||
//解密密文,但不解密最后四个字符,因为密文最后四位可能包括‘=’
|
||
for (resultIndex=0; resultIndex<resultSize-3; resultIndex+=3,textIndex+=4)
|
||
{
|
||
for (int m=0;m<4;m++)
|
||
{
|
||
if (pText[textIndex+m]>='A' && pText[textIndex+m]<='Z')
|
||
{
|
||
index[m]=pText[textIndex+m]-65;
|
||
}
|
||
else if (pText[textIndex+m]>='a' && pText[textIndex+m]<='z')
|
||
{
|
||
index[m]=pText[textIndex+m]-71;
|
||
}
|
||
else if (pText[textIndex+m]>='0' && pText[textIndex+m]<='9')
|
||
{
|
||
index[m]=pText[textIndex+m]+4;
|
||
}
|
||
else if (pText[textIndex+m]=='+')
|
||
{
|
||
index[m]=62;
|
||
}
|
||
else if (pText[textIndex+m]=='/')
|
||
{
|
||
index[m]=63;
|
||
}
|
||
else //如果密文包括其他字符则不是正确的Base64编码
|
||
{
|
||
delete [] pText;
|
||
delete [] pResult;
|
||
pText=pResult=NULL;
|
||
return "Base64 cipher text error!";
|
||
}
|
||
}
|
||
pResult[resultIndex] =(index[0]<<2 & 0XFC)|(index[1]>>4 & 0x03);
|
||
pResult[resultIndex+1]=(index[1]<<4 & 0xF0)|(index[2]>>2 & 0x0F);
|
||
pResult[resultIndex+2]=(index[2]<<6 & 0xC0)|index[3];
|
||
}
|
||
//处理密文的最后四位
|
||
for (int m=0;m<4;m++)
|
||
{
|
||
if (pText[textIndex+m]>='A' && pText[textIndex+m]<='Z')
|
||
{
|
||
index[m]=pText[textIndex+m]-65;
|
||
}
|
||
else if (pText[textIndex+m]>='a' && pText[textIndex+m]<='z')
|
||
{
|
||
index[m]=pText[textIndex+m]-71;
|
||
}
|
||
else if (pText[textIndex+m]>='0' && pText[textIndex+m]<='9')
|
||
{
|
||
index[m]=pText[textIndex+m]+4;
|
||
}
|
||
else if (pText[textIndex+m]=='+')
|
||
{
|
||
index[m]=62;
|
||
}
|
||
else if (pText[textIndex+m]=='/')
|
||
{
|
||
index[m]=63;
|
||
}
|
||
else if (pText[textIndex+m]=='=')
|
||
{
|
||
index[m]=64;
|
||
}
|
||
else
|
||
{
|
||
delete [] pText;
|
||
delete [] pResult;
|
||
pText=pResult=NULL;
|
||
return "Not base64 ciphertext!";
|
||
}
|
||
}
|
||
if (index[2]==64)//密文末尾有两个’=‘
|
||
{
|
||
pResult[resultIndex] =(index[0]<<2 & 0XFC)|(index[1]>>4 & 0x03);
|
||
pResult[resultIndex+1]='\0';
|
||
pResult[resultIndex+2]='\0';
|
||
}
|
||
else if (index[3]==64)//密文末尾有一个’=‘
|
||
{
|
||
pResult[resultIndex] =(index[0]<<2 & 0XFC)|(index[1]>>4 & 0x03);
|
||
pResult[resultIndex+1]=(index[1]<<4 & 0xF0)|(index[2]>>2 & 0x0F);
|
||
pResult[resultIndex+2]='\0';
|
||
|
||
}
|
||
else//密文末尾没有’=‘
|
||
{
|
||
pResult[resultIndex] =(index[0]<<2 & 0XFC)|(index[1]>>4 & 0x03);
|
||
pResult[resultIndex+1]=(index[1]<<4 & 0xF0)|(index[2]>>2 & 0x0F);
|
||
pResult[resultIndex+2]=(index[2]<<6 & 0xC0)|index[3];
|
||
}
|
||
|
||
std::string result=pResult;
|
||
|
||
delete [] pText;
|
||
delete [] pResult;
|
||
pText=NULL;
|
||
pResult=NULL;
|
||
|
||
return result;
|
||
|
||
}
|