📄 xbase64.cpp
字号:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "XBase64.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
namespace zdhsoft
{
const char XBase64::m_EnBase64Tab[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const char XBase64::m_Base64FillChar = '=';
const XByte XBase64::m_DeBase64Tab[256] =
{
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F,
0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
void XBase64::DecodeBase64(const void * srcData,int DataCount,XByteBuffer & OutBuffer,bool bBreakByError)
{
XByte dest[3] = { 0,0,0 };
OutBuffer.Clear();
int srcLen = DataCount;
const XByte * __srcData = (const XByte *)srcData;
if( srcLen > 0 )
{
int int4Count = srcLen / 4;
int int4Free = srcLen % 4;
if( int4Free > 0 ) OutBuffer.ensureCapacity( (int4Count + 1) * 3 );
else OutBuffer.ensureCapacity( int4Count * 3 );
if(bBreakByError)
{
bool bExit = false;
for(int i=0;i<int4Count;i++)
{
int iCount = __DecodeBase64Break(__srcData,dest);
if( iCount == 3 )
{
__srcData+=4;
OutBuffer.AppendData(dest,3);
}
else
{
OutBuffer.AppendData(dest,iCount);
bExit = true;
break;
}
}
if( int4Free > 0 && !bExit )
{
int iCount = __DecodeBase64Break(__srcData,dest);
OutBuffer.AppendData(dest,iCount);
}
}
else
{
for(int i=0;i<int4Count;i++)
{
int iCount = __DecodeBase64(__srcData,dest);
__srcData+=4;
OutBuffer.AppendData(dest,iCount);
}
if( int4Free > 0 )
{
int iCount = __DecodeBase64(__srcData,dest,int4Free);
OutBuffer.AppendData(dest,iCount);
}
}
}
}
void XBase64::EncodeBase64(const void * srcData,int DataCount,XByteBuffer & OutBuffer)
{
char dest[4];
OutBuffer.Clear();
int srcLen = DataCount;
const XByte * __srcData = (const XByte *)srcData;
if( srcLen > 0 )
{
int int3Count = srcLen / 3;
int int3Free = srcLen % 3;
//求出所需要的空间
if( int3Free > 0 ) OutBuffer.ensureCapacity( (int3Count+1) * 4 );
else OutBuffer.ensureCapacity( int3Count * 4 );
for(int i = 0;i < int3Count;i++)
{
__EncodeBase64(__srcData,dest);
__srcData+=3;
OutBuffer.AppendData(dest,4);
}
if( int3Free > 0 ) //如果未被3整除
{
__EncodeBase64(__srcData,dest,int3Free);
OutBuffer.AppendData(dest,4);
}
}
}
void XBase64::__EncodeBase64(const XByte * src,char dest[4],int iUse)
{
// 该方法使用asm实现,下面注释的部分是其C++实现方法,实现的结果是完全一样的
/* if( iUse == 3 )
{
dest[0] = m_EnBase64Tab[(src[0] >>2) & 0x3f];
dest[1] = m_EnBase64Tab[((src[0] & 0x03) << 4 ) | ((src[1]>>4) & 0x0f)];
dest[2] = m_EnBase64Tab[((src[1] & 0x0f) << 2 ) | ((src[2]>>6) & 0x03)];
dest[3] = m_EnBase64Tab[src[2] & 0x3f];
} else if( iUse == 2 )
{
dest[0] = m_EnBase64Tab[(src[0] >>2) & 0x3f];
dest[1] = m_EnBase64Tab[((src[0] & 0x03) << 4 ) | ((src[1]>>4) & 0x0f)];
dest[2] = m_EnBase64Tab[((src[1] & 0x0f) << 2 )];
dest[3] = m_Base64FillChar;
}else if( iUse == 1 )
{
dest[0] = m_EnBase64Tab[(src[0] >>2) & 0x3f];
dest[1] = m_EnBase64Tab[((src[0] & 0x03) << 4 )];
dest[2] = m_Base64FillChar;
dest[3] = m_Base64FillChar;
}
*/
char chTmp = m_Base64FillChar;
_ECX = (unsigned long)m_EnBase64Tab;
asm
{
mov eax,iUse
mov edx,dest
mov ebx,src
cmp eax,3
jne short @cmp2
xor eax,eax
mov al,byte ptr [ebx]
shr al,2
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,byte ptr[ebx]
inc ebx
mov ah,byte ptr[ebx]
and al,3
shl al,4
shr ah,4
or al,ah
xor ah,ah
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,byte ptr [ebx]
inc ebx
mov ah,byte ptr [ebx]
and al,15
shl al,2
shr ah,6
or al,ah
xor ah,ah
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,byte ptr [ebx]
and al,63
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
jmp short @cmpexit
@cmp2:
cmp eax,2
jne short @cmp1
xor eax,eax
mov al,byte ptr [ebx]
shr al,2
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,byte ptr[ebx]
inc ebx
mov ah,byte ptr[ebx]
and al,3
shl al,4
shr ah,4
or al,ah
xor ah,ah
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,byte ptr [ebx]
and al,15
shl al,2
mov al,byte ptr[eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,chTmp
mov byte ptr [edx],al
jmp short @cmpexit
@cmp1:
cmp eax,1
jne short @cmpexit
xor eax,eax
mov al,byte ptr [ebx]
shr al,2
mov al,byte ptr [eax + ecx]
mov byte ptr [edx],al
inc edx
mov al,byte ptr [ebx]
and al,3
shl al,4
mov al,byte ptr[eax + ecx]
mov byte ptr[edx],al
inc edx
mov al,chTmp
mov byte ptr [edx],al
inc edx
mov byte ptr [edx],al
@cmpexit:
};
}
/*
遇错误退出
*/
int XBase64::__DecodeBase64Break(const XByte * src,XByte * dest)
{
// 该方法使用asm实现,下面注释的部分是其C++实现方法,实现的结果是完全一样的
/*
int iUse = 4;
XDWord dwTmp = 0;
int iRet = 0;
for(int iCount = 0; iCount<4; iCount++)
{
XByte btTmp = m_DeBase64Tab[ *src++ ];
if( btTmp == 0xFF )
{
iUse = iCount;
break;
}
if( iCount>0 ) dwTmp <<= 6;
dwTmp |= btTmp;
}
if( iUse == 4 )
{
dest[2] = dwTmp & 0xFF;
dwTmp >>= 8;
dest[1] = dwTmp & 0xFF;
dwTmp >>= 8;
dest[0] = dwTmp & 0xFF;
iRet = 3;
}
else if( iUse == 3 )
{
dwTmp>>=2;
dest[1] = dwTmp & 0xFF;
dwTmp >>= 8;
dest[0] = dwTmp & 0xFF;
iRet = 2;
}
else if( iUse == 2 )
{
dwTmp>>=4;
dest[0] = dwTmp & 0xFF;
iRet = 1;
}
else if( iUse == 1)
{
dest[0] = dwTmp & 0xFF;
iRet = 1;
}
return iRet;
*/
_ESI = (unsigned long)m_DeBase64Tab;
asm
{
mov ebx,src
xor ecx,ecx
xor edx,edx
xor eax,eax
@fornext:
cmp ecx,4
jnl @forout
mov al,byte ptr [ebx]
inc ebx
mov al,byte ptr [eax + esi]
cmp al,255
jz @forout
cmp ecx,0
jng @fornext1
shl edx,6
@fornext1:
or edx,eax
inc ecx
jmp @fornext
@forout:
xor eax,eax
mov ebx,dest
cmp ecx,4
jnz @cmp3
mov cl,dl
shr edx,8
mov byte ptr [ebx],dh
inc ebx
mov byte ptr [ebx],dl
inc ebx
mov byte ptr [ebx],cl
mov al,3
jmp short @cmpout
@cmp3:
cmp ecx,3
jnz @cmp2
shr edx,2
mov byte ptr [ebx],dh
inc ebx
mov byte ptr [ebx],dl
mov al,2
jmp short @cmpout
@cmp2:
cmp ecx,2
jnz @cmp1
shr edx,4
mov byte ptr [ebx],dl
mov al,1
jmp short @cmpout
@cmp1:
cmp ecx,1
jnz @cmpout
mov byte ptr [ebx],dl
mov eax,1
jmp short @cmpout
@cmpout:
}
return _EAX;
}
/*
不作错误检查
但会检查是否是m_Base64FillChar结束符
*/
int XBase64::__DecodeBase64(const XByte * src,XByte * dest,int iUse)
{
// 该方法使用asm实现,下面注释的部分是其C++实现方法,实现的结果是完全一样的
/* if( iUse>4 || iUse <0 ) return 0;
XDWord dwTmp = 0;
int iRet = 0;
for(int iCount = 0; iCount<iUse; iCount++)
{
if( iCount>0 ) dwTmp <<= 6;
dwTmp |= m_DeBase64Tab[ *src++ ];
}
if( iUse == 4 )
{
dest[2] = dwTmp & 0xFF;
dwTmp >>= 8;
dest[1] = dwTmp & 0xFF;
dwTmp >>= 8;
dest[0] = dwTmp & 0xFF;
iRet = 3;
}
else if( iUse == 3 )
{
dwTmp>>=2;
dest[1] = dwTmp & 0xFF;
dwTmp >>= 8;
dest[0] = dwTmp & 0xFF;
iRet = 2;
}
else if( iUse == 2 )
{
dwTmp>>=4;
dest[0] = dwTmp & 0xFF;
iRet = 1;
}
else if( iUse == 1)
{
dest[0] = dwTmp & 0xFF;
iRet = 1;
}
return iRet;
*/
_ESI = (unsigned long)m_DeBase64Tab;
char chTmp = m_Base64FillChar;
asm
{
mov ecx,iUse
cmp ecx,4
jg @go1
cmp ecx,0
jnl @start
@go1:
xor eax,eax
jmp short @goreturn
@start:
xor ch,ch
xor edx,edx
mov ebx,src
xor eax,eax
@fornext:
cmp ch,cl
jnl @forout
mov al,byte ptr [ebx]
cmp al,chTmp
jz @breakfor
inc ebx
cmp ch,0
jng @fornext1:
shl edx,6
@fornext1:
mov al,byte ptr [esi + eax]
or edx,eax
inc ch
jmp @fornext
@breakfor:
mov cl,ch
@forout:
xor eax,eax
mov ebx,dest
xor ch,ch
cmp ecx,4
jnz @cmp3
mov cl,dl
shr edx,8
mov byte ptr [ebx],dh
inc ebx
mov byte ptr [ebx],dl
inc ebx
mov byte ptr [ebx],cl
mov al,3
jmp short @cmpout
@cmp3:
cmp ecx,3
jnz @cmp2
shr edx,2
mov byte ptr [ebx],dh
inc ebx
mov byte ptr [ebx],dl
mov al,2
jmp short @cmpout
@cmp2:
cmp ecx,2
jnz @cmp1
shr edx,4
mov byte ptr [ebx],dl
mov al,1
jmp short @cmpout
@cmp1:
cmp ecx,1
jnz @cmpout
mov byte ptr [ebx],dl
mov eax,1
jmp short @cmpout
@cmpout:
@goreturn:
}
return _EAX;
}
void XBase64::EncodeBase64(XByteBuffer & InBuffer,XByteBuffer & OutBuffer)
{
EncodeBase64(InBuffer.Data(),InBuffer.Length,OutBuffer);
}
void XBase64::EncodeBase64(const AnsiString & srcString,XByteBuffer & OutBuffer)
{
EncodeBase64(srcString.c_str(),srcString.Length(),OutBuffer);
}
AnsiString XBase64::EncodeBase64(XByteBuffer & InBuffer)
{
XByteBuffer TmpBuffer;
EncodeBase64(InBuffer,TmpBuffer);
TmpBuffer.AppendChar(0);
return (const char *)TmpBuffer.Data();
}
AnsiString XBase64::EncodeBase64(const void * srcData,int DataCount)
{
XByteBuffer TmpBuffer;
EncodeBase64(srcData,DataCount,TmpBuffer);
TmpBuffer.AppendChar(0);
return (const char *)TmpBuffer.Data();
}
AnsiString XBase64::EncodeBase64(const AnsiString & srcString)
{
XByteBuffer TmpBuffer;
EncodeBase64(srcString,TmpBuffer);
TmpBuffer.AppendChar(0);
return (const char *)TmpBuffer.Data();
}
void XBase64::DecodeBase64(const AnsiString & srcData,XByteBuffer & OutBuffer,bool bBreakByError)
{
DecodeBase64((const void *)srcData.c_str(),srcData.Length(),OutBuffer,bBreakByError);
}
void XBase64::DecodeBase64(const XByteBuffer & srcData,XByteBuffer & OutBuffer,bool bBreakByError)
{
DecodeBase64(srcData.Data(),srcData.Length,OutBuffer,bBreakByError);
}
AnsiString XBase64::DecodeBase64(const void * srcData,int DataCount,bool bBreakByError)
{
XByteBuffer OutBuffer;
DecodeBase64(srcData,DataCount,OutBuffer,bBreakByError);
OutBuffer.AppendChar(0);
return (const char *)OutBuffer.Data();
}
AnsiString XBase64::DecodeBase64(const AnsiString & srcData,bool bBreakByError)
{
XByteBuffer OutBuffer;
DecodeBase64(srcData,OutBuffer,bBreakByError);
OutBuffer.AppendChar(0);
return (const char *)OutBuffer.Data();
}
AnsiString XBase64::DecodeBase64(const XByteBuffer & srcData,bool bBreakByError)
{
XByteBuffer OutBuffer;
DecodeBase64(srcData,OutBuffer,bBreakByError);
OutBuffer.AppendChar(0);
return (const char *)OutBuffer.Data();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -