Base64.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:5k
源码类别:

CA认证

开发平台:

Visual C++

  1. /*
  2. Module : Base64.cpp
  3. Purpose: Implementation for a simple base64 decoding class
  4. Created: PJN / 22-04-1999
  5. History: None                    
  6. Copyright (c) 1999 - 2004 by PJ Naughter.  
  7. All rights reserved.
  8. Copyright / Usage Details:
  9. You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
  10. when your product is released in binary form. You are allowed to modify the source code in any way you want 
  11. except you cannot modify the copyright details at the top of each module. If you want to distribute source 
  12. code with your application, then you are only allowed to distribute versions released by the author. This is 
  13. to maintain a single distribution point for the source code. 
  14. */
  15. //////////////// Includes ////////////////////////////////////////////
  16. #include "stdafx.h"
  17. #include "Base64.h"
  18. //////////////// Statics / Macros ////////////////////////////////////
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char THIS_FILE[]=__FILE__;
  22. #define new DEBUG_NEW
  23. #endif
  24. //////////////// Implementation //////////////////////////////////////
  25. int CBase64::DecodeGetRequiredLength(int nSrcLen)
  26. {
  27. return nSrcLen;
  28. }
  29. int CBase64::EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags)
  30. {
  31. int nRet = nSrcLen*4/3;
  32. if ((dwFlags & BASE64_FLAG_NOPAD) == 0)
  33. nRet += nSrcLen % 3;
  34. int nCRLFs = nRet / 76 + 1;
  35. int nOnLastLine = nRet % 76;
  36. if (nOnLastLine)
  37. {
  38. if (nOnLastLine % 4)
  39. nRet += 4-(nOnLastLine % 4);
  40. }
  41. nCRLFs *= 2;
  42. if ((dwFlags & BASE64_FLAG_NOCRLF) == 0)
  43. nRet += nCRLFs;
  44. return nRet;
  45. }
  46. BOOL CBase64::Encode(const BYTE* pbSrcData, int nSrcLen, LPSTR szDest, int* pnDestLen, DWORD dwFlags)
  47. {
  48. static const char s_chBase64EncodingTable[64] = 
  49.   {
  50. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
  51. 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
  52. 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
  53. 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
  54.   //Validate our parameters
  55. if (!pbSrcData || !szDest || !pnDestLen)
  56. return FALSE;
  57. ASSERT(*pnDestLen >= EncodeGetRequiredLength(nSrcLen, dwFlags));
  58. int nWritten( 0 );
  59. int nLen1( (nSrcLen/3)*4 );
  60. int nLen2( nLen1/76 );
  61. int nLen3( 19 );
  62. for (int i=0; i<=nLen2; i++)
  63. {
  64. if (i==nLen2)
  65. nLen3 = (nLen1%76)/4;
  66. for (int j=0; j<nLen3; j++)
  67. {
  68. DWORD dwCurr(0);
  69. for (int n=0; n<3; n++)
  70. {
  71. dwCurr |= *pbSrcData++;
  72. dwCurr <<= 8;
  73. }
  74. for (int k=0; k<4; k++)
  75. {
  76. BYTE b = (BYTE)(dwCurr>>26);
  77. *szDest++ = s_chBase64EncodingTable[b];
  78. dwCurr <<= 6;
  79. }
  80. }
  81. nWritten+= nLen3*4;
  82. if ((dwFlags & BASE64_FLAG_NOCRLF)==0)
  83. {
  84. *szDest++ = 'r';
  85. *szDest++ = 'n';
  86. nWritten+= 2;
  87. }
  88. }
  89. if (nWritten && (dwFlags & BASE64_FLAG_NOCRLF)==0)
  90. {
  91. szDest-= 2;
  92. nWritten -= 2;
  93. }
  94. nLen2 = nSrcLen%3 ? nSrcLen%3 + 1 : 0;
  95. if (nLen2)
  96. {
  97. DWORD dwCurr(0);
  98. for (int n=0; n<3; n++)
  99. {
  100. if (n<(nSrcLen%3))
  101. dwCurr |= *pbSrcData++;
  102. dwCurr <<= 8;
  103. }
  104. for (int k=0; k<nLen2; k++)
  105. {
  106. BYTE b = (BYTE)(dwCurr>>26);
  107. *szDest++ = s_chBase64EncodingTable[b];
  108. dwCurr <<= 6;
  109. }
  110. nWritten+= nLen2;
  111. if ((dwFlags & BASE64_FLAG_NOPAD)==0)
  112. {
  113. nLen3 = nLen2 ? 4-nLen2 : 0;
  114. for (int j=0; j<nLen3; j++)
  115. {
  116. *szDest++ = '=';
  117. }
  118. nWritten+= nLen3;
  119. }
  120. }
  121. *pnDestLen = nWritten;
  122. return TRUE;
  123. }
  124. int CBase64::DecodeChar(unsigned int ch)
  125. {
  126. // returns -1 if the character is invalid
  127. // or should be skipped
  128. // otherwise, returns the 6-bit code for the character
  129. // from the encoding table
  130. if (ch >= 'A' && ch <= 'Z')
  131. return ch - 'A' + 0; // 0 range starts at 'A'
  132. if (ch >= 'a' && ch <= 'z')
  133. return ch - 'a' + 26; // 26 range starts at 'a'
  134. if (ch >= '0' && ch <= '9')
  135. return ch - '0' + 52; // 52 range starts at '0'
  136. if (ch == '+')
  137. return 62;
  138. if (ch == '/')
  139. return 63;
  140. return -1;
  141. }
  142. BOOL CBase64::Decode(LPCSTR szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen)
  143. {
  144. // walk the source buffer
  145. // each four character sequence is converted to 3 bytes
  146. // CRLFs and =, and any characters not in the encoding table
  147. // are skiped
  148.   //Validate our parameters
  149. if (!szSrc || !pbDest || !pnDestLen)
  150. return FALSE;
  151. LPCSTR szSrcEnd = szSrc + nSrcLen;
  152. int nWritten = 0;
  153. while (szSrc < szSrcEnd)
  154. {
  155. DWORD dwCurr = 0;
  156. int i;
  157. int nBits = 0;
  158. for (i=0; i<4; i++)
  159. {
  160. if (szSrc >= szSrcEnd)
  161. break;
  162. int nCh = DecodeChar(*szSrc);
  163. szSrc++;
  164. if (nCh == -1)
  165. {
  166. // skip this char
  167. i--;
  168. continue;
  169. }
  170. dwCurr <<= 6;
  171. dwCurr |= nCh;
  172. nBits += 6;
  173. }
  174. // dwCurr has the 3 bytes to write to the output buffer
  175. // left to right
  176. dwCurr <<= 24-nBits;
  177. for (i=0; i<nBits/8; i++)
  178. {
  179. *pbDest = (BYTE) ((dwCurr & 0x00ff0000) >> 16);
  180. dwCurr <<= 8;
  181. pbDest++;
  182. nWritten++;
  183. }
  184. }
  185. *pnDestLen = nWritten;
  186. return TRUE;
  187. }