www.pudn.com > 大型远程控制软件(偷窥者)源码大公开.zip > Base64.cpp


#include "stdafx.h" 
#include "Base64.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
CString CBase64::m_sBase64Alphabet =  
_T( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ); 
 
int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 }; 
 
CBase64::CBase64() 
{ 
} 
 
CBase64::~CBase64() 
{ 
} 
 
CString CBase64::Encode(LPCTSTR szEncoding, int nSize) 
{ 
	CString sOutput = _T( "" ); 
	int nNumBits = 6; 
	UINT nDigit; 
	int lp = 0; 
 
	ASSERT( szEncoding != NULL ); 
	if( szEncoding == NULL ) 
		return sOutput; 
	m_szInput = szEncoding; 
	m_nInputSize = nSize; 
 
	m_nBitsRemaining = 0; 
	nDigit = read_bits( nNumBits, &nNumBits, lp ); 
	while( nNumBits > 0 ) 
	{ 
		sOutput += m_sBase64Alphabet[ (int)nDigit ]; 
		nDigit = read_bits( nNumBits, &nNumBits, lp ); 
	} 
	// Pad with '=' as per RFC 1521 
	while( sOutput.GetLength() % 4 != 0 ) 
	{ 
		sOutput += '='; 
	} 
	return sOutput; 
} 
 
// The size of the output buffer must not be less than 
// 3/4 the size of the input buffer. For simplicity, 
// make them the same size. 
int CBase64::Decode(LPCTSTR szDecoding, LPTSTR szOutput) 
{ 
	CString sInput; 
    int c, lp =0; 
	int nDigit; 
    int nDecode[ 256 ]; 
 
	ASSERT( szDecoding != NULL ); 
	ASSERT( szOutput != NULL ); 
	if( szOutput == NULL ) 
		return 0; 
	if( szDecoding == NULL ) 
		return 0; 
	sInput = szDecoding; 
	if( sInput.GetLength() == 0 ) 
		return 0; 
 
	// Build Decode Table 
	// 
	for( int i = 0; i < 256; i++ )  
		nDecode[i] = -2; // Illegal digit 
	for( i=0; i < 64; i++ ) 
	{ 
		nDecode[ m_sBase64Alphabet[ i ] ] = i; 
		nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit 
		nDecode[ '=' ] = -1;  
		nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char 
    } 
 
	// Clear the output buffer 
	memset( szOutput, 0, sInput.GetLength() + 1 ); 
 
	// Decode the Input 
	// 
	for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ ) 
	{ 
		c = sInput[ lp ]; 
		nDigit = nDecode[ c & 0x7F ]; 
		if( nDigit < -1 )  
		{ 
			return 0; 
		}  
		else if( nDigit >= 0 )  
			// i (index into output) is incremented by write_bits() 
			write_bits( nDigit & 0x3F, 6, szOutput, i ); 
    }	 
	return i; 
} 
 
 
 
 
UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp) 
{ 
    ULONG lScratch; 
    while( ( m_nBitsRemaining < nNumBits ) &&  
		   ( lp < m_nInputSize ) )  
	{ 
		int c = m_szInput[ lp++ ]; 
        m_lBitStorage <<= 8; 
        m_lBitStorage |= (c & 0xff); 
		m_nBitsRemaining += 8; 
    } 
    if( m_nBitsRemaining < nNumBits )  
	{ 
		lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining ); 
		*pBitsRead = m_nBitsRemaining; 
		m_nBitsRemaining = 0; 
    }  
	else  
	{ 
		lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits ); 
		*pBitsRead = nNumBits; 
		m_nBitsRemaining -= nNumBits; 
    } 
    return (UINT)lScratch & m_nMask[nNumBits]; 
} 
 
 
void CBase64::write_bits(UINT nBits, 
						 int nNumBits, 
						 LPTSTR szOutput, 
						 int& i) 
{ 
	UINT nScratch; 
 
	m_lBitStorage = (m_lBitStorage << nNumBits) | nBits; 
	m_nBitsRemaining += nNumBits; 
	while( m_nBitsRemaining > 7 )  
	{ 
		nScratch = m_lBitStorage >> (m_nBitsRemaining - 8); 
		szOutput[ i++ ] = nScratch & 0xFF; 
		m_nBitsRemaining -= 8; 
	} 
}