Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7773297
  • 博文数量: 701
  • 博客积分: 2150
  • 博客等级: 上尉
  • 技术积分: 13233
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-29 16:28
个人简介

天行健,君子以自强不息!

文章分类

全部博文(701)

文章存档

2019年(2)

2018年(12)

2017年(76)

2016年(120)

2015年(178)

2014年(129)

2013年(123)

2012年(61)

分类: 网络与安全

2017-01-03 16:12:43

原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。

由于各种原因,可能存在诸多不足,欢迎斧正!

一、MD5概念

MD5,全名Message Digest Algorithm 5 ,中文名为消息摘要第五版,
为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
上面这段话话引用自百度百科,我的理解MD5是一种信息摘要算法,主要是通过特定的hash散列方法将文本信息转换成简短的信息摘要,
压缩+加密+hash算法的结合体,是绝对不可逆的。


二、MD5计算步骤   

MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,
经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

第一步、填充

     如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。
     填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);

第二步、记录信息长度

     用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N*512+448+64=(N+1)*512位。

第三步、装入标准的幻数(四个整数)

     标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是(A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L)。有点晕哈,其实想一想就明白了。

第四步、四轮循环运算

     循环的次数是分组的个数(N+1)

   1)将每一512字节细分成16个小组,每个小组64位(8个字节)    
   2)先认识四个线性函数(&是与,|是或,~是非,^是异或) 

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. F(X,Y,Z)=(X&Y)|((~X)&Z)  
  2. G(X,Y,Z)=(X&Z)|(Y&(~Z))  
  3. H(X,Y,Z)=X^Y^Z  
  4. I(X,Y,Z)=Y^(X|(~Z))  

    3)设Mj表示消息的第j个子分组(从0到15),<<
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<
  2. GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<
  3. HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<
  4. II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<

   4)四轮运算

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. 第一轮  
  2. a=FF(a,b,c,d,M0,7,0xd76aa478)  
  3.  b=FF(d,a,b,c,M1,12,0xe8c7b756)  
  4.  c=FF(c,d,a,b,M2,17,0x242070db)  
  5.  d=FF(b,c,d,a,M3,22,0xc1bdceee)  
  6.  a=FF(a,b,c,d,M4,7,0xf57c0faf)  
  7.  b=FF(d,a,b,c,M5,12,0x4787c62a)  
  8.  c=FF(c,d,a,b,M6,17,0xa8304613)  
  9.  d=FF(b,c,d,a,M7,22,0xfd469501)  
  10.  a=FF(a,b,c,d,M8,7,0x698098d8)  
  11.  b=FF(d,a,b,c,M9,12,0x8b44f7af)  
  12.  c=FF(c,d,a,b,M10,17,0xffff5bb1)  
  13.  d=FF(b,c,d,a,M11,22,0x895cd7be)  
  14.  a=FF(a,b,c,d,M12,7,0x6b901122)  
  15.  b=FF(d,a,b,c,M13,12,0xfd987193)  
  16.  c=FF(c,d,a,b,M14,17,0xa679438e)  
  17.  d=FF(b,c,d,a,M15,22,0x49b40821)  
  18.   
  19. 第二轮  
  20. a=GG(a,b,c,d,M1,5,0xf61e2562)  
  21.  b=GG(d,a,b,c,M6,9,0xc040b340)  
  22.  c=GG(c,d,a,b,M11,14,0x265e5a51)  
  23.  d=GG(b,c,d,a,M0,20,0xe9b6c7aa)  
  24.  a=GG(a,b,c,d,M5,5,0xd62f105d)  
  25.  b=GG(d,a,b,c,M10,9,0x02441453)  
  26.  c=GG(c,d,a,b,M15,14,0xd8a1e681)  
  27.  d=GG(b,c,d,a,M4,20,0xe7d3fbc8)  
  28.  a=GG(a,b,c,d,M9,5,0x21e1cde6)  
  29.  b=GG(d,a,b,c,M14,9,0xc33707d6)  
  30.  c=GG(c,d,a,b,M3,14,0xf4d50d87)  
  31.  d=GG(b,c,d,a,M8,20,0x455a14ed)  
  32.  a=GG(a,b,c,d,M13,5,0xa9e3e905)  
  33.  b=GG(d,a,b,c,M2,9,0xfcefa3f8)  
  34.  c=GG(c,d,a,b,M7,14,0x676f02d9)  
  35.  d=GG(b,c,d,a,M12,20,0x8d2a4c8a)  
  36.   
  37. 第三轮  
  38. a=HH(a,b,c,d,M5,4,0xfffa3942)  
  39.  b=HH(d,a,b,c,M8,11,0x8771f681)  
  40.  c=HH(c,d,a,b,M11,16,0x6d9d6122)  
  41.  d=HH(b,c,d,a,M14,23,0xfde5380c)  
  42.  a=HH(a,b,c,d,M1,4,0xa4beea44)  
  43.  b=HH(d,a,b,c,M4,11,0x4bdecfa9)  
  44.  c=HH(c,d,a,b,M7,16,0xf6bb4b60)  
  45.  d=HH(b,c,d,a,M10,23,0xbebfbc70)  
  46.  a=HH(a,b,c,d,M13,4,0x289b7ec6)  
  47.  b=HH(d,a,b,c,M0,11,0xeaa127fa)  
  48.  c=HH(c,d,a,b,M3,16,0xd4ef3085)  
  49.  d=HH(b,c,d,a,M6,23,0x04881d05)  
  50.  a=HH(a,b,c,d,M9,4,0xd9d4d039)  
  51.  b=HH(d,a,b,c,M12,11,0xe6db99e5)  
  52.  c=HH(c,d,a,b,M15,16,0x1fa27cf8)  
  53.  d=HH(b,c,d,a,M2,23,0xc4ac5665)  
  54.   
  55. 第四轮  
  56. a=II(a,b,c,d,M0,6,0xf4292244)  
  57.  b=II(d,a,b,c,M7,10,0x432aff97)  
  58.  c=II(c,d,a,b,M14,15,0xab9423a7)  
  59.  d=II(b,c,d,a,M5,21,0xfc93a039)  
  60.  a=II(a,b,c,d,M12,6,0x655b59c3)  
  61.  b=II(d,a,b,c,M3,10,0x8f0ccc92)  
  62.  c=II(c,d,a,b,M10,15,0xffeff47d)  
  63.  d=II(b,c,d,a,M1,21,0x85845dd1)  
  64.  a=II(a,b,c,d,M8,6,0x6fa87e4f)  
  65.  b=II(d,a,b,c,M15,10,0xfe2ce6e0)  
  66.  c=II(c,d,a,b,M6,15,0xa3014314)  
  67.  d=II(b,c,d,a,M13,21,0x4e0811a1)  
  68.  a=II(a,b,c,d,M4,6,0xf7537e82)  
  69.  b=II(d,a,b,c,M11,10,0xbd3af235)  
  70.  c=II(c,d,a,b,M2,15,0x2ad7d2bb)  
  71.  d=II(b,c,d,a,M9,21,0xeb86d391)   


    5)每轮循环后,将A,B,C,D分别加上a,b,c,d,然后进入下一循环。


三、MD5应用

1、一致性验证
     MD5的典型应用是对一段文本信息产生信息摘要,以防止被篡改。
常常在某些软件下载站点的某软件信息中看到其MD5值,它的作用就在于我们可以在下载该软件后,
对下载回来的文件用专门的软件(如Windows MD5 Check等)做一次MD5校验,
以确保我们获得的文件与该站点提供的文件为同一文件。
2、数字证书
     如果有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。
3、安全访问认证
     在Unix系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。
当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,然后再去和保存在文件系统中的MD5值进行比较,
进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。


四、源代码    


[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //MessageDigestAlgorithm5.h  
  2. #pragma once  
  3. #include  
  4. #include  
  5. #include  
  6. using namespace std;  
  7.   
  8. typedef unsigned char Byte;  
  9.   
  10. class CMessageDigestAlgorithm5  
  11. {  
  12. public:  
  13.     CMessageDigestAlgorithm5(void);  
  14.     ~CMessageDigestAlgorithm5(void);  
  15.   
  16.     //MD5算法主函数,对str加密  
  17.     string Encode(string &str);  
  18.     string Encode(ifstream& infile);  
  19.   
  20. private:  
  21.     unsigned int F(unsigned int x, unsigned int y,unsigned int z);  
  22.     unsigned int G(unsigned int x, unsigned int y,unsigned int z);  
  23.     unsigned int H(unsigned int x, unsigned int y,unsigned int z);  
  24.     unsigned int I(unsigned int x, unsigned int y,unsigned int z);  
  25.     void Initialize();  
  26.     unsigned int LeftRotate(unsigned int opNumber,unsigned int opBit);  
  27.     void FF(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti);  
  28.     void GG(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti);  
  29.     void HH(unsigned int &a, unsigned int b,unsigned int c,unsigned int d,  unsigned int Mj,unsigned int s,unsigned int Ti);  
  30.     void II(unsigned int &a, unsigned int b,unsigned int c,unsigned int d,  unsigned int Mj,unsigned int s,unsigned int Ti);  
  31.     void ByteToUnsignedInt(const Byte* input, unsigned int* output, size_t length);  
  32.     string ByteToHexString(const Byte* input, size_t length);  
  33.     void UnsignedIntToByte(const unsigned int * input, Byte* output, size_t length);  
  34.     void ProcessOfMDA5(const Byte block[64]);  
  35.     void EncodeByte(const Byte* input, size_t length);  
  36.     void  Final();  
  37.   
  38.   
  39. private:  
  40.     unsigned int  m_ChainingVariable[4];  
  41.     unsigned int m_Count[2];  
  42.     Byte m_Result[16];  
  43.     Byte m_Buffer[64];  
  44.     enum  
  45.     {  
  46.         S11 = 7,   
  47.         S12 = 12,  
  48.         S13 = 17,  
  49.         S14 = 22,  
  50.         S21 = 5,  
  51.         S22 = 9,  
  52.         S23 = 14,  
  53.         S24 = 20,  
  54.         S31 = 4,  
  55.         S32 = 11,  
  56.         S33 = 16,  
  57.         S34 = 23,  
  58.         S41 = 6,  
  59.         S42 = 10,  
  60.         S43 = 15,  
  61.         S44 = 21,  
  62.     };  
  63.     static const Byte g_Padding[64];  
  64. };  

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //MessageDigestAlgorithm5.cpp  
  2.   
  3. #include "stdafx.h"  
  4. #include "MessageDigestAlgorithm5.h"  
  5.   
  6. const Byte CMessageDigestAlgorithm5::g_Padding[64] = { 0x80 };//第一位补1,其他补0  
  7.   
  8. CMessageDigestAlgorithm5::CMessageDigestAlgorithm5(void)  
  9. {  
  10. }  
  11.   
  12. CMessageDigestAlgorithm5::~CMessageDigestAlgorithm5(void)  
  13. {  
  14. }  
  15.   
  16. unsigned int CMessageDigestAlgorithm5::F(unsigned int x, unsigned int y,unsigned int z)  
  17. {  
  18.     return (x & y) | ((~ x) & z);  
  19. }  
  20.   
  21. unsigned int CMessageDigestAlgorithm5::G(unsigned int x, unsigned int y,unsigned int z)  
  22. {  
  23.     return (x & z) | (y & (~ z));  
  24. }  
  25.   
  26. unsigned int CMessageDigestAlgorithm5::H(unsigned int x, unsigned int y,unsigned int z)  
  27. {  
  28.     return x ^ y ^ z;  
  29. }  
  30.   
  31. unsigned int CMessageDigestAlgorithm5::I(unsigned int x, unsigned int y,unsigned int z)  
  32. {  
  33.     return y ^ (x | (~ z));  
  34. }  
  35.   
  36. /*************************************************** 
  37. *参数:空 
  38. *功能:初始化链接变量 
  39. *返回值:空 
  40. ****************************************************/  
  41. void CMessageDigestAlgorithm5::Initialize()  
  42. {  
  43.     m_Count[0] = m_Count[1] = 0;  
  44.     m_ChainingVariable[0] = 0x67452301;  
  45.     m_ChainingVariable[1] = 0xefcdab89;  
  46.     m_ChainingVariable[2] = 0x98badcfe;  
  47.     m_ChainingVariable[3] = 0x10325476;  
  48. }  
  49.   
  50. /*************************************************** 
  51. *参数:opNumber表示待左移的数 
  52.       opBit表示左移的位数 
  53. *功能:完成循环左移操作 
  54. *返回值:循环左移后值 
  55. ****************************************************/  
  56. unsigned int CMessageDigestAlgorithm5::LeftRotate(unsigned int opNumber,unsigned int opBit)  
  57. {  
  58.     unsigned int left = opNumber;  
  59.     unsigned int right = opNumber;  
  60.     return (left << opBit) | (right >> (32 - opBit));  
  61. }  
  62.   
  63. void CMessageDigestAlgorithm5::FF(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti)  
  64. {  
  65.     unsigned int temp = a + F(b,c,d) + Mj + Ti;  
  66.     a = b + LeftRotate(temp,s);   
  67. }  
  68.   
  69. void CMessageDigestAlgorithm5::GG(unsigned int &a, unsigned int b,unsigned int c,unsigned int d,unsigned int Mj,unsigned int s,unsigned int Ti)  
  70. {  
  71.     unsigned int temp = a + G(b,c,d) + Mj + Ti;  
  72.     a = b + LeftRotate(temp,s);   
  73. }  
  74.   
  75. void CMessageDigestAlgorithm5::HH(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti)  
  76. {  
  77.     unsigned int temp = a + H(b,c,d) + Mj + Ti;  
  78.     a = b + LeftRotate(temp,s);   
  79. }  
  80.   
  81. void CMessageDigestAlgorithm5::II(unsigned int &a, unsigned int b,unsigned int c,unsigned int d, unsigned int Mj,unsigned int s,unsigned int Ti)  
  82. {  
  83.     unsigned int temp = a + I(b,c,d) + Mj + Ti;  
  84.     a = b + LeftRotate(temp,s);   
  85. }  
  86.   
  87. /*************************************************** 
  88. *参数:input表示输入字节数组 
  89.       output表示输出unsigned int数组 
  90.       length表示输入字节长度 
  91. *功能:byte转unsigned int(左低右高) 
  92. *返回值:空 
  93. ****************************************************/  
  94. void CMessageDigestAlgorithm5::ByteToUnsignedInt(const Byte* input, unsigned int* output, size_t length)  
  95. {  
  96.     for(size_t i = 0,j = 0;j < length;++ i, j += 4)  
  97.     {  
  98.         output[i] = ((static_castint>(input[j]))  
  99.             |((static_castint>(input[j + 1])) << 8)  
  100.             |((static_castint>(input[j + 2])) << 16)  
  101.             |((static_castint>(input[j + 3])) << 24));  
  102.     }  
  103. }  
  104.   
  105. /*************************************************** 
  106. *参数:input表示输入unsigned int数组 
  107.       output表示输出字节数组 
  108.       length表示输入字节长度 
  109. *功能:unsigned int转byte 
  110. *返回值:空 
  111. ****************************************************/  
  112. void CMessageDigestAlgorithm5::UnsignedIntToByte(const unsigned int * input, Byte* output, size_t length)  
  113. {  
  114.     for (size_t i = 0, j = 0; j < length; ++i, j += 4)   
  115.     {  
  116.         output[j] = static_cast(input[i] & 0xff);  
  117.         output[j + 1] = static_cast((input[i] >> 8) & 0xff);  
  118.         output[j + 2] = static_cast((input[i] >> 16) & 0xff);  
  119.         output[j + 3] = static_cast((input[i] >> 24) & 0xff);  
  120.     }  
  121. }  
  122.   
  123. /*************************************************** 
  124. *参数:groups[]表示一个512位(64字节)分组 
  125. *功能:四轮主要操作 
  126. *返回值:空 
  127. ****************************************************/  
  128. void CMessageDigestAlgorithm5::ProcessOfMDA5(const Byte  groups[64])  
  129. {  
  130.     unsigned int a = m_ChainingVariable[0], b = m_ChainingVariable[1], c = m_ChainingVariable[2], d = m_ChainingVariable[3];  
  131.     unsigned int M[16];  
  132.   
  133.     ByteToUnsignedInt( groups, M, 64);  
  134.   
  135.     FF(a, b, c, d, M[ 0], S11, 0xd76aa478);   
  136.     FF(d, a, b, c, M[ 1], S12, 0xe8c7b756);   
  137.     FF(c, d, a, b, M[ 2], S13, 0x242070db);   
  138.     FF(b, c, d, a, M[ 3], S14, 0xc1bdceee);   
  139.     FF(a, b, c, d, M[ 4], S11, 0xf57c0faf);   
  140.     FF(d, a, b, c, M[ 5], S12, 0x4787c62a);   
  141.     FF(c, d, a, b, M[ 6], S13, 0xa8304613);   
  142.     FF(b, c, d, a, M[ 7], S14, 0xfd469501);   
  143.     FF(a, b, c, d, M[ 8], S11, 0x698098d8);   
  144.     FF(d, a, b, c, M[ 9], S12, 0x8b44f7af);   
  145.     FF(c, d, a, b, M[10], S13, 0xffff5bb1);   
  146.     FF(b, c, d, a, M[11], S14, 0x895cd7be);   
  147.     FF(a, b, c, d, M[12], S11, 0x6b901122);   
  148.     FF(d, a, b, c, M[13], S12, 0xfd987193);   
  149.     FF(c, d, a, b, M[14], S13, 0xa679438e);   
  150.     FF(b, c, d, a, M[15], S14, 0x49b40821);  
  151.   
  152.     GG(a, b, c, d, M[ 1], S21, 0xf61e2562);   
  153.     GG(d, a, b, c, M[ 6], S22, 0xc040b340);  
  154.     GG(c, d, a, b, M[11], S23, 0x265e5a51);  
  155.     GG(b, c, d, a, M[ 0], S24, 0xe9b6c7aa);   
  156.     GG(a, b, c, d, M[ 5], S21, 0xd62f105d);   
  157.     GG(d, a, b, c, M[10], S22,  0x2441453);   
  158.     GG(c, d, a, b, M[15], S23, 0xd8a1e681);   
  159.     GG(b, c, d, a, M[ 4], S24, 0xe7d3fbc8);   
  160.     GG(a, b, c, d, M[ 9], S21, 0x21e1cde6);  
  161.     GG(d, a, b, c, M[14], S22, 0xc33707d6);   
  162.     GG(c, d, a, b, M[ 3], S23, 0xf4d50d87);   
  163.     GG(b, c, d, a, M[ 8], S24, 0x455a14ed);  
  164.     GG(a, b, c, d, M[13], S21, 0xa9e3e905);   
  165.     GG(d, a, b, c, M[ 2], S22, 0xfcefa3f8);  
  166.     GG(c, d, a, b, M[ 7], S23, 0x676f02d9);   
  167.     GG(b, c, d, a, M[12], S24, 0x8d2a4c8a);   
  168.   
  169.     HH(a, b, c, d, M[ 5], S31, 0xfffa3942);   
  170.     HH(d, a, b, c, M[ 8], S32, 0x8771f681);   
  171.     HH(c, d, a, b, M[11], S33, 0x6d9d6122);   
  172.     HH(b, c, d, a, M[14], S34, 0xfde5380c);   
  173.     HH(a, b, c, d, M[ 1], S31, 0xa4beea44);   
  174.     HH(d, a, b, c, M[ 4], S32, 0x4bdecfa9);   
  175.     HH(c, d, a, b, M[ 7], S33, 0xf6bb4b60);   
  176.     HH(b, c, d, a, M[10], S34, 0xbebfbc70);   
  177.     HH(a, b, c, d, M[13], S31, 0x289b7ec6);   
  178.     HH(d, a, b, c, M[ 0], S32, 0xeaa127fa);   
  179.     HH(c, d, a, b, M[ 3], S33, 0xd4ef3085);   
  180.     HH(b, c, d, a, M[ 6], S34,  0x4881d05);   
  181.     HH(a, b, c, d, M[ 9], S31, 0xd9d4d039);   
  182.     HH(d, a, b, c, M[12], S32, 0xe6db99e5);   
  183.     HH(c, d, a, b, M[15], S33, 0x1fa27cf8);   
  184.     HH(b, c, d, a, M[ 2], S34, 0xc4ac5665);   
  185.   
  186.     II(a, b, c, d, M[ 0], S41, 0xf4292244);   
  187.     II(d, a, b, c, M[ 7], S42, 0x432aff97);   
  188.     II(c, d, a, b, M[14], S43, 0xab9423a7);  
  189.     II(b, c, d, a, M[ 5], S44, 0xfc93a039);   
  190.     II(a, b, c, d, M[12], S41, 0x655b59c3);   
  191.     II(d, a, b, c, M[ 3], S42, 0x8f0ccc92);   
  192.     II(c, d, a, b, M[10], S43, 0xffeff47d);   
  193.     II(b, c, d, a, M[ 1], S44, 0x85845dd1);   
  194.     II(a, b, c, d, M[ 8], S41, 0x6fa87e4f);   
  195.     II(d, a, b, c, M[15], S42, 0xfe2ce6e0);   
  196.     II(c, d, a, b, M[ 6], S43, 0xa3014314);   
  197.     II(b, c, d, a, M[13], S44, 0x4e0811a1);   
  198.     II(a, b, c, d, M[ 4], S41, 0xf7537e82);   
  199.     II(d, a, b, c, M[11], S42, 0xbd3af235);   
  200.     II(c, d, a, b, M[ 2], S43, 0x2ad7d2bb);   
  201.     II(b, c, d, a, M[ 9], S44, 0xeb86d391);   
  202.   
  203.     m_ChainingVariable[0] += a;  
  204.     m_ChainingVariable[1] += b;  
  205.     m_ChainingVariable[2] += c;  
  206.     m_ChainingVariable[3] += d;  
  207. }  
  208.   
  209. /*************************************************** 
  210. *参数:input表示输入字节数组 
  211.       length表示输入字节长度=16(8*16=128位输出) 
  212. *功能:byte转16进制 
  213. *返回值:16进制字符串 
  214. ****************************************************/  
  215. string CMessageDigestAlgorithm5::ByteToHexString(const Byte* input, size_t length)  
  216. {  
  217.     const char MapByteToHex[16] =   
  218.     {  
  219.     '0''1''2''3',  
  220.     '4''5''6''7',  
  221.     '8''9''A''B',  
  222.     'C''D''E''F'  
  223.      };  
  224.     string str;  
  225.     for (size_t i = 0; i < length; ++ i)  
  226.     {  
  227.         unsigned int temp = static_castint>(input[i]);  
  228.         unsigned int a = temp / 16;  
  229.         unsigned int b = temp % 16;  
  230.         str.append(1, MapByteToHex[a]);  
  231.         str.append(1, MapByteToHex[b]);  
  232.     }  
  233.     return str;  
  234. }  
  235.   
  236.   
  237. /*************************************************** 
  238. *参数:str表示待加密文本 
  239. *功能:MD5算法主函数 
  240. *返回值:MD5加密后算列值 
  241. ****************************************************/  
  242. string CMessageDigestAlgorithm5::Encode(string &str)  
  243. {  
  244.     Initialize();  
  245.     EncodeByte((const Byte * )(str.c_str()), str.length());  
  246.     Final();  
  247.     string strMD5 = ByteToHexString(m_Result,16);  
  248.     return strMD5;  
  249. }  
  250.   
  251. /*************************************************** 
  252. *参数:infile表示待加密文件 
  253. *功能:MD5算法主函数 
  254. *返回值:MD5加密后算列值 
  255. ****************************************************/  
  256. string CMessageDigestAlgorithm5::Encode(ifstream & infile)   
  257. {  
  258.     if (!infile)  
  259.     {  
  260.         return "";  
  261.     }  
  262.     Initialize();  
  263.     streamsize length;  
  264.     string str;  
  265.     char buffer[1024];  
  266.     while (! infile.eof())   
  267.     {  
  268.         infile.read(buffer, 1024);  
  269.         length = infile.gcount();  
  270.         if (length > 0)  
  271.         {  
  272.              EncodeByte((const Byte* )buffer,length);  
  273.              Final();  
  274.         }  
  275.     }  
  276.     infile.close();  
  277.     string strMD5 = ByteToHexString(m_Result,16);  
  278.     return strMD5;  
  279. }  
  280.   
  281.   
  282. void CMessageDigestAlgorithm5::EncodeByte(const Byte* input, size_t length)  
  283. {  
  284.   
  285.     unsigned int index, partLen;  
  286.     size_t i;  
  287.   
  288.     index = static_castint>((m_Count[0] >> 3) & 0x3f);//转换成字节mod64  
  289.   
  290.     m_Count[0] += (static_castint>(length) << 3);//bit数  
  291.     if (m_Count[0] < (static_castint>(length) << 3))  
  292.     {  
  293.         ++m_Count[1];  
  294.     }  
  295.     m_Count[1] += (static_castint>(length) >> 29);//  
  296.   
  297.     partLen = 64 - index;  
  298.   
  299.     if (length >= partLen)   
  300.     {  
  301.         memcpy(&m_Buffer[index], input, partLen);  
  302.         ProcessOfMDA5(m_Buffer);  
  303.         for (i = partLen; i + 63 < length; i += 64)  
  304.         {  
  305.             ProcessOfMDA5(&input[i]);  
  306.         }  
  307.         index = 0;  
  308.     }   
  309.     else   
  310.     {  
  311.         i = 0;  
  312.     }  
  313.     memcpy(&m_Buffer[index], &input[i], length - i);  
  314. }  
  315.   
  316. void  CMessageDigestAlgorithm5::Final()   
  317. {  
  318.     Byte bits[8];  
  319.     unsigned int tempChainingVariable[4],tempCount[2];  
  320.     unsigned int index, padLen;  
  321.   
  322.     memcpy(tempChainingVariable, m_ChainingVariable, 16);  
  323.     memcpy(tempCount, m_Count, 8);  
  324.   
  325.     UnsignedIntToByte(m_Count, bits, 8);  
  326.   
  327.   
  328.     index = static_castint>((m_Count[0] >> 3) & 0x3f);  
  329.     padLen = (index < 56) ? (56 - index) : (120 - index);  
  330.     EncodeByte(g_Padding, padLen);  
  331.   
  332.     EncodeByte(bits, 8);  
  333.   
  334.   
  335.     UnsignedIntToByte(m_ChainingVariable,m_Result, 16);  
  336.   
  337.     memcpy(m_ChainingVariable, tempChainingVariable, 16);  
  338.     memcpy(m_Count,tempCount, 8);  
  339. }  





五、说明

     对于MD5算法,不同的读取格式产生的字节流是不一样的,而且涉及计算可能需要数据格式转换,如把bit转换成一定的整型数据方便计算,
因此,不同MD5算法实现版本算出的结果可能有很大不一样。
因此,我觉得最好多次计算的MD5算法版本一致。关于MD5算法,有一个比较好的在线计算工具,点击MD5在线计算器
MD5算法是不可逆的,但是,基于键值对的字典关系原理,有一些收集海量MD5信息与摘要的,采用枚举法
能够从MD5值找到原文本信息
提供一个类似的工具,点击
。此外,在此提供MD5的讨论社区,点击 。

阅读(12616) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~