找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 4466|回复: 0

【C】C语言实现MD5算法

[复制链接]
发表于 2015-2-28 02:43:01 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

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

×
现在MD5已被证实其并不安全了!不过它也还是有些作用的。
  1. //=============================================================================
  2. //作者:0xAA55
  3. //网站:http://www.0xaa55.com
  4. //版权所有(C)技术宅的结界 2013-2015
  5. //请保留原作者信息,否则视为侵权
  6. //-----------------------------------------------------------------------------
  7. //rfc1321

  8. #include"md5.h"
  9. #include<memory.h>

  10. //MD5寄存器
  11. typedef struct
  12. {
  13.         uint32_t A;
  14.         uint32_t B;
  15.         uint32_t C;
  16.         uint32_t D;
  17.         uint32_t AA;
  18.         uint32_t BB;
  19.         uint32_t CC;
  20.         uint32_t DD;
  21. }MD5Registers,*MD5RegistersP;

  22. static uint32_t F(uint32_t x,uint32_t y,uint32_t z){return (x&y)|(~x&z);}
  23. static uint32_t G(uint32_t x,uint32_t y,uint32_t z){return (x&z)|(y&~z);}
  24. static uint32_t H(uint32_t x,uint32_t y,uint32_t z){return x^y^z;}
  25. static uint32_t I(uint32_t x,uint32_t y,uint32_t z){return y^(x|~z);}

  26. static uint32_t Rol(uint32_t v,uint8_t Count){return (v<<Count)|(v>>(32-Count));}

  27. static uint32_t FF(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
  28.                                    uint32_t X,uint32_t s,uint32_t T)
  29. {return b+Rol((a+F(b,c,d)+X+T),s);}
  30. static uint32_t GG(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
  31.                                    uint32_t X,uint32_t s,uint32_t T)
  32. {return b+Rol((a+G(b,c,d)+X+T),s);}
  33. static uint32_t HH(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
  34.                                    uint32_t X,uint32_t s,uint32_t T)
  35. {return b+Rol((a+H(b,c,d)+X+T),s);}
  36. static uint32_t II(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
  37.                                    uint32_t X,uint32_t s,uint32_t T)
  38. {return b+Rol((a+I(b,c,d)+X+T),s);}

  39. //=============================================================================
  40. //函数:InitRegs
  41. //描述:初始化MD5寄存器
  42. //-----------------------------------------------------------------------------
  43. static void InitRegs(MD5RegistersP pReg)
  44. {
  45.         //初始4个32位寄存器
  46.         pReg->A=0x67452301;
  47.         pReg->B=0xEFCDAB89;
  48.         pReg->C=0x98BADCFE;
  49.         pReg->D=0x10325476;
  50. }

  51. //=============================================================================
  52. //函数:DigestChunk
  53. //描述:将一个64字节的“块”作为数据压入计算
  54. //-----------------------------------------------------------------------------
  55. static void DigestChunk(MD5RegistersP pReg,void*pData)
  56. {
  57. #        define p ((uint32_t*)pData)
  58.         pReg->AA=pReg->A;
  59.         pReg->BB=pReg->B;
  60.         pReg->CC=pReg->C;
  61.         pReg->DD=pReg->D;

  62.         pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p[0x0],0x07,0xD76AA478);
  63.         pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p[0x1],0x0C,0xE8C7B756);
  64.         pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p[0x2],0x11,0x242070DB);
  65.         pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p[0x3],0x16,0xC1BDCEEE);
  66.         pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p[0x4],0x07,0xF57C0FAF);
  67.         pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p[0x5],0x0C,0x4787C62A);
  68.         pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p[0x6],0x11,0xA8304613);
  69.         pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p[0x7],0x16,0xFD469501);
  70.         pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p[0x8],0x07,0x698098D8);
  71.         pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p[0x9],0x0C,0x8B44F7AF);
  72.         pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p[0xA],0x11,0xFFFF5BB1);
  73.         pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p[0xB],0x16,0x895CD7BE);
  74.         pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p[0xC],0x07,0x6B901122);
  75.         pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p[0xD],0x0C,0xFD987193);
  76.         pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p[0xE],0x11,0xA679438E);
  77.         pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p[0xF],0x16,0x49B40821);

  78.         pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p[0x1],0x05,0xF61E2562);
  79.         pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p[0x6],0x09,0xC040B340);
  80.         pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p[0xB],0x0E,0x265E5A51);
  81.         pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p[0x0],0x14,0xE9B6C7AA);
  82.         pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p[0x5],0x05,0xD62F105D);
  83.         pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p[0xA],0x09,0x02441453);
  84.         pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p[0xF],0x0E,0xD8A1E681);
  85.         pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p[0x4],0x14,0xE7D3FBC8);
  86.         pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p[0x9],0x05,0x21E1CDE6);
  87.         pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p[0xE],0x09,0xC33707D6);
  88.         pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p[0x3],0x0E,0xF4D50D87);
  89.         pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p[0x8],0x14,0x455A14ED);
  90.         pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p[0xD],0x05,0xA9E3E905);
  91.         pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p[0x2],0x09,0xFCEFA3F8);
  92.         pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p[0x7],0x0E,0x676F02D9);
  93.         pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p[0xC],0x14,0x8D2A4C8A);

  94.         pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p[0x5],0x04,0xFFFA3942);
  95.         pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p[0x8],0x0B,0x8771F681);
  96.         pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p[0xB],0x10,0x6D9D6122);
  97.         pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p[0xE],0x17,0xFDE5380C);
  98.         pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p[0x1],0x04,0xA4BEEA44);
  99.         pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p[0x4],0x0B,0x4BDECFA9);
  100.         pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p[0x7],0x10,0xF6BB4B60);
  101.         pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p[0xA],0x17,0xBEBFBC70);
  102.         pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p[0xD],0x04,0x289B7EC6);
  103.         pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p[0x0],0x0B,0xEAA127FA);
  104.         pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p[0x3],0x10,0xD4EF3085);
  105.         pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p[0x6],0x17,0x04881D05);
  106.         pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p[0x9],0x04,0xD9D4D039);
  107.         pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p[0xC],0x0B,0xE6DB99E5);
  108.         pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p[0xF],0x10,0x1FA27CF8);
  109.         pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p[0x2],0x17,0xC4AC5665);

  110.         pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p[0x0],0x06,0xF4292244);
  111.         pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p[0x7],0x0A,0x432AFF97);
  112.         pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p[0xE],0x0F,0xAB9423A7);
  113.         pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p[0x5],0x15,0xFC93A039);
  114.         pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p[0xC],0x06,0x655B59C3);
  115.         pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p[0x3],0x0A,0x8F0CCC92);
  116.         pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p[0xA],0x0F,0xFFEFF47D);
  117.         pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p[0x1],0x15,0x85845DD1);
  118.         pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p[0x8],0x06,0x6FA87E4F);
  119.         pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p[0xF],0x0A,0xFE2CE6E0);
  120.         pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p[0x6],0x0F,0xA3014314);
  121.         pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p[0xD],0x15,0x4E0811A1);
  122.         pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p[0x4],0x06,0xF7537E82);
  123.         pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p[0xB],0x0A,0xBD3AF235);
  124.         pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p[0x2],0x0F,0x2AD7D2BB);
  125.         pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p[0x9],0x15,0xEB86D391);

  126.         pReg->A+=pReg->AA;
  127.         pReg->B+=pReg->BB;
  128.         pReg->C+=pReg->CC;
  129.         pReg->D+=pReg->DD;
  130. }

  131. //=============================================================================
  132. //函数:MD5Sum
  133. //描述:计算MD5校验和,其中pMD5Out接收结果(函数将写入16个字节到pMD5Out)
  134. //-----------------------------------------------------------------------------
  135. void MD5Sum
  136. (
  137.         void                *pData,        //数据指针
  138.         size_t                cbData,        //数据大小(Bytes)
  139.         uint32_t        *pMD5Out//输出MD5
  140. )
  141. {
  142.         MD5Registers Regs={0};
  143.         uint8_t PadBuf[64]={0};//用于计算最后的填充内容的缓冲区
  144.         size_t i;
  145.         size_t cbLast=cbData;

  146.         //=========================================================================
  147.         //MD5算法:
  148.         //第一:数据补充
  149.         //1、将数据看成是bit流,在最后一个bit的后面添加一个1。
  150.         //2、再在数据的后面不断补充0,直到数据的总位数与512求余==448
  151.         //3、将数据的总位数以uint64_t格式补充到最后
  152.         //第二:运算
  153.         //1、初始化MD5寄存器
  154.         //2、将数据划分为n个512 bit的块,对每个块进行DigestChunk运算
  155.         //3、最后将MD5寄存器的值返回

  156.         //初始化MD5寄存器
  157.         InitRegs(&Regs);

  158.         //将数据拆成64字节一个块,先分析逐个块,直到最后一个块(然后再来处理“补齐”)
  159.         for(i=0;i+64<=cbData;i+=64)
  160.         {
  161.                 DigestChunk(&Regs,pData);
  162.                 (uint8_t*)pData+=64;
  163.                 cbLast-=64;
  164.         }

  165.         //如果最后一个块有内容则复制到最后的填充内容的缓冲区
  166.         if(cbData)
  167.                 memcpy(PadBuf,pData,cbLast);

  168.         //补充1
  169.         PadBuf[cbLast++]=0x80;

  170.         //然后在这个填充数据块的结尾补充[数据的总位数]。

  171.         //如果有空余的空间可用于补充,则补充
  172.         if(cbLast<56)
  173.         {
  174.                 *(uint64_t*)&(PadBuf[56])=(uint64_t)cbData*8;
  175.                 DigestChunk(&Regs,PadBuf);
  176.         }
  177.         else//否则再补充56个,然后再补充
  178.         {
  179.                 DigestChunk(&Regs,PadBuf);
  180.                 memset(PadBuf,0,sizeof(PadBuf));
  181.                 *(uint64_t*)&(PadBuf[56])=(uint64_t)cbData*8;
  182.                 DigestChunk(&Regs,PadBuf);
  183.         }

  184.         //最后返回MD5寄存器的值
  185.         pMD5Out[0]=Regs.A;
  186.         pMD5Out[1]=Regs.B;
  187.         pMD5Out[2]=Regs.C;
  188.         pMD5Out[3]=Regs.D;
  189. }
复制代码
以下程序用于计算一个字符串的MD5值。
命令:md5 <string>
BIN: md5.exe (64.5 KB, 下载次数: 8)
SRC: md5.7z (134.16 KB, 下载次数: 16)

本帖被以下淘专辑推荐:

回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 02:31 , Processed in 0.036762 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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