#include "sbase64.h"
char sbase_six2pr[64] = {
'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','+','/'
};
unsigned char sbase_pr2six[256];
std::string sbase64_encode(const std::string &bufplain,
char ch1, char ch2, char padding)
{
std::string bufcoded;
bufcoded.reserve(bufplain.size()*3);
/* ENC is the basic 1 character encoding function to make a char printing */
#define ENC(c) sbase_six2pr[c]
sbase_six2pr[62]=ch1;
sbase_six2pr[63]=ch2;
unsigned int i=bufplain.size();
const unsigned char *bufin=(const unsigned char *)bufplain.c_str();
for(; i>=3; i-=3)
{
bufcoded+=ENC(bufin[0] >> 2); /* c1 */
bufcoded+=ENC(((bufin[0] << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
bufcoded+=ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)); /*c3*/
bufcoded+=ENC(bufin[2] & 077); /* c4 */
bufin+=3;
}
if(i==2)
{
bufcoded+=ENC(bufin[0] >> 2); /* c1 */
bufcoded+=ENC(((bufin[0] << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
bufcoded+=ENC((bufin[1] << 2) & 074); /* c3 */
if(padding!=0) bufcoded+=padding; /* c4 */
}
else if(i==1)
{
bufcoded+=ENC(bufin[0] >> 2); /* c1 */
bufcoded+=ENC((bufin[0] << 4) & 060); /* c2 */
if(padding!=0)
{
bufcoded+=padding; /* c3 */
bufcoded+=padding; /* c4 */
}
}
return bufcoded;
}
std::string sbase64_decode(const std::string &bufcoded,
char ch1, char ch2, char padding)
{
std::string bufplain;
bufplain.reserve(bufcoded.size());
/* single character decode */
#define DEC(c) sbase_pr2six[(int)c]
#define MAXVAL 63
sbase_six2pr[62]=ch1;
sbase_six2pr[63]=ch2;
static int first = 1;
register int nprbytes;
register const char *bufin=bufcoded.c_str();
/* If this is the first call, initialize the mapping table.
* This code should work even on non-ASCII machines.
*/
if(first)
{
unsigned j;
first = 0;
for(j=0; j<256; j++) sbase_pr2six[j] = MAXVAL+1;
for(j=0; j<64; j++) sbase_pr2six[(int)sbase_six2pr[j]] = (unsigned char) j;
}
/* Strip leading whitespace. */
nprbytes=bufcoded.size();
while(*bufin==' ' || *bufin == '\t' || *bufin=='\r' || *bufin=='\n')
{ bufin++; nprbytes--; }
for(; nprbytes>0; nprbytes-=4)
{
unsigned char c1, c2, c3, c4;
if(nprbytes>=4) c4=bufin[3]; else c4='=';
if(nprbytes>=3) c3=bufin[2]; else c3='=';
if(nprbytes>=2) c2=bufin[1]; else c2='=';
if(nprbytes>=1) c1=bufin[0]; else c1='=';
if(c1!='=' && c2!='=' && c1!=padding && c2!=padding)
bufplain+=(unsigned char) (DEC(c1) << 2 | DEC(c2) >> 4);
if(c2!='=' && c3!='=' && c2!=padding && c3!=padding)
bufplain+=(unsigned char) (DEC(c2) << 4 | DEC(c3) >> 2);
if(c3!='=' && c4!='=' && c3!=padding && c4!=padding)
bufplain+=(unsigned char) (DEC(c3) << 6 | DEC(c4));
bufin+=4;
}
return bufplain;
}
syntax highlighted by Code2HTML, v. 0.9.1