md5加密算法

举报
鱼酱 发表于 2022/01/06 23:38:15 2022/01/06
【摘要】 MD5.h #ifndef MD5H#define MD5H#include <math.h>#include <Windows.h> void ROL(unsigned int &s, unsigned short cx); //32位数循环左移实现函数void ltob(unsigned i...

MD5.h



  
  1. #ifndef MD5H
  2. #define MD5H
  3. #include <math.h>
  4. #include <Windows.h>
  5. void ROL(unsigned int &s, unsigned short cx); //32位数循环左移实现函数
  6. void ltob(unsigned int &i); //B\L互转,接受UINT类型
  7. unsigned int* MD5(const char* mStr); //接口函数,并执行数据填充,计算MD5时调用此函数
  8. #endif

MD5.cpp


  
  1. #include "MD5.h"
  2. /*4组计算函数*/
  3. inline unsigned int F(unsigned int X, unsigned int Y, unsigned int Z)
  4. {
  5. return (X & Y) | ((~X) & Z);
  6. }
  7. inline unsigned int G(unsigned int X, unsigned int Y, unsigned int Z)
  8. {
  9. return (X & Z) | (Y & (~Z));
  10. }
  11. inline unsigned int H(unsigned int X, unsigned int Y, unsigned int Z)
  12. {
  13. return X ^ Y ^ Z;
  14. }
  15. inline unsigned int I(unsigned int X, unsigned int Y, unsigned int Z)
  16. {
  17. return Y ^ (X | (~Z));
  18. }
  19. /*4组计算函数结束*/
  20. /*32位数循环左移实现函数*/
  21. void ROL(unsigned int &s, unsigned short cx)
  22. {
  23. if (cx > 32)cx %= 32;
  24. s = (s << cx) | (s >> (32 - cx));
  25. return;
  26. }
  27. /*B\L互转,接收UINT类型*/
  28. void ltob(unsigned int &i)
  29. {
  30. unsigned int tmp = i;//保存副本
  31. byte *psour = (byte*)&tmp, *pdes = (byte*)&i;
  32. pdes += 3;//调整指针,准备左右调转
  33. for (short i = 3; i >= 0; --i)
  34. {
  35. CopyMemory(pdes - i, psour + i, 1);
  36. }
  37. return;
  38. }
  39. /*
  40. MD5循环计算函数,label=第几轮循环(1<=label<=4),lGroup数组=4个种子副本,M=数据(16组32位数指针)
  41. 种子数组排列方式: --A--D--C--B--,即 lGroup[0]=A; lGroup[1]=D; lGroup[2]=C; lGroup[3]=B;
  42. */
  43. void AccLoop(unsigned short label, unsigned int *lGroup, void *M)
  44. {
  45. unsigned int *i1, *i2, *i3, *i4, TAcc, tmpi = 0; //定义:4个指针; T表累加器; 局部变量
  46. typedef unsigned int(*clac)(unsigned int X, unsigned int Y, unsigned int Z); //定义函数类型
  47. const unsigned int rolarray[4][4] = {
  48. { 7, 12, 17, 22 },
  49. { 5, 9, 14, 20 },
  50. { 4, 11, 16, 23 },
  51. { 6, 10, 15, 21 }
  52. };//循环左移-位数表
  53. const unsigned short mN[4][16] = {
  54. { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
  55. { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 },
  56. { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 },
  57. { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }
  58. };//数据坐标表
  59. const unsigned int *pM = static_cast<unsigned int*>(M);//转换类型为32位的Uint
  60. TAcc = ((label - 1) * 16) + 1; //根据第几轮循环初始化T表累加器
  61. clac clacArr[4] = { F, G, H, I }; //定义并初始化计算函数指针数组
  62. /*一轮循环开始(16组->16次)*/
  63. for (short i = 0; i < 16; ++i)
  64. {
  65. /*进行指针自变换*/
  66. i1 = lGroup + ((0 + i) % 4);
  67. i2 = lGroup + ((3 + i) % 4);
  68. i3 = lGroup + ((2 + i) % 4);
  69. i4 = lGroup + ((1 + i) % 4);
  70. /*第一步计算开始: A+F(B,C,D)+M[i]+T[i+1] 注:第一步中直接计算T表*/
  71. tmpi = (*i1 + clacArr[label - 1](*i2, *i3, *i4) + pM[(mN[label - 1][i])] + (unsigned int)(0x100000000UL * abs(sin((double)(TAcc + i)))));
  72. ROL(tmpi, rolarray[label - 1][i % 4]);//第二步:循环左移
  73. *i1 = *i2 + tmpi;//第三步:相加并赋值到种子
  74. }
  75. return;
  76. }
  77. /*接口函数,并执行数据填充*/
  78. unsigned int* MD5(const char* mStr)
  79. {
  80. unsigned int mLen = strlen(mStr); //计算字符串长度
  81. if (mLen < 0) return 0;
  82. unsigned int FillSize = 448 - ((mLen * 8) % 512); //计算需填充的bit数
  83. unsigned int FSbyte = FillSize / 8; //以字节表示的填充数
  84. unsigned int BuffLen = mLen + 8 + FSbyte; //缓冲区长度或者说填充后的长度
  85. unsigned char *md5Buff = new unsigned char[BuffLen]; //分配缓冲区
  86. CopyMemory(md5Buff, mStr, mLen); //复制字符串到缓冲区
  87. /*数据填充开始*/
  88. md5Buff[mLen] = 0x80; //第一个bit填充1
  89. ZeroMemory(&md5Buff[mLen + 1], FSbyte - 1); //其它bit填充0,另一可用函数为FillMemory
  90. unsigned long long lenBit = mLen * 8ULL; //计算字符串长度,准备填充
  91. CopyMemory(&md5Buff[mLen + FSbyte], &lenBit, 8); //填充长度
  92. /*数据填充结束*/
  93. /*运算开始*/
  94. unsigned int LoopNumber = BuffLen / 64; //以16个字为一分组,计算分组数量
  95. unsigned int A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;//初始4个种子,小端类型
  96. unsigned int *lGroup = new unsigned int[4];
  97. lGroup[0]= A;
  98. lGroup[1]= D;
  99. lGroup[2]= C;
  100. lGroup[3]= B;
  101. //{ A, D, C, B}; //种子副本数组,并作为返回值返回
  102. for (unsigned int Bcount = 0; Bcount < LoopNumber; ++Bcount) //分组大循环开始
  103. {
  104. /*进入4次计算的小循环*/
  105. for (unsigned short Lcount = 0; Lcount < 4;)
  106. {
  107. AccLoop(++Lcount, lGroup, &md5Buff[Bcount * 64]);
  108. }
  109. /*数据相加作为下一轮的种子或者最终输出*/
  110. A = (lGroup[0] += A);
  111. B = (lGroup[3] += B);
  112. C = (lGroup[2] += C);
  113. D = (lGroup[1] += D);
  114. }
  115. /*转换内存中的布局后才能正常显示*/
  116. ltob(lGroup[0]);
  117. ltob(lGroup[1]);
  118. ltob(lGroup[2]);
  119. ltob(lGroup[3]);
  120. delete[] md5Buff; //清除内存并返回
  121. return lGroup;
  122. }


  
  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "MD5.h"
  5. int main(int argc, char **argv)
  6. {
  7. char tmpstr[256], buf[4][10];
  8. std::cout << "请输入要加密的字符串:";
  9. std::cin >> tmpstr;
  10. unsigned int* tmpGroup = MD5(tmpstr);
  11. sprintf_s(buf[0], "%8X", tmpGroup[0]);
  12. sprintf_s(buf[1], "%8X", tmpGroup[3]);
  13. sprintf_s(buf[2], "%8X", tmpGroup[2]);
  14. sprintf_s(buf[3], "%8X", tmpGroup[1]);
  15. std::cout <<"MD5:"<< buf[0] << buf[1] << buf[2] << buf[3] << std::endl;
  16. delete[] tmpGroup;
  17. while(1)
  18. {
  19. }
  20. return 0; //在此下断点才能看到输出的值
  21. }



文章来源: yujiang.blog.csdn.net,作者:鱼酱2333,版权归原作者所有,如需转载,请联系作者。

原文链接:yujiang.blog.csdn.net/article/details/54616028

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。