⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 base32enc.h

📁 用于生成Base32代码的类,和atl里面的base64接口一致
💻 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 + -