MD5加密算法(c语言实现)

这次我分享的是MD5加密算法。其实MD5这个大名在还没上密码学课之前我就听说过了,那时我才刚学php,视频里面的讲师说像密码这种重要的信息要用md5()函数处理下再存数据库,这么一说起来其实MD5算是我接触的第一个现代密码呢害羞

     考虑到可能有些人是为了科普一下才点进来看的,我还是结合自身经验和课本知识把MD5加密原理讲一下把,MD5算法的具体过程有以下4步:

    (1)附加填充位 

      课本原话:填充一个‘1’和若干个‘0’使其长度模512与448同余,然后再将消息的真实长度以64bit表示附加在填充结果后面,从而使得消息长度恰好为512bit的整数倍。(不知道这段话你们看懂没有,方正我看了很久才看懂的,大概以前语文真的是体育老师教的哭

      举例说明吧:

      如明文为iscbupt

      其16ascII码是105,115,99,98,117,112,116,转换成二进制便是01101001 01110011 01100011 01100010 01110101 01110000 01110100,这是长度为56,要使其长度模512与448同余,则需补充一个‘1’和391个‘0’。因为消息长度为56,所以用64位二进制表示为00110000   00~00(56个‘0’)。到目前为止512位全部填充完整了~

    (2)初始化链接变量 

      课本原话:MD5中有A、B、C、D 4个32为寄存器,最开始存放4个固定的32位的整数参数,即初始链接变量,这些参数用于第1轮运算。

      A=0x12345678,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210

   (3)分组处理(迭代压缩)  

     课本原话:MD5算法的分组处理(压缩函数)与分组密码的分组处理相似。它由4轮组成,512bit的消息分组Mi被分成16个子分组(每个子分组为32bit)参与每轮16步函数运算,即每轮包括16个步骤。每步的输入是4个32bit的链接变量(插句话~也就是A、B、C、D)和一个32bit的消息分组(是Mi哦~~),输出为32位值。经过4轮共64步后,得到的4个寄存器值分别与输入链接变量(也就是初始的A、B、C、D)进行模加,即是当前消息的中间散列值。

     明文是iscbupt的Mi如下:

     M0:01101001 01110011 01100011 01100010

     M1:01110101 01110000 01110100 10000000

     M2:00000000 00000000 00000000 00000000

     ................

     M14:00111000 00000000 00000000 00000000

     M15:00000000 00000000 00000000 00000000

   (4)步函数

     由于课本的图无法上传,那这里就由我来说下啦~~

     所有大轮(上文所说的4轮)里的所有小轮(16轮)都是同一个步函数A=B+((A+f(B,C,D)+M[j]+T[i])<<<s)) 即B、C、D进入f函数(这里的f函数就是课本里的非线性函数,包含F、G、H、I这四种函数),得到的结果与A模加,与M[j]模加(这里的j与第几大轮第几小轮有关),与T[i]模加(这里的i从1取到64),然后进行循环左移(左移的2位数也与第几大轮第几小轮有关),再与B模加,最后得到的结果赋值给A。

    一小轮结束后将A赋值给B,B赋值给C,C赋值给D,原本的D赋值给A,赋值完的A、B、C、D便可以进入下一轮。

    下面来说下上文j、左移步数step、T[i]的取值情况:

     第一大轮:

      j在这大轮是按顺序从0取到15

     第1、5、9、13小轮step=7;第2、6、10、14小轮step=12;第3、7、11、15小轮step=17;第4、8、12、16小轮step=22

      第二大轮:

      j的取值顺序为-----1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 

     第1、5、9、13小轮step=5;第2、6、10、14小轮step=9;第3、7、11、15小轮step=14;第4、8、12、16小轮step=20

     第三大轮:

     j的取值顺序为----- 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 

     第1、5、9、13小轮step=4;第2、6、10、14小轮step=11;第3、7、11、15小轮step=16;第4、8、12、16小轮step=23

     第四大轮:

      j的取值顺序为-----0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9

      第1、5、9、13小轮step=6;第2、6、10、14小轮step=10;第3、7、11、15小轮step=15;第4、8、12、16小轮step=21

     T[i]= 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,

  1.       0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
  2.        0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193,
  3.        0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51,
  4.        0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  5.        0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905,
  6.        0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681,
  7.        0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60,
  8.        0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
  9.        0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244,
  10.        0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
  11.        0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314,
  12.        0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
   
   MD5的加密原理到这里就讲完了,下面来说下注意事项,也是我这次编程发现的一些理解的误区(这些结论是在明文长度不大于448的情况下成了,大于448是否成立我并没有验证过..):

      1.MD5加密算法里面的所有模加都是模2的32次加,而不是模2加。举例说明下模2的32次加:如11101000......(省略了24个‘0’)+01110000.........(省略了24个‘0’)=101011000.......(省略了24个‘0’),共33位,取后32位最终得到01011000........(省略了24个‘0’)。

      2.初始的A、B、C、D 4个链接变量与M[j]在进入步函数前要先经过大小端处理,T[i]不需要。

      3.位数填充时(64bit),若长度的二进制位数不足,需要在二进制前补齐至8的整数倍而不是4的整数倍。如400=110010000

补齐后是00000001 10010000而不是00011001 00000000

      4.大小端处理不是单纯指12345678->78563412,之所以有前面这种变换,是因为12、34、56、78分别表示4个十进制数,也就是说表示第1个十进制数的十六进制数经过转换放在最后,第2个放在第1个前。。当1234表示第1个十进制数、5678表示第2个十进制数时,12345678->56781234而不是78563412。如:明文长度为400,M[14]为0x01900000,转换后为0x00000190而不是0x00009001


     下面附上代码(输入的明文字符个数不大于64)

 
  1. #include<stdio.h>
  2. /*各函数声明*/
  3. void shizhuaner(int in, int n, int *md5);
  4. void shizhuaner_weishu(int in, int *md5);
  5. void shiliuzhuaner(char *t, int *temp);
  6. void c_out(int *a);
  7. void abcd_out(int *a);
  8. void F(int *b, int *c, int *d, int *temp1, int *temp2);
  9. void G(int *b, int *c, int *d, int *temp1, int *temp2);
  10. void H(int *b, int *c, int *d, int *temp);
  11. void I(int *b, int *c, int *d, int *temp);
  12. void yu(int *a, int *b, int *temp);
  13. void huo(int *a, int *b, int *temp);
  14. void fei(int *a, int *temp);
  15. void yihuo(int *a, int *b, int *temp);
  16. void jia(int *a, int *b, int *temp);
  17. /*十进制转二进制函数*/
  18. void shizhuaner(int in, int n, int *md5)
  19. {
  20. int j, s, w;
  21. s = n / 4 + 1; //s是md5里面组的排位数,w是该组里面的位数
  22. w = n % 4;
  23. j = 1;
  24. do
  25. {
  26. md5[ 32 * s - 8 * w - j] = in % 2;
  27. in = in / 2;
  28. j++;
  29. } while (in != 0);
  30. while (j <= 8) //二进制不够八位时补零
  31. {
  32. md5[ 32 * s - 8 * w - j] = 0;
  33. j++;
  34. }
  35. }
  36. /* 位数填充时所用到的十进制转二进制函数 */
  37. void shizhuaner_weishu(int in, int *md5)
  38. {
  39. int i,j,temp, a[ 64];
  40. for (i = 0; in!= 0; i++)
  41. {
  42. a[i] = in % 2;
  43. in = in / 2;
  44. }
  45. while (i % 8 != 0) //二进制位数不够八的整数倍时补零
  46. {
  47. a[i] = 0;
  48. i++;
  49. }
  50. for (j = 0; j <i/ 2; j++)
  51. {
  52. temp = a[i - j - 1];
  53. a[i - j -1] = a[j];
  54. a[j] = temp;
  55. }
  56. temp = i/ 8;
  57. for (i=i -1; i < 64; i++)
  58. a[i] = 0;
  59. for (i = 0; i < 4; i++)
  60. {
  61. for (j = 0; j < 8; j++)
  62. md5[ 512 - temp * 8 + j - 32] = a[i * 8 + j];
  63. temp = temp - 1;
  64. }
  65. for (i = 0; i < 4; i++)
  66. {
  67. for (j = 0; j < 8; j++)
  68. md5[ 512 - (i + 1) * 8 + j ] = a[i * 8 + j+ 32];
  69. }
  70. }
  71. /* 十六进制转二进制函数 */
  72. void shiliuzhuaner(char *t, int *temp)
  73. {
  74. int i;
  75. for (i = 0; i < 8; i++)
  76. {
  77. switch (t[i])
  78. {
  79. case '0':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 0; } break;
  80. case '1':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 1; } break;
  81. case '2':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 0; } break;
  82. case '3':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 1; } break;
  83. case '4':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 0; } break;
  84. case '5':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 1; } break;
  85. case '6':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 0; } break;
  86. case '7':{temp[ 4 * i] = 0; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 1; } break;
  87. case '8':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 0; } break;
  88. case '9':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 1; } break;
  89. case 'a':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 0; } break;
  90. case 'b':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 0; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 1; } break;
  91. case 'c':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 0; } break;
  92. case 'd':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 0; temp[ 4 * i + 3] = 1; } break;
  93. case 'e':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 0; } break;
  94. case 'f':{temp[ 4 * i] = 1; temp[ 4 * i + 1] = 1; temp[ 4 * i + 2] = 1; temp[ 4 * i + 3] = 1; } break;
  95. }
  96. }
  97. }
  98. /* 密文输出函数 */
  99. void c_out(int *a)
  100. {
  101. int i,add;
  102. for (i = 1; i <= 4; i++) //二进制转换成十六进制输出
  103. {
  104. add = a[ 32 - i * 8] * 8 + a[ 32 - i * 8 + 1] * 4 + a[ 32 - i * 8 + 2] * 2 + a[ 32 - i * 8 + 3];
  105. if (add >= 10)
  106. {
  107. switch (add)
  108. {
  109. case 10: printf( "a"); break;
  110. case 11: printf( "b"); break;
  111. case 12: printf( "c"); break;
  112. case 13: printf( "d"); break;
  113. case 14: printf( "e"); break;
  114. case 15: printf( "f"); break;
  115. }
  116. }
  117. else
  118. printf( "%d", add);
  119. add = a[ 32 - i * 8+ 4] * 8 + a[ 32 - i * 8 + 5] * 4 + a[ 32 - i * 8 + 6] * 2 + a[ 32 - i * 8 + 7];
  120. if (add >= 10)
  121. {
  122. switch (add)
  123. {
  124. case 10: printf( "a"); break;
  125. case 11: printf( "b"); break;
  126. case 12: printf( "c"); break;
  127. case 13: printf( "d"); break;
  128. case 14: printf( "e"); break;
  129. case 15: printf( "f"); break;
  130. }
  131. }
  132. else
  133. printf( "%d", add);
  134. }
  135. }
  136. /* 中间过程的输出函数 */
  137. void abcd_out(int *a)
  138. {
  139. int i, add;
  140. for (i = 0; i < 4; i++) //二进制转换成十六进制输出
  141. {
  142. add = a[i * 8] * 8 + a[i * 8 + 1] * 4 + a[i * 8 + 2] * 2 + a[i * 8 + 3];
  143. if (add >= 10)
  144. {
  145. switch (add)
  146. {
  147. case 10: printf( "a"); break;
  148. case 11: printf( "b"); break;
  149. case 12: printf( "c"); break;
  150. case 13: printf( "d"); break;
  151. case 14: printf( "e"); break;
  152. case 15: printf( "f"); break;
  153. }
  154. }
  155. else
  156. printf( "%d", add);
  157. add = a[i * 8 + 4] * 8 + a[i * 8 + 5] * 4 + a[i * 8 + 6] * 2 + a[i * 8 + 7];
  158. if (add >= 10)
  159. {
  160. switch (add)
  161. {
  162. case 10: printf( "a"); break;
  163. case 11: printf( "b"); break;
  164. case 12: printf( "c"); break;
  165. case 13: printf( "d"); break;
  166. case 14: printf( "e"); break;
  167. case 15: printf( "f"); break;
  168. }
  169. }
  170. else
  171. printf( "%d", add);
  172. }
  173. }
  174. /* 与函数 */
  175. void yu(int *a, int *b,int *temp)
  176. {
  177. int i;
  178. for (i = 0; i < 32; i++) //同为1为1,否则为0
  179. {
  180. if (a[i] == 1 && b[i] == 1)
  181. temp[i] = 1;
  182. else
  183. temp[i] = 0;
  184. }
  185. }
  186. /* 或函数 */
  187. void huo(int *a, int *b, int *temp)
  188. {
  189. int i;
  190. for (i = 0; i < 32; i++) //同0为0,否则为1
  191. {
  192. if (a[i] == 0 && b[i] == 0)
  193. temp[i] = 0;
  194. else
  195. temp[i] = 1;
  196. }
  197. }
  198. /* 非函数 */
  199. void fei(int *a, int *temp)
  200. {
  201. int i;
  202. for (i = 0; i < 32; i++)
  203. {
  204. if (a[i] == 0)
  205. temp[i] = 1;
  206. else
  207. temp[i] = 0;
  208. }
  209. }
  210. /*异或函数*/
  211. void yihuo(int *a, int *b, int *temp)
  212. {
  213. int i;
  214. for (i = 0; i < 32; i++) //相同为0,不同为1
  215. {
  216. if (a[i] != b[i])
  217. temp[i] = 1;
  218. else
  219. temp[i] = 0;
  220. }
  221. }
  222. /* 模二的32次加 */
  223. void jia(int *a, int *b, int *temp)
  224. {
  225. int i,jin;
  226. jin = 0;
  227. for (i = 0; i < 32; i++)
  228. {
  229. if (a[ 31 - i] + b[ 31 - i] + jin> 1)
  230. {
  231. temp[ 31 - i] = a[ 31 - i] + b[ 31 - i] + jin - 2;
  232. jin = 1;
  233. }
  234. else
  235. {
  236. temp[ 31 - i] = a[ 31 - i] + b[ 31 - i]+jin;
  237. jin = 0;
  238. }
  239. }
  240. }
  241. /* F函数 */
  242. void F(int *b, int *c, int *d,int *temp1,int *temp2)
  243. {
  244. /* F(x,y,z)=(x∧y)∨(¬x∧z) */
  245. yu(b, c, temp1);
  246. fei(b, temp2);
  247. yu(temp2, d, temp2);
  248. huo(temp1, temp2, temp2);
  249. }
  250. /* G函数 */
  251. void G(int *b, int *c, int *d, int *temp1, int *temp2)
  252. {
  253. /* G(x,y,z)=(x∧z)∨(y∧¬z) */
  254. yu(b, d, temp1);
  255. fei(d, temp2);
  256. yu(temp2, c, temp2);
  257. huo(temp1, temp2, temp2);
  258. }
  259. /* H函数 */
  260. void H(int *b, int *c, int *d, int *temp)
  261. {
  262. /* H(x,y,z)=x⊕y⊕z */
  263. yihuo(b, c, temp);
  264. yihuo(temp, d, temp);
  265. }
  266. /* I函数 */
  267. void I(int *b, int *c, int *d, int *temp)
  268. {
  269. /* I(x,y,z)=y⊕(x∨¬z) */
  270. fei(d, temp);
  271. huo(b, temp, temp);
  272. yihuo(c, temp, temp);
  273. }
  274. /*左移函数*/
  275. void move(int step, int *temp1, int *temp2)
  276. {
  277. int i;
  278. for (i = 0; i < 32 - step; i++)
  279. temp2[i] = temp1[i + step];
  280. for (i = 0; i < step; i++)
  281. temp2[ 32 - step + i] = temp1[i];
  282. }
  283. /*每一大轮的16小轮循环函数*/
  284. void round(int *a, int *b, int *c, int *d, int *m, int *md5, int r, char *t1,
  285. char *t2, char *t3, char *t4, char *t5, char *t6, char *t7, char *t8, char *t9,
  286. char *t10, char *t11, char *t12, char *t13, char *t14, char *t15, char *t16 )
  287. {
  288. int i, j, in, step , temp1[ 32], temp2[ 32];
  289. for (i = 0; i < 16; i++)
  290. {
  291. switch (r) //根据r判断所选的逻辑函数
  292. {
  293. case 1:F(b, c, d, temp1, temp2); break;
  294. case 2:G(b, c, d, temp1, temp2); break;
  295. case 3:H(b, c, d, temp2); break;
  296. case 4:I(b, c, d, temp2); break;
  297. }
  298. in = m[i];
  299. for (j = 0; j < 32; j++)
  300. temp1[j] = md5[in * 32 + j];
  301. jia(temp2, temp1, temp2);
  302. switch (i + 1) //选择t[]
  303. {
  304. case 1:shiliuzhuaner(t1, temp1); break;
  305. case 2:shiliuzhuaner(t2, temp1); break;
  306. case 3:shiliuzhuaner(t3, temp1); break;
  307. case 4:shiliuzhuaner(t4, temp1); break;
  308. case 5:shiliuzhuaner(t5, temp1); break;
  309. case 6:shiliuzhuaner(t6, temp1); break;
  310. case 7:shiliuzhuaner(t7, temp1); break;
  311. case 8:shiliuzhuaner(t8, temp1); break;
  312. case 9:shiliuzhuaner(t9, temp1); break;
  313. case 10:shiliuzhuaner(t10, temp1); break;
  314. case 11:shiliuzhuaner(t11, temp1); break;
  315. case 12:shiliuzhuaner(t12, temp1); break;
  316. case 13:shiliuzhuaner(t13, temp1); break;
  317. case 14:shiliuzhuaner(t14, temp1); break;
  318. case 15:shiliuzhuaner(t15, temp1); break;
  319. case 16:shiliuzhuaner(t16, temp1); break;
  320. }
  321. jia(temp2, temp1, temp2);
  322. jia(temp2, a, temp2);
  323. switch(r) //根据r为左移步数step赋值
  324. {
  325. case 1: switch (i % 4 + 1){ case 1:step = 7; break; case 2:step = 12; break; case 3:step = 17; break; case 4:step = 22; break; } break;
  326. case 2: switch (i % 4 + 1){ case 1:step = 5; break; case 2:step = 9; break; case 3:step = 14; break; case 4:step = 20; break; } break;
  327. case 3: switch (i % 4 + 1){ case 1:step = 4; break; case 2:step = 11; break; case 3:step = 16; break; case 4:step = 23; break; } break;
  328. case 4: switch (i % 4 + 1){ case 1:step = 6; break; case 2:step = 10; break; case 3:step = 15; break; case 4:step = 21; break; } break;
  329. }
  330. move(step, temp2, temp1);
  331. jia(temp1, b, temp2);
  332. for (j = 0; j < 32; j++)
  333. {
  334. a[j] = d[j];
  335. d[j] = c[j];
  336. c[j] = b[j];
  337. b[j] = temp2[j];
  338. }
  339. /*若想输出每轮a、b、c、d的值,把下面的注释取消即可*/
  340. /*printf("第%d大轮的第%d小轮\n", r, i);
  341. abcd_out(a);
  342. printf(" ");
  343. abcd_out(b);
  344. printf(" ");
  345. abcd_out(c);
  346. printf(" ");
  347. abcd_out(d);
  348. printf("\n");*/
  349. }
  350. }
  351. /* 主函数 */
  352. int main()
  353. {
  354. char ch,
  355. /* 一大坨t[] */
  356. t1[ 8] = { 'd', '7', '6', 'a', 'a', '4', '7', '8' },
  357. t2[ 8] = { 'e', '8', 'c', '7', 'b', '7', '5', '6' },
  358. t3[ 8] = { '2', '4', '2', '0', '7', '0', 'd', 'b' },
  359. t4[ 8] = { 'c', '1', 'b', 'd', 'c', 'e', 'e', 'e' },
  360. t5[ 8] = { 'f', '5', '7', 'c', '0', 'f', 'a', 'f' },
  361. t6[ 8] = { '4', '7', '8', '7', 'c', '6', '2', 'a' },
  362. t7[ 8] = { 'a', '8', '3', '0', '4', '6', '1', '3' },
  363. t8[ 8] = { 'f', 'd', '4', '6', '9', '5', '0', '1' },
  364. t9[ 8] = { '6', '9', '8', '0', '9', '8', 'd', '8' },
  365. t10[ 8] = { '8', 'b', '4', '4', 'f', '7', 'a', 'f' },
  366. t11[ 8] = { 'f', 'f', 'f', 'f', '5', 'b', 'b', '1' },
  367. t12[ 8] = { '8', '9', '5', 'c', 'd', '7', 'b', 'e' },
  368. t13[ 8] = { '6', 'b', '9', '0', '1', '1', '2', '2' },
  369. t14[ 8] = { 'f', 'd', '9', '8', '7', '1', '9', '3' },
  370. t15[ 8] = { 'a', '6', '7', '9', '4', '3', '8', 'e' },
  371. t16[ 8] = { '4', '9', 'b', '4', '0', '8', '2', '1' },
  372. t17[ 8] = { 'f', '6', '1', 'e', '2', '5', '6', '2' },
  373. t18[ 8] = { 'c', '0', '4', '0', 'b', '3', '4', '0' },
  374. t19[ 8] = { '2', '6', '5', 'e', '5', 'a', '5', '1' },
  375. t20[ 8] = { 'e', '9', 'b', '6', 'c', '7', 'a', 'a' },
  376. t21[ 8] = { 'd', '6', '2', 'f', '1', '0', '5', 'd' },
  377. t22[ 8] = { '0', '2', '4', '4', '1', '4', '5', '3' },
  378. t23[ 8] = { 'd', '8', 'a', '1', 'e', '6', '8', '1' },
  379. t24[ 8] = { 'e', '7', 'd', '3', 'f', 'b', 'c', '8' },
  380. t25[ 8] = { '2', '1', 'e', '1', 'c', 'd', 'e', '6' },
  381. t26[ 8] = { 'c', '3', '3', '7', '0', '7', 'd', '6' },
  382. t27[ 8] = { 'f', '4', 'd', '5', '0', 'd', '8', '7' },
  383. t28[ 8] = { '4', '5', '5', 'a', '1', '4', 'e', 'd' },
  384. t29[ 8] = { 'a', '9', 'e', '3', 'e', '9', '0', '5' },
  385. t30[ 8] = { 'f', 'c', 'e', 'f', 'a', '3', 'f', '8' },
  386. t31[ 8] = { '6', '7', '6', 'f', '0', '2', 'd', '9' },
  387. t32[ 8] = { '8', 'd', '2', 'a', '4', 'c', '8', 'a' },
  388. t33[ 8] = { 'f', 'f', 'f', 'a', '3', '9', '4', '2' },
  389. t34[ 8] = { '8', '7', '7', '1', 'f', '6', '8', '1' },
  390. t35[ 8] = { '6', 'd', '9', 'd', '6', '1', '2', '2' },
  391. t36[ 8] = { 'f', 'd', 'e', '5', '3', '8', '0', 'c' },
  392. t37[ 8] = { 'a', '4', 'b', 'e', 'e', 'a', '4', '4' },
  393. t38[ 8] = { '4', 'b', 'd', 'e', 'c', 'f', 'a', '9' },
  394. t39[ 8] = { 'f', '6', 'b', 'b', '4', 'b', '6', '0' },
  395. t40[ 8] = { 'b', 'e', 'b', 'f', 'b', 'c', '7', '0' },
  396. t41[ 8] = { '2', '8', '9', 'b', '7', 'e', 'c', '6' },
  397. t42[ 8] = { 'e', 'a', 'a', '1', '2', '7', 'f', 'a' },
  398. t43[ 8] = { 'd', '4', 'e', 'f', '3', '0', '8', '5' },
  399. t44[ 8] = { '0', '4', '8', '8', '1', 'd', '0', '5' },
  400. t45[ 8] = { 'd', '9', 'd', '4', 'd', '0', '3', '9' },
  401. t46[ 8] = { 'e', '6', 'd', 'b', '9', '9', 'e', '5' },
  402. t47[ 8] = { '1', 'f', 'a', '2', '7', 'c', 'f', '8' },
  403. t48[ 8] = { 'c', '4', 'a', 'c', '5', '6', '6', '5' },
  404. t49[ 8] = { 'f', '4', '2', '9', '2', '2', '4', '4' },
  405. t50[ 8] = { '4', '3', '2', 'a', 'f', 'f', '9', '7' },
  406. t51[ 8] = { 'a', 'b', '9', '4', '2', '3', 'a', '7' },
  407. t52[ 8] = { 'f', 'c', '9', '3', 'a', '0', '3', '9' },
  408. t53[ 8] = { '6', '5', '5', 'b', '5', '9', 'c', '3' },
  409. t54[ 8] = { '8', 'f', '0', 'c', 'c', 'c', '9', '2' },
  410. t55[ 8] = { 'f', 'f', 'e', 'f', 'f', '4', '7', 'd' },
  411. t56[ 8] = { '8', '5', '8', '4', '5', 'd', 'd', '1' },
  412. t57[ 8] = { '6', 'f', 'a', '8', '7', 'e', '4', 'f' },
  413. t58[ 8] = { 'f', 'e', '2', 'c', 'e', '6', 'e', '0' },
  414. t59[ 8] = { 'a', '3', '0', '1', '4', '3', '1', '4' },
  415. t60[ 8] = { '4', 'e', '0', '8', '1', '1', 'a', '1' },
  416. t61[ 8] = { 'f', '7', '5', '3', '7', 'e', '8', '2' },
  417. t62[ 8] = { 'b', 'd', '3', 'a', 'f', '2', '3', '5' },
  418. t63[ 8] = { '2', 'a', 'd', '7', 'd', '2', 'b', 'b' },
  419. t64[ 8] = { 'e', 'b', '8', '6', 'd', '3', '9', '1' };
  420. int in, n = 0, i,j,addup;
  421. int md5[ 512],
  422. /*每一大轮m[]的调用顺序*/
  423. m1[ 16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
  424. m2[ 16] = { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 },
  425. m3[ 16] = { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 },
  426. m4[ 16] = { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 },
  427. /* a[]、b[]、c[]、d[]的初始值(已经过大小端处理) */
  428. /* 把a[]、b[]、c[]、d[]赋值给a1[]、b1[]、c1[]、d1[]*/
  429. a[ 32] = { 0, 1, 1, 0, 0, 1, 1, 1,
  430. 0, 1, 0, 0, 0, 1, 0, 1,
  431. 0, 0, 1, 0, 0, 0, 1, 1,
  432. 0, 0, 0, 0, 0, 0, 0, 1 },
  433. a1[ 32] = { 0, 1, 1, 0, 0, 1, 1, 1,
  434. 0, 1, 0, 0, 0, 1, 0, 1,
  435. 0, 0, 1, 0, 0, 0, 1, 1,
  436. 0, 0, 0, 0, 0, 0, 0, 1 },
  437. b[ 32] = { 1, 1, 1, 0, 1, 1, 1, 1,
  438. 1, 1, 0, 0, 1, 1, 0, 1,
  439. 1, 0, 1, 0, 1, 0, 1, 1,
  440. 1, 0, 0, 0, 1, 0, 0, 1 },
  441. b1[ 32] = { 1, 1, 1, 0, 1, 1, 1, 1,
  442. 1, 1, 0, 0, 1, 1, 0, 1,
  443. 1, 0, 1, 0, 1, 0, 1, 1,
  444. 1, 0, 0, 0, 1, 0, 0, 1 },
  445. c[ 32] = { 1, 0, 0, 1, 1, 0, 0, 0,
  446. 1, 0, 1, 1, 1, 0, 1, 0,
  447. 1, 1, 0, 1, 1, 1, 0, 0,
  448. 1, 1, 1, 1, 1, 1, 1, 0 },
  449. c1[ 32] = { 1, 0, 0, 1, 1, 0, 0, 0,
  450. 1, 0, 1, 1, 1, 0, 1, 0,
  451. 1, 1, 0, 1, 1, 1, 0, 0,
  452. 1, 1, 1, 1, 1, 1, 1, 0 },
  453. d[ 32] = { 0, 0, 0, 1, 0, 0, 0, 0,
  454. 0, 0, 1, 1, 0, 0, 1, 0,
  455. 0, 1, 0, 1, 0, 1, 0, 0,
  456. 0, 1, 1, 1, 0, 1, 1, 0 },
  457. d1[ 32] = { 0, 0, 0, 1, 0, 0, 0, 0,
  458. 0, 0, 1, 1, 0, 0, 1, 0,
  459. 0, 1, 0, 1, 0, 1, 0, 0,
  460. 0, 1, 1, 1, 0, 1, 1, 0 };
  461. printf( "请输入需加密的明文(长度不大于56)\n");
  462. ch = getchar();
  463. while (ch!= '\n'&&n< 57) //用getchar()函数接收字符,直到接收到回车符或字符数超过56为止
  464. {
  465. in = ( int)ch;
  466. shizhuaner(in, n, md5);
  467. n++;
  468. ch = getchar();
  469. }
  470. i = 0;
  471. addup = n;
  472. while (n% 4 != 0 && n< 56) //长度不是4的倍数,补一个1和0直到长度为4的倍数,,最终实现用1与0使其长度模512与448同于,在这个程序里也就是448
  473. {
  474. int s, w, j;
  475. s = n / 4 + 1;
  476. w = n % 4;
  477. j = 1;
  478. do
  479. {
  480. md5[ 32 * s - 8 * w - j] = 0;
  481. j++;
  482. } while (j<= 7);
  483. if (i == 0)
  484. {
  485. md5[ 32 * s - 8 * w - j] = 1;
  486. i = 1;
  487. }
  488. n++;
  489. }
  490. if (i == 0) //长度不是4的倍数,补一个1和31个0
  491. {
  492. for (j = 0; j < 32; j++)
  493. md5[n * 8 + j] = 0;
  494. md5[ 8 * n + 24] = 1;
  495. }
  496. for (i = 0; i < 512; i++) //补零,任何不为1的数都设为0
  497. {
  498. if (md5[i] == 1)
  499. md5[i] = 1;
  500. else
  501. md5[i] = 0;
  502. }
  503. printf( "\n");
  504. shizhuaner_weishu(addup * 8, md5); //64位数填充
  505. /*若想看m[0]~m[15],把下面注释去掉即可*/
  506. /*printf("m[0]~m[15]如下:\n");
  507. for (i = 0; i < 512; i++)
  508. {
  509. printf("%d ", md5[i]);
  510. if (i % 8 == 7)
  511. printf("\n");
  512. if (i % 32 == 31)
  513. printf("\n");
  514. }
  515. printf("\n");*/
  516. /* 第一、二、三、四大轮,每一大轮下有16小轮 */
  517. round(a, b, c, d, m1, md5, 1, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16);
  518. round(a, b, c, d, m2, md5, 2, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32);
  519. round(a, b, c, d, m3, md5, 3, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48);
  520. round(a, b, c, d, m4, md5, 4, t49, t50, t51, t52, t53, t54, t55, t56, t57, t58, t59, t60, t61, t62, t63, t64);
  521. printf( "\n");
  522. /* 最终的a、b、c、d分别与最初的a、b、c、d相加 */
  523. jia(a, a1, a);
  524. jia(b, b1, b);
  525. jia(c, c1, c);
  526. jia(d, d1, d);
  527. /*密文输出*/
  528. printf( "密文:\n");
  529. c_out(a);
  530. c_out(b);
  531. c_out(c);
  532. c_out(d);
  533. printf( "\n");
  534. return 0;
  535. }

运行结果:

示例1


示例2


示例3



使用说明:

1.因为我对位运算不是很了解,所以这份代码是没有使用位运算的。如果看时觉得混乱可以发邮件给我

2.默认情况下这份代码是不输出M[0]~M[15]和4大轮16小轮中A、B、C、D的变化情况的,如果想输出以上内容的话,在适当的位置取消注释便可(代码中有注释说明位置)

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值