Base64.cpp
上传用户:xmpantheon
上传日期:2016-10-20
资源大小:7502k
文件大小:4k
源码类别:

Email服务器

开发平台:

Visual C++

  1. // Base64.cpp: implementation of the CBase64 class.
  2. // Author: Wes Clyburn (clyburnw@enmu.edu)
  3. // 
  4. // This code was practically stolen from:
  5. // Dr. Dobb's Journal, September 1995, 
  6. // "Mime and Internet Mail", by Tim Kientzle
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "Base64.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. // Static Member Initializers
  16. //
  17. // The 7-bit alphabet used to encode binary information
  18. CString CBase64::m_sBase64Alphabet = 
  19. _T( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );
  20. int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
  21. //////////////////////////////////////////////////////////////////////
  22. // Construction/Destruction
  23. //////////////////////////////////////////////////////////////////////
  24. CBase64::CBase64()
  25. {
  26. }
  27. CBase64::~CBase64()
  28. {
  29. }
  30. CString CBase64::Encode(LPCTSTR szEncoding, int nSize)
  31. {
  32. CString sOutput = _T( "" );
  33. int nNumBits = 6;
  34. UINT nDigit;
  35. int lp = 0;
  36. ASSERT( szEncoding != NULL );
  37. if( szEncoding == NULL )
  38. return sOutput;
  39. m_szInput = szEncoding;
  40. m_nInputSize = nSize;
  41. m_nBitsRemaining = 0;
  42. nDigit = read_bits( nNumBits, &nNumBits, lp );
  43. while( nNumBits > 0 )
  44. {
  45. sOutput += m_sBase64Alphabet[ (int)nDigit ];
  46. nDigit = read_bits( nNumBits, &nNumBits, lp );
  47. }
  48. // Pad with '=' as per RFC 1521
  49. while( sOutput.GetLength() % 4 != 0 )
  50. {
  51. sOutput += '=';
  52. }
  53. return sOutput;
  54. }
  55. // The size of the output buffer must not be less than
  56. // 3/4 the size of the input buffer. For simplicity,
  57. // make them the same size.
  58. int CBase64::Decode(LPCTSTR szDecoding, LPTSTR szOutput)
  59. {
  60. CString sInput;
  61.     int c, lp =0;
  62. int nDigit;
  63.     int nDecode[ 256 ];
  64. ASSERT( szDecoding != NULL );
  65. ASSERT( szOutput != NULL );
  66. if( szOutput == NULL )
  67. return 0;
  68. if( szDecoding == NULL )
  69. return 0;
  70. sInput = szDecoding;
  71. if( sInput.GetLength() == 0 )
  72. return 0;
  73. // Build Decode Table
  74. //
  75. for( int i = 0; i < 256; i++ ) 
  76. nDecode[i] = -2; // Illegal digit
  77. for(int i=0; i < 64; i++ )
  78. {
  79. nDecode[ m_sBase64Alphabet[ i ] ] = i;
  80. nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit
  81. nDecode[ '=' ] = -1; 
  82. nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char
  83.     }
  84. // Clear the output buffer
  85. memset( szOutput, 0, sInput.GetLength() + 1 );
  86. // Decode the Input
  87. //
  88. int i;
  89. for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ )
  90. {
  91. c = sInput[ lp ];
  92. nDigit = nDecode[ c & 0x7F ];
  93. if( nDigit < -1 ) 
  94. {
  95. return 0;
  96. else if( nDigit >= 0 ) 
  97. // i (index into output) is incremented by write_bits()
  98. write_bits( nDigit & 0x3F, 6, szOutput, i );
  99.     }
  100. return i;
  101. }
  102. UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
  103. {
  104.     ULONG lScratch;
  105.     while( ( m_nBitsRemaining < nNumBits ) && 
  106.    ( lp < m_nInputSize ) ) 
  107. {
  108. int c = m_szInput[ lp++ ];
  109.         m_lBitStorage <<= 8;
  110.         m_lBitStorage |= (c & 0xff);
  111. m_nBitsRemaining += 8;
  112.     }
  113.     if( m_nBitsRemaining < nNumBits ) 
  114. {
  115. lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
  116. *pBitsRead = m_nBitsRemaining;
  117. m_nBitsRemaining = 0;
  118.     } 
  119. else 
  120. {
  121. lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
  122. *pBitsRead = nNumBits;
  123. m_nBitsRemaining -= nNumBits;
  124.     }
  125.     return (UINT)lScratch & m_nMask[nNumBits];
  126. }
  127. void CBase64::write_bits(UINT nBits,
  128.  int nNumBits,
  129.  LPTSTR szOutput,
  130.  int& i)
  131. {
  132. UINT nScratch;
  133. m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
  134. m_nBitsRemaining += nNumBits;
  135. while( m_nBitsRemaining > 7 ) 
  136. {
  137. nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
  138. szOutput[ i++ ] = nScratch & 0xFF;
  139. m_nBitsRemaining -= 8;
  140. }
  141. }