Base64.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /************************************************
  2. * *
  3. * CBase64.cpp *
  4. * Base 64 de- and encoding class *
  5. * *
  6. * ============================================ *
  7. * *
  8. * This class was written on 28.05.2003 *
  9. * by Jan Raddatz [jan-raddatz@web.de] *
  10. * *
  11. * ============================================ *
  12. * *
  13. * Copyright (c) by Jan Raddatz *
  14. * This class was published @ codeguru.com *
  15. * 28.05.2003 *
  16. * *
  17. ************************************************/
  18. #include "stdafx.h"
  19. #include "Base64.h"
  20. CBase64::CBase64 ()
  21. {
  22. }
  23. unsigned int CBase64::CalculateRecquiredEncodeOutputBufferSize (unsigned int p_InputByteCount)
  24. {
  25. div_t result = div (p_InputByteCount, 3);
  26. unsigned int RecquiredBytes = 0;
  27. if (result.rem == 0)
  28. {
  29. // Number of encoded characters
  30. RecquiredBytes = result.quot * 4;
  31. // CRLF -> "\r\n" each 76 characters
  32. result = div (RecquiredBytes, 76);
  33. RecquiredBytes += result.quot * 2;
  34. // Terminating null for the Encoded String
  35. RecquiredBytes += 1;
  36. return RecquiredBytes;
  37. }
  38. else
  39. {
  40. // Number of encoded characters
  41. RecquiredBytes = result.quot * 4 + 4;
  42. // CRLF -> "\r\n" each 76 characters
  43. result = div (RecquiredBytes, 76);
  44. RecquiredBytes += result.quot * 2;
  45. // Terminating null for the Encoded String
  46. RecquiredBytes += 1;
  47. return RecquiredBytes;
  48. }
  49. }
  50. unsigned int CBase64::CalculateRecquiredDecodeOutputBufferSize (char* p_pInputBufferString)
  51. {
  52. unsigned int BufferLength = strlen (p_pInputBufferString);
  53. div_t result = div (BufferLength, 4);
  54. if (p_pInputBufferString [BufferLength - 1] != '=')
  55. {
  56. return result.quot * 3;
  57. }
  58. else
  59. {
  60. if (p_pInputBufferString [BufferLength - 2] == '=')
  61. {
  62. return result.quot * 3 - 2;
  63. }
  64. else
  65. {
  66. return result.quot * 3 - 1;
  67. }
  68. }
  69. }
  70. void CBase64::EncodeByteTriple (char* p_pInputBuffer, unsigned int InputCharacters, char* p_pOutputBuffer)
  71. {
  72. unsigned int mask = 0xfc000000;
  73. unsigned int buffer = 0;
  74. char* temp = (char*) &buffer;
  75. temp [3] = p_pInputBuffer [0];
  76. if (InputCharacters > 1)
  77. temp [2] = p_pInputBuffer [1];
  78. if (InputCharacters > 2)
  79. temp [1] = p_pInputBuffer [2];
  80. switch (InputCharacters)
  81. {
  82. case 3:
  83. {
  84. p_pOutputBuffer [0] = BASE64_ALPHABET [(buffer & mask) >> 26];
  85. buffer = buffer << 6;
  86. p_pOutputBuffer [1] = BASE64_ALPHABET [(buffer & mask) >> 26];
  87. buffer = buffer << 6;
  88. p_pOutputBuffer [2] = BASE64_ALPHABET [(buffer & mask) >> 26];
  89. buffer = buffer << 6;
  90. p_pOutputBuffer [3] = BASE64_ALPHABET [(buffer & mask) >> 26];
  91. break;
  92. }
  93. case 2:
  94. {
  95. p_pOutputBuffer [0] = BASE64_ALPHABET [(buffer & mask) >> 26];
  96. buffer = buffer << 6;
  97. p_pOutputBuffer [1] = BASE64_ALPHABET [(buffer & mask) >> 26];
  98. buffer = buffer << 6;
  99. p_pOutputBuffer [2] = BASE64_ALPHABET [(buffer & mask) >> 26];
  100. p_pOutputBuffer [3] = '=';
  101. break;
  102. }
  103. case 1:
  104. {
  105. p_pOutputBuffer [0] = BASE64_ALPHABET [(buffer & mask) >> 26];
  106. buffer = buffer << 6;
  107. p_pOutputBuffer [1] = BASE64_ALPHABET [(buffer & mask) >> 26];
  108. p_pOutputBuffer [2] = '=';
  109. p_pOutputBuffer [3] = '=';
  110. break;
  111. }
  112. }
  113. }
  114. unsigned int CBase64::DecodeByteQuartet (char* p_pInputBuffer, char* p_pOutputBuffer)
  115. {
  116. unsigned int buffer = 0;
  117. if (p_pInputBuffer[3] == '=')
  118. {
  119. if (p_pInputBuffer[2] == '=')
  120. {
  121. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[0]]) << 6;
  122. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[1]]) << 6;
  123. buffer = buffer << 14;
  124. char* temp = (char*) &buffer;
  125. p_pOutputBuffer [0] = temp [3];
  126. return 1;
  127. }
  128. else
  129. {
  130. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[0]]) << 6;
  131. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[1]]) << 6;
  132. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[2]]) << 6;
  133. buffer = buffer << 8;
  134. char* temp = (char*) &buffer;
  135. p_pOutputBuffer [0] = temp [3];
  136. p_pOutputBuffer [1] = temp [2];
  137. return 2;
  138. }
  139. }
  140. else
  141. {
  142. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[0]]) << 6;
  143. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[1]]) << 6;
  144. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[2]]) << 6;
  145. buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[3]]) << 6;
  146. buffer = buffer << 2;
  147. char* temp = (char*) &buffer;
  148. p_pOutputBuffer [0] = temp [3];
  149. p_pOutputBuffer [1] = temp [2];
  150. p_pOutputBuffer [2] = temp [1];
  151. return 3;
  152. }
  153. return -1;
  154. }
  155. void CBase64::EncodeBuffer(char* p_pInputBuffer, unsigned int p_InputBufferLength, char* p_pOutputBufferString)
  156. {
  157. unsigned int FinishedByteQuartetsPerLine = 0;
  158. unsigned int InputBufferIndex = 0;
  159. unsigned int OutputBufferIndex = 0;
  160. memset (p_pOutputBufferString, 0, CalculateRecquiredEncodeOutputBufferSize (p_InputBufferLength));
  161. while (InputBufferIndex < p_InputBufferLength)
  162. {
  163. if (p_InputBufferLength - InputBufferIndex <= 2)
  164. {
  165. FinishedByteQuartetsPerLine ++;
  166. EncodeByteTriple (p_pInputBuffer + InputBufferIndex, p_InputBufferLength - InputBufferIndex, p_pOutputBufferString + OutputBufferIndex);
  167. break;
  168. }
  169. else
  170. {
  171. FinishedByteQuartetsPerLine++;
  172. EncodeByteTriple (p_pInputBuffer + InputBufferIndex, 3, p_pOutputBufferString + OutputBufferIndex);
  173. InputBufferIndex += 3;
  174. OutputBufferIndex += 4;
  175. }
  176. if (FinishedByteQuartetsPerLine == 19)
  177. {
  178. p_pOutputBufferString [OutputBufferIndex ] = '\r';
  179. p_pOutputBufferString [OutputBufferIndex+1] = '\n';
  180. p_pOutputBufferString += 2;
  181. FinishedByteQuartetsPerLine = 0;
  182. }
  183. }
  184. }
  185. unsigned int CBase64::DecodeBuffer (char* p_pInputBufferString, char* p_pOutputBuffer)
  186. {
  187. unsigned int InputBufferIndex = 0;
  188. unsigned int OutputBufferIndex = 0;
  189. unsigned int InputBufferLength = strlen (p_pInputBufferString);
  190. char ByteQuartet [4];
  191. while (InputBufferIndex < InputBufferLength)
  192. {
  193. for (int i = 0; i < 4; i++)
  194. {
  195. ByteQuartet [i] = p_pInputBufferString [InputBufferIndex];
  196. // Ignore all characters except the ones in BASE64_ALPHABET
  197. if ((ByteQuartet [i] >= 48 && ByteQuartet [i] <= 57) ||
  198. (ByteQuartet [i] >= 65 && ByteQuartet [i] <= 90) ||
  199. (ByteQuartet [i] >= 97 && ByteQuartet [i] <= 122) ||
  200. ByteQuartet [i] == '+' || ByteQuartet [i] == '/' || ByteQuartet [i] == '=')
  201. {
  202. }
  203. else
  204. {
  205. // Invalid character
  206. i--;
  207. }
  208. InputBufferIndex++;
  209. }
  210. OutputBufferIndex += DecodeByteQuartet (ByteQuartet, p_pOutputBuffer + OutputBufferIndex);
  211. }
  212. // OutputBufferIndex gives us the next position of the next decoded character
  213. // inside our output buffer and thus represents the number of decoded characters
  214. // in our buffer.
  215. return OutputBufferIndex;
  216. }
  217. unsigned int CBase64::CreateMatchingEncodingBuffer (unsigned int p_InputByteCount, char** p_ppEncodingBuffer)
  218. {
  219. unsigned int Size = CalculateRecquiredEncodeOutputBufferSize (p_InputByteCount);
  220. (*p_ppEncodingBuffer) = (char*) malloc (Size);
  221. memset (*p_ppEncodingBuffer, 0, Size);
  222. return Size;
  223. }
  224. unsigned int CBase64::CreateMatchingDecodingBuffer (char* p_pInputBufferString, char** p_ppDecodingBuffer)
  225. {
  226. unsigned int Size = CalculateRecquiredDecodeOutputBufferSize (p_pInputBufferString);
  227. (*p_ppDecodingBuffer) = (char*) malloc (Size+1);
  228. memset (*p_ppDecodingBuffer, 0, Size+1);
  229. return Size+1;
  230. }
  231. unsigned int CBase64::EncodeFile( CString p_pSourceFileName, CString p_pEncodedFileName )
  232. {
  233. CFile InputFile;
  234. CFile OutputFile;
  235. if (!InputFile.Open (p_pSourceFileName, CFile::modeRead))
  236. return UNABLE_TO_OPEN_INPUT_FILE;
  237. if (!OutputFile.Open (p_pEncodedFileName, CFile::modeCreate|CFile::modeWrite))
  238. return UNABLE_TO_OPEN_OUTPUT_FILE;
  239. char InputBuffer [19 * 3];
  240. char* pOutputBuffer;
  241. CreateMatchingEncodingBuffer (sizeof (InputBuffer), &pOutputBuffer);
  242. if (pOutputBuffer == 0)
  243. return UNABLE_TO_CREATE_OUTPUTBUFFER;
  244. unsigned int ReadBytes = 0;
  245. while ((ReadBytes = InputFile.Read (InputBuffer, sizeof (InputBuffer))) != 0)
  246. {
  247. EncodeBuffer (InputBuffer, ReadBytes, pOutputBuffer);
  248. OutputFile.Write (pOutputBuffer, strlen (pOutputBuffer));
  249. }
  250. OutputFile.Flush ();
  251. OutputFile.Close ();
  252. InputFile.Close ();
  253. return 0;
  254. }
  255. unsigned int CBase64::DecodeFile( CString p_pSourceFileName, CString p_pDecodedFileName )
  256. {
  257. CStdioFile InputFile;
  258. CFile OutputFile;
  259. if (!InputFile.Open (p_pSourceFileName, CFile::modeRead))
  260. return UNABLE_TO_OPEN_INPUT_FILE;
  261. if (!OutputFile.Open (p_pDecodedFileName, CFile::modeCreate|CFile::modeWrite))
  262. return UNABLE_TO_OPEN_OUTPUT_FILE;
  263. CString InputBuffer;
  264. char OutputBuffer[64];
  265. unsigned int ReadBytes = 0;
  266. while ((ReadBytes = InputFile.ReadString (InputBuffer)) != 0)
  267. {
  268. InputBuffer.Remove ('\r');
  269. InputBuffer.Remove ('\n');
  270. throw std::exception();
  271. //unsigned int DecodedBytes = DecodeBuffer ((LPTSTR) (LPCTSTR) InputBuffer, OutputBuffer);
  272. //OutputFile.Write (&OutputBuffer [0], DecodedBytes);
  273. }
  274. OutputFile.Flush ();
  275. OutputFile.Close ();
  276. InputFile.Close ();
  277. return 0;
  278. }