经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C/C++编程学习:MD5算法代码实现
来源:cnblogs  作者:大天使维迦  时间:2021/2/22 9:07:50  对本文有异议

 

 

 

 

我们在计算算法的时候,通常都会使用MD5加密算法,而一般实现这些操作都以来函数,下面是C/C++MD5算法的实现代码,希望能为你带来帮助。

md5简介

消息摘要算法第五版(英语:Message-Digest Algorithm 5,缩写为MD5),是当前计算机领域用于确保信息传输完整一致而广泛使用的散列算法之一(又译哈希算法、摘要算法等),主流编程语言普遍已有MD5的实现。

将数据 (如一段文字)运算变为另一固定长度值,是散列算法的基础原理,MD5的前身有MD2、MD3和MD4。MD5由MD4、MD3、MD2改进而来,主要增强算法复杂度和不可逆性。

目前,MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通 数据的错误检查领域。例如在一些BitTorrent下载中,软件将通过计算MD5检验下载到的文件片段的完整性。

MD5已经广泛使用在为文件传输提供一定的可靠性方面。例如,服务器预先提供一个MD5校验和,用户下载完文件以后, 用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错。

MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个 128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

md5算法描述

假设输入信息(input message)的长度为b(bit),我们想要产生它的报文摘要,在此处b为任意的非负整数:b也可能为0,也不一定为8的整数倍,且可能是任意大的长度。设该信息的比特流表示如下: M[0] M[1] M[2] ... M[b-1] 计算此信息的报文摘要需要如下5步:

1.补位

信息计算前先要进行位补位,设补位后信息的长度为LEN(bit),则LEN%512 = 448(bit),即数据扩展至 K * 512 + 448(bit)。即K * 64+56(byte),K为整数。补位操作始终要执行,即使补位前信息的长度对512求余的结果是448。具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补1bit,最多补512bit。

2.尾部加上信息长度

将输入信息的原始长度b(bit)表示成一个64-bit的数字,把它添加到上一步的结果后面(在32位的机器上,这64位将用2个字来表示并且低位在前)。当遇到b大于2^64这种极少的情况时,b的高位被截去,仅使用b的低64位。

经过上面两步,数据就被填补成长度为512(bit)的倍数。也就是说,此时的数据长度是16个字(32byte)的整数倍。此时的数据表示为: M[0 ... N-1] 其中的N是16的倍数。

3.初始化缓存区

用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字,注意低字节在前: word A: 01 23 45 67 word B: 89 ab cd ef word C: fe dc ba 98 word D: 76 54 32 10

4.转换

首先定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字: F(X,Y,Z) = XY v not(X) Z G(X,Y,Z) = XZ v Y not(Z) H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X v not(Z))

FF(a,b,c,d,Mj,s,ti)表示 a = b + ((a + F(b,c,d) + Mj + ti)

下面是MD5算法的具体的实现

MD5算法的头文件Md5.h:

  1. #ifndef MD5_H
  2. #define MD5_H
  3. typedef struct
  4. {
  5. unsigned int count[2];
  6. unsigned int state[4];
  7. unsigned char buffer[64];
  8. }MD5_CTX;
  9. #define F(x,y,z) ((x & y) | (~x & z))
  10.  
  11. #define G(x,y,z) ((x & z) | (y & ~z))
  12.  
  13. #define H(x,y,z) (x^y^z)
  14.  
  15. #define I(x,y,z) (y ^ (x | ~z))
  16.  
  17. #define ROTATE_LEFT(x,n) ((x > (32-n)))
  18.  
  19. #define FF(a,b,c,d,x,s,ac) { \
  20. a += F(b, c, d) + x + ac;
  21. a = ROTATE_LEFT(a, s);
  22. a += b;
  23. }
  24. #define GG(a,b,c,d,x,s,ac) { \
  25. a += G(b, c, d) + x + ac;
  26. a = ROTATE_LEFT(a, s);
  27. a += b;
  28. }
  29. #define HH(a,b,c,d,x,s,ac) { \
  30. a += H(b, c, d) + x + ac;
  31. a = ROTATE_LEFT(a, s);
  32. a += b;
  33. }
  34. #define II(a,b,c,d,x,s,ac) { \
  35. a += I(b, c, d) + x + ac;
  36. a = ROTATE_LEFT(a, s);
  37. a += b;
  38. }
  39. void MD5Init(MD5_CTX *context);
  40. void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
  41. void MD5Final(MD5_CTX *context, unsigned char digest[16]);
  42. void MD5Transform(unsigned int state[4], unsigned char block[64]);
  43. void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
  44. void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
  45. #endif
  46. MD5算法的实现文件Md5.cpp
  47. unsigned char PADDING[] = {
  48. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  49. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  50. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  51. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  52. //在逆向代码的时候,需要关注下面的特征值
  53.  
  54. void MD5Init(MD5_CTX *context)
  55. {
  56. context->count[0] = 0;
  57. context->count[1] = 0;
  58. context->state[0] = 0x67452301;
  59. context->state[1] = 0xEFCDAB89;
  60. context->state[2] = 0x98BADCFE;
  61. context->state[3] = 0x10325476;
  62. }
  63. void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen)
  64. {
  65. unsigned int i = 0, index = 0, partlen = 0;
  66. index = (context->count[0] >> 3) & 0x3F;
  67. partlen = 64 - index;
  68. context->count[0] += inputlen count[0] count[1]++;
  69. context->count[1] += inputlen >> 29;
  70. if (inputlen >= partlen)
  71. {
  72. memcpy(&context->buffer[index], input, partlen);
  73. MD5Transform(context->state, context->buffer);
  74. for (i = partlen; i + 64 state, &input[i]);
  75. index = 0;
  76. }
  77. else
  78. {
  79. i = 0;
  80. }
  81. memcpy(&context->buffer[index], &input[i], inputlen - i);
  82. }
  83. void MD5Final(MD5_CTX *context, unsigned char digest[16])
  84. {
  85. unsigned int index = 0, padlen = 0;
  86. unsigned char bits[8];
  87. index = (context->count[0] >> 3) & 0x3F;
  88. padlen = (index count, 8);
  89. MD5Update(context, PADDING, padlen);
  90. MD5Update(context, bits, 8);
  91. MD5Encode(digest, context->state, 16);
  92. }
  93. void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len)
  94. {
  95. unsigned int i = 0, j = 0;
  96. while (j > 8) & 0xFF;
  97. output[j + 2] = (input[i] >> 16) & 0xFF;
  98. output[j + 3] = (input[i] >> 24) & 0xFF;
  99. i++;
  100. j += 4;
  101. }
  102. }
  103. void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)
  104. {
  105. unsigned int i = 0, j = 0;
  106. while (j
  107. MD5算法的调用测试:
  108. int _tmain(int argc, _TCHAR* argv[])
  109. {
  110. int i;
  111. unsigned char encrypt[] = "admin";//21232f297a57a5a743894a0e4a801fc3
  112. unsigned char decrypt[16];
  113. MD5_CTX md5;
  114. MD5Init(&md5);
  115. MD5Update(&md5, encrypt, strlen((char *)encrypt));
  116. MD5Final(&md5, decrypt);
  117. //Md5加密后的32位结果
  118. printf("加密前:%s\n加密后16位:", encrypt);

分享(源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

免费学习书籍:


 

免费学习资料:

 

原文链接:http://www.cnblogs.com/zuishuaideou/p/14426202.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号