242 lines
5.8 KiB
C++
242 lines
5.8 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','+','/','='};
|
|
|
|
string Base64::Encode(const string& plaintext)
|
|
{
|
|
int textSize=(int)plaintext.size(); //明文长度
|
|
int resultSize=((int)plaintext.size()+2)/3*4;//密文长度
|
|
char* pText=new char[textSize+1]; //多开辟一个内存空间用于存储 '\0'
|
|
char* pResult=new char[resultSize+1]; //多开辟一个内存空间用于存储 '\0'
|
|
|
|
//plaintext.copy(pText,textSize,0);
|
|
strcpy(pText,plaintext.c_str());
|
|
|
|
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];
|
|
}
|
|
}
|
|
|
|
string result=pResult;
|
|
delete [] pText;
|
|
delete [] pResult;
|
|
pText=NULL;
|
|
pResult=NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
string Base64::Decode(const string& ciphertext)
|
|
{
|
|
int textSize=(int)ciphertext.size();
|
|
|
|
if (textSize%4!=0)//Base64密文的长度应该是4的倍数
|
|
{
|
|
return "Base64 cipher text error!";
|
|
}
|
|
|
|
int resultSize=(int)ciphertext.size()/4*3;//明文的长度
|
|
char* pText=new char[textSize+1];
|
|
memset(pText,0,textSize+1);
|
|
char* pResult=new char[resultSize+1];
|
|
memset(pResult,0,resultSize + 1);
|
|
|
|
//ciphertext.copy(pText,textSize,0);
|
|
strcpy(pText,ciphertext.c_str());
|
|
|
|
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];
|
|
}
|
|
|
|
string result=pResult;
|
|
|
|
delete [] pText;
|
|
delete [] pResult;
|
|
pText=NULL;
|
|
pResult=NULL;
|
|
|
|
return result;
|
|
|
|
}
|