Base64编码、解码的实现(二)

由于项目用到了字节数组与文本互相转换,所以自己写了一对方法用来把字节数组转成可见字符串,及把字符串转成字节数组的BASE64算法。

使用toBase64String的时候默认的是加上了回车换行的处理,但是在fromBase64String的时候无论有没有回车换行符都可以正确的转换。

这里的算法完全是自己由Base64思想自己完出来的,如果错误敬请指正。

使用的示例:

 

BYTE* bts(NULL);

int len;

LPCTSTR str=_T("abcdefg123456");

 

bts=this->fromBase64String(str, len);//转成字节数组

 

CString t = this->toBase64String(bts, len);//由字节数组再转回字符串

delete bts;

 

实现代码:

 

CString CTAXGDlg::toBase64String(BYTE* btyArray, int length)

{

CString strResult;

if (length==0)

{

return strResult;

}

 

TCHAR base64[65]={

_T('A'), _T('B'), _T('C'), _T('D'), _T('E'), _T('F'), _T('G'), _T('H'), _T('I'), _T('J'), _T('K'), _T('L'), _T('M'), _T('N'), _T('O'), _T('P'), 

_T('Q'), _T('R'), _T('S'), _T('T'), _T('U'), _T('V'), _T('W'), _T('X'), _T('Y'), _T('Z'), _T('a'), _T('b'), _T('c'), _T('d'), _T('e'), _T('f'), 

_T('g'), _T('h'), _T('i'), _T('j'), _T('k'), _T('l'), _T('m'), _T('n'), _T('o'), _T('p'), _T('q'), _T('r'), _T('s'), _T('t'), _T('u'), _T('v'), 

_T('w'), _T('x'), _T('y'), _T('z'), _T('0'), _T('1'), _T('2'), _T('3'), _T('4'), _T('5'), _T('6'), _T('7'), _T('8'), _T('9'), _T('+'), _T('/'), 

_T('=')

};

 

int nRemainder = length % 3;//num为剩余的字节数

int nlength = (length / 3) * 4;

if (nRemainder!=0)

{

nlength += 4;

}

 

int lines = nlength / 0x50;

if ((nlength % 0x50) == 0)

{

lines--;

}

nlength+=lines * 2;//×2是因为有两个回车换行符

 

TCHAR* chrArray=new TCHAR[nlength];

::ZeroMemory(chrArray, nlength*sizeof(TCHAR));

 

int charIndex(0);

int nLineChars(0);

int nSourceIndex(0);

 

for (nSourceIndex = 0; nSourceIndex < length - nRemainder; nSourceIndex += 3)

{

//每三个字节转成四个字节且,这四个字节值都不大于64,这就保证了只会出现64个字符中的一个。

chrArray[charIndex++] = base64[(btyArray[nSourceIndex] & 0xfc) >> 2];

chrArray[charIndex++] = base64[((btyArray[nSourceIndex] & 0x3) << 4) | ((btyArray[nSourceIndex + 1] & 0xF0) >> 4)];

chrArray[charIndex++] = base64[((btyArray[nSourceIndex + 1] & 0xF) << 2) | ((btyArray[nSourceIndex + 2] & 0xc0) >> 6)];

chrArray[charIndex++] = base64[btyArray[nSourceIndex + 2] & 0x3f];

 

nLineChars += 4;

if (nLineChars == 0x50)

{

chrArray[charIndex++] = _T('/r');

chrArray[charIndex++] = _T('/n');

nLineChars = 0;

}

}

 

//处理剩余的字节,如果剩余字节数不为0且没有添加换行符则添加换行符。

if (((nRemainder != 0)) && (nLineChars == 0x50))

{

chrArray[charIndex++] = _T('/r');

chrArray[charIndex++] = _T('/n');

}

switch (nRemainder)

{

case 1:

chrArray[charIndex++] = base64[(btyArray[nSourceIndex] & 0xfc) >> 2];

chrArray[charIndex++] = base64[(btyArray[nSourceIndex] & 0x3) << 4];

chrArray[charIndex++] = base64[0x40];

chrArray[charIndex++] = base64[0x40];

break;

case 2:

chrArray[charIndex++] = base64[(btyArray[nSourceIndex] & 0xfc) >> 2];

chrArray[charIndex++] = base64[((btyArray[nSourceIndex] & 3) << 4) | ((btyArray[nSourceIndex + 1] & 240) >> 4)];

chrArray[charIndex++] = base64[(btyArray[nSourceIndex + 1] & 15) << 2];

chrArray[charIndex++] = base64[0x40];

break;

}

strResult=CString(chrArray, charIndex);

delete[] chrArray;

 

return strResult;

}

 

BYTE* CTAXGDlg::fromBase64String(LPCTSTR text, int& length)

{

//去掉回车换行符

int textLength(0);

const TCHAR* pText=text;

while(*pText++)

{

textLength++;

}

 

TCHAR* chrArray=new TCHAR[textLength+1];

ZeroMemory(chrArray, sizeof(TCHAR)*(textLength+1));

 

int nCount=0;

for(int charIndex=0;charIndex<textLength;charIndex++)

{

TCHAR tmpChar=text[charIndex];

if (tmpChar==_T('/r') || tmpChar==_T('/n'))

{

continue;

}

if (tmpChar==_T('='))

{

break;

}

chrArray[nCount++]=tmpChar;

}

 

int nRemainder=nCount%4;

int tmpLength = (nCount/4) * 3;

if(nRemainder!=0)

{

tmpLength+=3;

}

BYTE* btyArray=new BYTE[tmpLength];

 

int byteIndex(0);

int nSourceIndex(0);

 

for (nSourceIndex = 0; nSourceIndex < nCount-nRemainder; nSourceIndex++)

{

//每四个字符转成三个字节,这四个字符值都不大于64。

TCHAR c1=chrArray[nSourceIndex++];

TCHAR c2=chrArray[nSourceIndex++];

TCHAR c3=chrArray[nSourceIndex++];

TCHAR c4=chrArray[nSourceIndex];

 

BYTE b1=getBase64Byte(c1);

BYTE b2=getBase64Byte(c2);

BYTE b3=getBase64Byte(c3);

BYTE b4=getBase64Byte(c4);

 

btyArray[byteIndex++] = (BYTE)(((b1 & 0x3f) << 2)|((b2 & 0xf0) >> 4));

btyArray[byteIndex++] = (BYTE)(((b2 & 0xf) << 4)|((b3 & 0xfc) >> 2));

btyArray[byteIndex++] = (BYTE)(((b3 & 0x3) << 6)|(b4 & 0x3f));

}

switch(nRemainder)

{

case 3:

{

TCHAR c1=chrArray[nSourceIndex++];

TCHAR c2=chrArray[nSourceIndex++];

TCHAR c3=chrArray[nSourceIndex];

 

BYTE b1=getBase64Byte(c1);

BYTE b2=getBase64Byte(c2);

BYTE b3=getBase64Byte(c3);

 

BYTE v1=(BYTE)(((b1 & 0x3f) << 2)|((b2 & 0xf0) >> 4));

BYTE v2=(BYTE)(((b2 & 0xf) << 4)|((b3 & 0xfc) >> 2));

 

btyArray[byteIndex++] = v1;

btyArray[byteIndex++] = v2;

}

break;

case 2:

{

TCHAR c1=chrArray[nSourceIndex++];

TCHAR c2=chrArray[nSourceIndex];

 

BYTE b1=getBase64Byte(c1);

BYTE b2=getBase64Byte(c2);

 

BYTE v1=(BYTE)(((b1 & 0x3f) << 2)|((b2 & 0xf0) >> 4));

 

btyArray[byteIndex++] = v1;

}

break;

}

 

delete[] chrArray;

length=byteIndex;

return btyArray;

}

BYTE CTAXGDlg::getBase64Byte(TCHAR value)

{

BYTE b(64);

 

if (value>=_T('A') && value<=_T('Z'))

{

b=(BYTE)(value-_T('A'));

}

else if (value>=_T('a') && value<=_T('z'))

{

b=(BYTE)(value-_T('a')+26);

}

else if (value>=_T('0') && value<=_T('9'))

{

b=(BYTE)(value-_T('0')+52);

}

else if (value==_T('+')||value==_T('*')||value==_T('['))

{

b=(BYTE)62;

}

else if (value==_T('/')||value==_T('-')||value==_T(']')) 

{

b=(BYTE)63;

}

return b;

}

你可能感兴趣的:(c,算法,String,null,delete,byte)