MFC封装的base64编码解码函数

本是古典 何须时尚 2022-12-10 14:42 465阅读 0赞

函数本就是网上下载的,经过我修改并测试通过以后,封装成C++代码了,并且使用了MFC的数据结构,懂C或C++的朋友可以拿过去稍作修改就可以用了。
提醒:作为C函数,在进行base64编码时一定要给够缓冲区,base64是将8比特数据封装到6比特里,所以缓冲区大小应该为原数据长度 x 4 / 3 + 3,同理,解码的时候则是原数据长度 x 3 / 4 +4,为什么+3、+4?这是因为整除会抛弃余数,余数最大值分别为:2、3,+3、4,多了1个字节,正好给结尾的字符0准备。

  1. #include "StdAfx.h"
  2. #include "base64.h"
  3. // 进行1次base64编码,返回编码的源字符串字符个数,-1代表出错
  4. static int base64_string( const unsigned char *src, size_t srclen, unsigned char *dest, size_t destlen, unsigned char *base64, int index )
  5. {
  6. if ( NULL == src || NULL == dest || NULL == base64 || index < 0)
  7. return -1;
  8. if (srclen <= 0 || destlen < 5) {
  9. return -1; // // dest多留1个给结尾的0
  10. }
  11. unsigned char one;
  12. unsigned char two;
  13. unsigned char thr;
  14. unsigned char fou;
  15. if ( srclen >= 3)
  16. {
  17. one = src[0] >> 2;
  18. two = ( ( src[0] & 0x03 ) << 4 ) | ( src[1] >> 4 );
  19. thr = ( ( src[1] & 0x0F ) << 2 ) | ( src[2] >> 6 );
  20. fou = src[2] & 0x3F;
  21. *( dest + index++ ) = base64[one];
  22. *( dest + index++ ) = base64[two];
  23. *( dest + index++ ) = base64[thr];
  24. *( dest + index ) = base64[fou];
  25. }
  26. else if ( srclen == 2)
  27. {
  28. one = src[0] >> 2;
  29. two = ( ( src[0] & 0x03) << 4 ) | ( src[1] >> 4 );
  30. thr = ( src[1] & 0x0F ) << 2;
  31. *( dest + index++ ) = base64[one];
  32. *( dest + index++ ) = base64[two];
  33. *( dest + index++ ) = base64[thr];
  34. *( dest + index ) = '=';
  35. }
  36. else if ( srclen == 1 )
  37. {
  38. one = src[0] >> 2;
  39. two = ( src[0] & 0x03 ) << 4;
  40. *( dest + index++ ) = base64[one];
  41. *( dest + index++ ) = base64[two];
  42. *( dest + index++ ) = '=';
  43. *( dest + index ) = '=';
  44. }
  45. return srclen >= 3 ? 3 : srclen;
  46. }
  47. // base64编码,传入的dest空间必须>=src * 4 / 3 + 3才能保证安全
  48. void base64_encode( const unsigned char *src, int srclen, unsigned char *dest, int destlen )
  49. {
  50. if ( NULL == src || srclen == 0 || NULL == dest || destlen < srclen * 4 / 3 + 3)
  51. return;
  52. unsigned char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  53. int index = 0;
  54. while ( srclen > 0 )
  55. {
  56. int step = base64_string( src, srclen, dest, destlen, base64, index );
  57. if (step == -1) {
  58. break;
  59. }
  60. destlen -= 4; // 每次用掉4字节
  61. index += 4; // 那么索引每次必然增加4
  62. srclen -= step; // 每次减少3字节或2或者1,2或1都是结尾剩余字符个数
  63. src += step; // 那么每次增加3或者2或者1
  64. }
  65. *( dest + index ) = '\0';
  66. }
  67. // 以上是base64编码的函数
  68. // 下面是base64解码的函数
  69. void create_array( unsigned char *array )
  70. {
  71. int index = 0;
  72. for ( index = 0; index < 123; index += 1 )
  73. {
  74. if ( index == 0x2B )
  75. {
  76. *( array + index ) = 0x3E;
  77. }
  78. else if ( index == 0x2F )
  79. {
  80. *( array + index ) = 0x3F;
  81. }
  82. else if ( index >= 0x30 && index <= 0x39 )
  83. {
  84. *( array + index ) = 0x34 + index - 0x30;
  85. }
  86. else if ( index == 0x3D )
  87. {
  88. /* 特殊字符'=',也可合并到else情况 */
  89. *( array + index ) = 0x00;
  90. }
  91. else if ( index >= 0x41 && index <= 0x5A )
  92. {
  93. *( array + index ) = index - 0x41;
  94. }
  95. else if ( index >= 0x61 && index <= 0x7A ) {
  96. *( array + index ) = 0x1A + index - 0x61;
  97. }
  98. else
  99. {
  100. *( array + index ) = 0x00;
  101. }
  102. }
  103. *( array + 123 ) = '\0';
  104. }
  105. int decode_string( const unsigned char *src, size_t srclen, unsigned char *dest, size_t destlen, unsigned char *array, int index )
  106. {
  107. if ( NULL == src || NULL == dest || NULL == array || index < 0)
  108. return -1;
  109. if (srclen < 4 || destlen < 4) {
  110. return -1; // // dest多留1个给结尾的0
  111. }
  112. int step = 0;
  113. unsigned char one;
  114. unsigned char two;
  115. unsigned char thr;
  116. if ( src[3] == '=' && src[2] == '=' )
  117. {
  118. one = ( array[src[0]] << 2 ) | ( array[src[1]] >> 4 );
  119. *( dest + index ) = one;
  120. step = 1;
  121. }
  122. else if ( src[3] == '=' )
  123. {
  124. one = ( array[src[0]] << 2 ) | ( array[src[1]] >> 4 );
  125. two = ( ( array[src[1]] & 0x0F ) << 4 ) | ( array[src[2]] >> 2 );
  126. *( dest + index++ ) = one;
  127. *( dest + index ) = two;
  128. step = 2;
  129. }
  130. else
  131. {
  132. one = ( array[src[0]] << 2 ) | ( array[src[1]] >> 4 );
  133. two = ( ( array[src[1]] & 0x0F ) << 4 ) | ( array[src[2]] >> 2 );
  134. thr = ( array[src[2]] << 6 ) | array[src[3]];
  135. *( dest + index++ ) = one;
  136. *( dest + index++ ) = two;
  137. *( dest + index ) = thr;
  138. step = 3;
  139. }
  140. return step;
  141. }
  142. // base64解码,传入的dest空间=src空间 * 3 / 4 + 4即可满足要求
  143. void base64_decode( const unsigned char *src, size_t srclen, unsigned char *dest, size_t destlen )
  144. {
  145. if ( NULL == src || NULL == dest || srclen < 0 || destlen < srclen * 3 / 4 + 4)
  146. return;
  147. static unsigned char array[124] = { '\0'};
  148. if (array[0x2B] == '\0') { // 需要初始化
  149. create_array( array );
  150. }
  151. int index = 0;
  152. while ( srclen )
  153. {
  154. int step = decode_string( src, srclen, dest, destlen, array, index );
  155. if (step == -1) {
  156. break;
  157. }
  158. srclen -= 4; // 每次解码4个字节
  159. src += 4; // 源字符串前进4字节
  160. destlen -= step; // 每次消耗step(可能是3字节,也可能是2字节或1字节)
  161. index += step; // 目标字符串每次前进step字节
  162. }
  163. *( dest + index ) = '\0';
  164. }
  165. // 下面是导出给MFC用的
  166. CString Base64Encode(const unsigned char *src, size_t srclen)
  167. {
  168. CString dest;
  169. srclen = srclen > 0 ? srclen : strlen((const char*)src);
  170. size_t destlen = srclen * 4 / 3 + 3;
  171. base64_encode(src, srclen, (unsigned char*)dest.GetBuffer(destlen), destlen);
  172. dest.ReleaseBuffer();
  173. return dest;
  174. }
  175. CString Base64Decode(const unsigned char *src, size_t srclen)
  176. {
  177. CString dest;
  178. srclen = srclen > 0 ? srclen : strlen((const char*)src);
  179. size_t destlen = srclen * 3 / 4 + 4;
  180. base64_decode(src, srclen, (unsigned char*)dest.GetBuffer(destlen), destlen);
  181. dest.ReleaseBuffer();
  182. return dest;
  183. }
  184. #ifndef __BASE64_20200920_H__
  185. #define __BASE64_20200920_H__
  186. __declspec(dllexport) CString Base64Encode(const unsigned char *src, size_t srclen = 0);
  187. __declspec(dllexport) CString Base64Decode(const unsigned char *src, size_t srclen = 0);
  188. #endif

发表评论

表情:
评论列表 (有 0 条评论,465人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Base64编码解码算法

    Base64不是什么新奇的算法了,不过如果你没从事过页面开发(或者说动态页面开发,尤其是邮箱服务),你都不怎么了解过,只是听起来很熟悉。 对于黑客来说,Base64与MD5算

    相关 BASE64编码解码

    BASE64,是一种公共编解码算法 大家都是遵循同一种算法来对字节数组进行编解码,所以可以通用. java在很多公共的框架中都有BASE64的实现. 可以用: A