base64加密解密

朱雀 2022-05-29 04:51 567阅读 0赞

1.定义

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。

2.原理

转码过程例子:
3*8=4*6
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机是8位8位的存数 6不够,自动就补两个高位0了
所有有了 高位补0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z

  先以“迅雷下载”为例: 很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
其实迅雷的“专用地址”也是用Base64”加密”的,其过程如下:
一、在地址的前后分别添加AA和ZZ
二、对新的字符串进行Base64编码
另: Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,Flashget在地址前后加的“料”是[FLASHGET]

而QQ旋风的干脆不加料,直接就对地址进行Base64编码了

3.实例

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef unsigned char u_char;
  5. #define C_B64_CHAR62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  6. /**
  7. * @fn static inline void _WRITE_B64( char *p, char a, char b, char c, char const *ct )
  8. * @brief 具体解密计算,三个字符一组进行计算
  9. *
  10. * @param[in] a:第一个加密字符
  11. * @param[in] b:第二个加密字符
  12. * @param[in] c:第三个加密字符
  13. * @param[in] ct:加密表
  14. * @param[out] p:加密后的输出参数
  15. *
  16. * @retval
  17. */
  18. static inline void _WRITE_B64( char *p, char a, char b, char c, char const *ct )
  19. {
  20. p[0] = ct[ (u_char)((a >> 2) & 0x3F) ];
  21. p[1] = ct[ (u_char)(((a << 4) & 0x30) | ((b >> 4) & 0x0F)) ];
  22. p[2] = ct[ (u_char)(((b << 2) & 0x3C) | ((c >> 6) & 0x03)) ];
  23. p[3] = ct[ (u_char)(c & 0x3F) ];
  24. }
  25. /**
  26. * @fn void c_b64_encrypt( char *obj, char const *src, size_t len, char const *ct, char tc )
  27. * @brief 加密操作
  28. *
  29. * @param[in] src:加密数据源
  30. * @param[in] len:数据长度
  31. * @param[in] tc:密钥
  32. * @param[in] ct:加密表
  33. * @param[out] obj:加密后输出缓冲区
  34. *
  35. * @retval
  36. */
  37. void c_b64_encrypt( char *obj, char const *src, size_t len, char const *ct, char tc )
  38. {
  39. char const *ps;
  40. ps = src;
  41. while(len >= 3)
  42. {
  43. _WRITE_B64(obj, ps[0], ps[1], ps[2], ct);
  44. len -= 3;
  45. ps += 3;
  46. obj += 4;
  47. }
  48. switch(len)
  49. {
  50. case 1:
  51. _WRITE_B64(obj, ps[0], 0, 0, ct);
  52. obj += 2;
  53. *obj++ = tc;
  54. *obj++ = tc;
  55. break;
  56. case 2:
  57. _WRITE_B64(obj, ps[0], ps[1], 0, ct);
  58. obj += 3;
  59. *obj++ = tc;
  60. break;
  61. }
  62. }
  63. size_t c_strlen( char const *p, size_t c )
  64. {
  65. size_t i;
  66. for(i = 0; i != c; ++i)
  67. {
  68. if(!p[i])
  69. {
  70. break;
  71. }
  72. }
  73. return i;
  74. }
  75. /**
  76. * @fn void c_b64_decrypt( char *obj, char const *src, size_t len, char const *dt, char tc )
  77. * @brief 解密操作
  78. *
  79. * @param[in] src:解密数据源
  80. * @param[in] len:数据长度
  81. * @param[in] tc:密钥
  82. * @param[in] dt:加密表
  83. * @param[out] obj:加密后输出缓冲区
  84. *
  85. * @retval
  86. */
  87. void c_b64_decrypt( char *obj, char const *src, size_t len, char const *dt, char tc )
  88. {
  89. char a, b, c, d;
  90. char const *end;
  91. if(len == (size_t)(-1))
  92. {
  93. len = c_strlen(src, (size_t)-1);
  94. }
  95. end = src + len;
  96. while(src < end)
  97. {
  98. a = dt[(u_char)src[0]];
  99. b = dt[(u_char)src[1]];
  100. c = dt[(u_char)src[2]];
  101. d = dt[(u_char)src[3]];
  102. if(src[3] == tc)
  103. {
  104. if(src[2] == tc)
  105. {
  106. obj[0] = (((a << 2) & 0xFC) | ((b >> 4) & 0x03));
  107. }
  108. else
  109. {
  110. obj[0] = (((a << 2) & 0xFC) | ((b >> 4) & 0x03));
  111. obj[1] = (((b << 4) & 0xF0) | ((c >> 2) & 0x0F));
  112. }
  113. }
  114. else
  115. {
  116. obj[0] = (((a << 2) & 0xFC) | ((b >> 4) & 0x03));
  117. obj[1] = (((b << 4) & 0xF0) | ((c >> 2) & 0x0F));
  118. obj[2] = (((c << 6) & 0xC0) | (d & 0x3F));
  119. }
  120. src += 4;
  121. obj += 3;
  122. }
  123. }
  124. /**
  125. * @fn void c_b64_decrypt_table( char *dt, char const *ct )
  126. * @brief 获取解密表
  127. *
  128. * @param[in] ct:加密表
  129. * @param[out] dt:解密表
  130. *
  131. * @retval
  132. */
  133. void c_b64_decrypt_table( char *dt, char const *ct )
  134. {
  135. int i;
  136. memset(dt, 0, 256);
  137. for(i = 0; i != 64; ++i)
  138. {
  139. dt[ (u_char)ct[i] ] = (char)i;
  140. }
  141. }
  142. int main()
  143. {
  144. char obj[256] = {0};
  145. char *src = "1abc中国……7,。、23456789";
  146. printf("src:%s\n",src);
  147. size_t len = strlen(src)+1;
  148. char tc = ':';
  149. c_b64_encrypt(obj, src, len, C_B64_CHAR62, tc);
  150. printf("obj:%s\n",obj);
  151. char dt[256] = {0};
  152. char dobj[256] = {0};
  153. len = strlen(obj)+1;
  154. c_b64_decrypt_table(dt,C_B64_CHAR62);
  155. c_b64_decrypt(dobj, obj,len,dt,tc);
  156. printf("dobj:%s\n",dobj);
  157. return 0;
  158. }

发表评论

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

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

相关阅读

    相关 base64加密解密

    1.定义 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2

    相关 多重base64加密解密

    单次base64编码不安全 base64只是一种编码,严格来说,不算是加密,只能"防君子不防小人",当然多次也一样的,虽然多次编码后不容易被一下子翻译成明文,但是仍然是不