📄 base32enc.h
字号:
#pragma once
#include <string>
namespace base32enc
{
const DWORD BASE32_FLAG_NONE = 0;
const DWORD BASE32_FLAG_NOPAD = 1;
const DWORD BASE32_FLAG_NOCRLF = 2;
inline
int Base32EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags=BASE32_FLAG_NONE) throw()
{
int nRet = (nSrcLen * 8 + 4) / 5;
if ((dwFlags & BASE32_FLAG_NOPAD) == 0)
nRet = (nRet + 7) / 8 * 8;
if ((dwFlags & BASE32_FLAG_NOCRLF) == 0)
{
int nCRLFs = nRet / 72 + 1;
nRet += nCRLFs * 2;
}
return nRet;
}
inline
int Base32DecodeGetRequiredLength(int nSrcLen) throw()
{
return nSrcLen;
}
inline
BOOL Base32Encode(
const BYTE *pbSrcData,
int nSrcLen,
LPSTR szDest,
int *pnDestLen,
DWORD dwFlags=BASE32_FLAG_NONE) throw()
{
static const CHAR s_chBase32EncodingTable[] = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; //不包含 0,1,I,O,共32个字符
if (!pbSrcData || !szDest || !pnDestLen)
{
return FALSE;
}
if(*pnDestLen < Base32EncodeGetRequiredLength(nSrcLen, dwFlags))
{
ATLASSERT(FALSE);
return FALSE;
}
int nWritten( 0 );
int nLen1( (nSrcLen/5)*8 );
int nLen2( nLen1/72 );
int nLen3( 9 );
for (int i=0; i<=nLen2; i++)
{
if (i==nLen2)
nLen3 = (nLen1%72)/8;
for (int j=0; j<nLen3; j++)
{
UINT64 qwCurr(0);
for (int n=0; n<5; n++)
{
qwCurr |= *pbSrcData++;
qwCurr <<= 8;
}
qwCurr <<= 16;
for (int k=0; k<8; k++)
{
BYTE b = (BYTE)(qwCurr>>59);
*szDest++ = s_chBase32EncodingTable[b];
qwCurr <<= 5;
}
}
nWritten+= nLen3*8;
if ((dwFlags & BASE32_FLAG_NOCRLF)==0)
{
*szDest++ = '\r';
*szDest++ = '\n';
nWritten+= 2;
}
}
if (nWritten && (dwFlags & BASE32_FLAG_NOCRLF)==0)
{
szDest-= 2;
nWritten -= 2;
}
nLen2 = nSrcLen%5 ? (nSrcLen%5*8+4)/5 : 0;
if (nLen2)
{
UINT64 qwCurr(0);
for (int n=0; n<5; n++)
{
if (n<(nSrcLen%5))
qwCurr |= *pbSrcData++;
qwCurr <<= 8;
}
qwCurr <<= 16;
for (int k=0; k<nLen2; k++)
{
BYTE b = (BYTE)(qwCurr>>59);
*szDest++ = s_chBase32EncodingTable[b];
qwCurr <<= 5;
}
nWritten+= nLen2;
if ((dwFlags & BASE32_FLAG_NOPAD)==0)
{
nLen3 = nLen2 ? 8-nLen2 : 0;
for (int j=0; j<nLen3; j++)
{
*szDest++ = '=';
}
nWritten+= nLen3;
}
}
*pnDestLen = nWritten;
return TRUE;
}
inline
int DecodeBase32Char(unsigned int ch) throw()
{
// returns -1 if the character is invalid
// or should be skipped
// otherwise, returns the 5-bit code for the character
// from the encoding table
//"ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; //不包含 0,1,I,O,共32个字符
if (ch >= 'A' && ch <= 'H')
return ch - 'A' + 0; // 0 range starts at 'A'
if (ch >= 'J' && ch <= 'N')
return ch - 'J' + 8; // 8 range starts at 'J'
if (ch >= 'P' && ch <= 'Z')
return ch - 'P' + 13; // 13 range starts at 'P'
if (ch >= '2' && ch <= '9')
return ch - '2' + 24; // 24 range starts at '2'
return -1;
}
inline
BOOL Base32Decode(LPCSTR szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen) throw()
{
// walk the source buffer
// each four character sequence is converted to 5 bytes
// CRLFs and =, and any characters not in the encoding table
// are skiped
if (szSrc == NULL || pnDestLen == NULL)
{
ATLASSERT(FALSE);
return FALSE;
}
LPCSTR szSrcEnd = szSrc + nSrcLen;
int nWritten = 0;
BOOL bOverflow = (pbDest == NULL) ? TRUE : FALSE;
while (szSrc < szSrcEnd)
{
UINT64 qwCurr = 0;
int i;
int nBits = 0;
for (i=0; i<8; i++)
{
if (szSrc >= szSrcEnd)
break;
int nCh = DecodeBase32Char(*szSrc);
szSrc++;
if (nCh == -1)
{
// skip this char
i--;
continue;
}
qwCurr <<= 5;
qwCurr |= nCh;
nBits += 5;
}
if(!bOverflow && nWritten + (nBits/8) > (*pnDestLen))
bOverflow = TRUE;
// qwCurr has the 5 bytes to write to the output buffer
// left to right
qwCurr <<= 40-nBits;
for (i=0; i<nBits/8; i++)
{
if(!bOverflow)
{
*pbDest = (BYTE) ((qwCurr & 0x000000ff00000000) >> 32);
pbDest++;
}
qwCurr <<= 8;
nWritten++;
}
}
*pnDestLen = nWritten;
if(bOverflow)
{
if(pbDest != NULL)
ATLASSERT(FALSE);
return FALSE;
}
return TRUE;
}
} //namespace base32enc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -