鱼C论坛

 找回密码
 立即注册
查看: 1962|回复: 7

[已解决]SLE30课的作业MD5加密算法求解

[复制链接]
发表于 2023-2-20 23:10:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目: 编写一个函数,接收用户输入的字符串,并对该字符串进行 MD5 加密后返回密文

1.png

到引擎上搜索过MD5加密的算法原理大致就是:
1. 数据填充
2. 添加消息的长度
3. 数据处理
4. MD5运算

目前大致理解了MD5如何运用,但是思路连接不起来,是我想的太复杂了么

[sup]需要一点提示,最好是理论提示谢谢[/sup]
最佳答案
2023-2-21 18:07:41
转自百度百科
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. #define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
  5. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))   
  6. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  7. #define H(x, y, z) ((x) ^ (y) ^ (z))
  8. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  9. #define A 0x67452301
  10. #define B 0xefcdab89
  11. #define C 0x98badcfe
  12. #define D 0x10325476
  13. //strBaye的长度
  14. unsigned int strlength;
  15. //A,B,C,D的临时变量
  16. unsigned int atemp;
  17. unsigned int btemp;
  18. unsigned int ctemp;
  19. unsigned int dtemp;
  20. //常量ti unsigned int(abs(sin(i+1))*(2pow32))
  21. const unsigned int k[]={
  22.         0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
  23.         0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
  24.         0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
  25.         0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
  26.         0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
  27.         0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
  28.         0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
  29.         0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
  30.         0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
  31.         0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
  32.         0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
  33.         0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
  34.         0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
  35. //向左位移数
  36. const unsigned int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
  37.         12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
  38.         4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
  39.         15,21,6,10,15,21,6,10,15,21,6,10,15,21};
  40. const char str16[]="0123456789abcdef";
  41. void mainLoop(unsigned int M[])
  42. {
  43.     unsigned int f,g;
  44.     unsigned int a=atemp;
  45.     unsigned int b=btemp;
  46.     unsigned int c=ctemp;
  47.     unsigned int d=dtemp;
  48.     for (unsigned int i = 0; i < 64; i++)
  49.     {
  50.         if(i<16){
  51.             f=F(b,c,d);
  52.             g=i;
  53.         }else if (i<32)
  54.         {
  55.             f=G(b,c,d);
  56.             g=(5*i+1)%16;
  57.         }else if(i<48){
  58.             f=H(b,c,d);
  59.             g=(3*i+5)%16;
  60.         }else{
  61.             f=I(b,c,d);
  62.             g=(7*i)%16;
  63.         }
  64.         unsigned int tmp=d;
  65.         d=c;
  66.         c=b;
  67.         b=b+shift((a+f+k[i]+M[g]),s[i]);
  68.         a=tmp;
  69.     }
  70.     atemp=a+atemp;
  71.     btemp=b+btemp;
  72.     ctemp=c+ctemp;
  73.     dtemp=d+dtemp;
  74. }
  75. /*
  76. *填充函数
  77. *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
  78. *填充方式为先加一个1,其它位补零
  79. *最后加上64位的原来长度
  80. */
  81. unsigned int* add(string str)
  82. {
  83.     unsigned int num=((str.length()+8)/64)+1;//以512位,64个字节为一组
  84.     unsigned int *strByte=new unsigned int[num*16];    //64/4=16,所以有16个整数
  85.     strlength=num*16;
  86.     for (unsigned int i = 0; i < num*16; i++)
  87.         strByte[i]=0;
  88.     for (unsigned int i=0; i <str.length(); i++)
  89.     {
  90.         strByte[i>>2]|=(str[i])<<((i%4)*8);//一个整数存储四个字节,i>>2表示i/4 一个unsigned int对应4个字节,保存4个字符信息
  91.     }
  92.     strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);//尾部添加1 一个unsigned int保存4个字符信息,所以用128左移
  93.     /*
  94.     *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
  95.     */
  96.     strByte[num*16-2]=str.length()*8;
  97.     return strByte;
  98. }
  99. string changeHex(int a)
  100. {
  101.     int b;
  102.     string str1;
  103.     string str="";
  104.     for(int i=0;i<4;i++)
  105.     {
  106.         str1="";
  107.         b=((a>>i*8)%(1<<8))&0xff;   //逆序处理每个字节
  108.         for (int j = 0; j < 2; j++)
  109.         {
  110.             str1.insert(0,1,str16[b%16]);
  111.             b=b/16;
  112.         }
  113.         str+=str1;
  114.     }
  115.     return str;
  116. }
  117. string getMD5(string source)
  118. {
  119.     atemp=A;    //初始化
  120.     btemp=B;
  121.     ctemp=C;
  122.     dtemp=D;
  123.     unsigned int *strByte=add(source);
  124.     for(unsigned int i=0;i<strlength/16;i++)
  125.     {
  126.         unsigned int num[16];
  127.         for(unsigned int j=0;j<16;j++)
  128.             num[j]=strByte[i*16+j];
  129.         mainLoop(num);
  130.     }
  131.     return changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));
  132. }
  133. unsigned int main()
  134. {
  135.     string ss;
  136. //    cin>>ss;
  137.     string s=getMD5("abc");
  138.     cout<<s;
  139.     return 0;
  140. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 23:24:20 From FishC Mobile | 显示全部楼层
试着把现在的思路表达出来?
https://www.rfc-editor.org/rfc/rfc1321.html
https://www.rfc-editor.org/errata/rfc1321
不知道发生什么了所以不知道有没有用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-21 13:34:58 | 显示全部楼层
有代码还是贴代码吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-21 14:25:51 From FishC Mobile | 显示全部楼层
做最好的自己520 发表于 2023-2-21 13:34
有代码还是贴代码吧

您要贴的代码呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-21 14:36:23 | 显示全部楼层
dolly_yos2 发表于 2023-2-21 14:25
您要贴的代码呢?

不好意思哈     代码我写了一点点没弄出来,现在我要提问的是,如何用C语言封装一个MD5函数?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-21 14:54:24 From FishC Mobile | 显示全部楼层
做最好的自己520 发表于 2023-2-21 14:36
不好意思哈     代码我写了一点点没弄出来,现在我要提问的是,如何用C语言封装一个MD5函数?

如果您打开了我之前发的链接,就会发现那是 MD5 算法的详细描述
如果您耐心翻到了最后,就会发现附录里有 MD5 的参考实现
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-21 15:05:32 | 显示全部楼层
dolly_yos2 发表于 2023-2-21 14:54
如果您打开了我之前发的链接,就会发现那是 MD5 算法的详细描述
如果您耐心翻到了最后,就会发现附录里 ...

哈哈  谢谢   你发出来的时候看了一下全部是英文直接把我劝退了    我现在去认真再看看
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-21 18:07:41 | 显示全部楼层    本楼为最佳答案   
转自百度百科
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. #define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
  5. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))   
  6. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  7. #define H(x, y, z) ((x) ^ (y) ^ (z))
  8. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  9. #define A 0x67452301
  10. #define B 0xefcdab89
  11. #define C 0x98badcfe
  12. #define D 0x10325476
  13. //strBaye的长度
  14. unsigned int strlength;
  15. //A,B,C,D的临时变量
  16. unsigned int atemp;
  17. unsigned int btemp;
  18. unsigned int ctemp;
  19. unsigned int dtemp;
  20. //常量ti unsigned int(abs(sin(i+1))*(2pow32))
  21. const unsigned int k[]={
  22.         0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
  23.         0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
  24.         0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
  25.         0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
  26.         0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
  27.         0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
  28.         0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
  29.         0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
  30.         0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
  31.         0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
  32.         0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
  33.         0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
  34.         0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
  35. //向左位移数
  36. const unsigned int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
  37.         12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
  38.         4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
  39.         15,21,6,10,15,21,6,10,15,21,6,10,15,21};
  40. const char str16[]="0123456789abcdef";
  41. void mainLoop(unsigned int M[])
  42. {
  43.     unsigned int f,g;
  44.     unsigned int a=atemp;
  45.     unsigned int b=btemp;
  46.     unsigned int c=ctemp;
  47.     unsigned int d=dtemp;
  48.     for (unsigned int i = 0; i < 64; i++)
  49.     {
  50.         if(i<16){
  51.             f=F(b,c,d);
  52.             g=i;
  53.         }else if (i<32)
  54.         {
  55.             f=G(b,c,d);
  56.             g=(5*i+1)%16;
  57.         }else if(i<48){
  58.             f=H(b,c,d);
  59.             g=(3*i+5)%16;
  60.         }else{
  61.             f=I(b,c,d);
  62.             g=(7*i)%16;
  63.         }
  64.         unsigned int tmp=d;
  65.         d=c;
  66.         c=b;
  67.         b=b+shift((a+f+k[i]+M[g]),s[i]);
  68.         a=tmp;
  69.     }
  70.     atemp=a+atemp;
  71.     btemp=b+btemp;
  72.     ctemp=c+ctemp;
  73.     dtemp=d+dtemp;
  74. }
  75. /*
  76. *填充函数
  77. *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
  78. *填充方式为先加一个1,其它位补零
  79. *最后加上64位的原来长度
  80. */
  81. unsigned int* add(string str)
  82. {
  83.     unsigned int num=((str.length()+8)/64)+1;//以512位,64个字节为一组
  84.     unsigned int *strByte=new unsigned int[num*16];    //64/4=16,所以有16个整数
  85.     strlength=num*16;
  86.     for (unsigned int i = 0; i < num*16; i++)
  87.         strByte[i]=0;
  88.     for (unsigned int i=0; i <str.length(); i++)
  89.     {
  90.         strByte[i>>2]|=(str[i])<<((i%4)*8);//一个整数存储四个字节,i>>2表示i/4 一个unsigned int对应4个字节,保存4个字符信息
  91.     }
  92.     strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);//尾部添加1 一个unsigned int保存4个字符信息,所以用128左移
  93.     /*
  94.     *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
  95.     */
  96.     strByte[num*16-2]=str.length()*8;
  97.     return strByte;
  98. }
  99. string changeHex(int a)
  100. {
  101.     int b;
  102.     string str1;
  103.     string str="";
  104.     for(int i=0;i<4;i++)
  105.     {
  106.         str1="";
  107.         b=((a>>i*8)%(1<<8))&0xff;   //逆序处理每个字节
  108.         for (int j = 0; j < 2; j++)
  109.         {
  110.             str1.insert(0,1,str16[b%16]);
  111.             b=b/16;
  112.         }
  113.         str+=str1;
  114.     }
  115.     return str;
  116. }
  117. string getMD5(string source)
  118. {
  119.     atemp=A;    //初始化
  120.     btemp=B;
  121.     ctemp=C;
  122.     dtemp=D;
  123.     unsigned int *strByte=add(source);
  124.     for(unsigned int i=0;i<strlength/16;i++)
  125.     {
  126.         unsigned int num[16];
  127.         for(unsigned int j=0;j<16;j++)
  128.             num[j]=strByte[i*16+j];
  129.         mainLoop(num);
  130.     }
  131.     return changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));
  132. }
  133. unsigned int main()
  134. {
  135.     string ss;
  136. //    cin>>ss;
  137.     string s=getMD5("abc");
  138.     cout<<s;
  139.     return 0;
  140. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-12 20:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表