MD5算法

摘要:
转自MD5算法MD5是输入不定长度信息,输出固定长度128-bits的算法。MD5的具体实现好像有所区别,起码维基百科和百度百科的就不一样。但经过验证都是正确的,而这里采用的是维基百科的方法:使用MD5转换数据,需要使用相关的预设数据值去执行一系列步骤。

转自MD5算法

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

MD5的具体实现好像有所区别,起码维基百科和百度百科的就不一样。但经过验证都是正确的,而这里采用的是维基百科的方法(http://zh.wikipedia.org/wiki/MD5):

使用MD5转换数据,需要使用相关的预设数据值去执行一系列步骤。先定义几个需要使用的数据和函数,罗列如下:

 A = 0x67452301;
 B = 0xEFCDAB89;
 C = 0x98BADCFE;
 D = 0x10325476;
    F(X, Y, Z) = (X & Y) | (~X & Z);
    G(X, Y, Z) = (X & Z) | (Y & ~Z);
    H(X, Y, Z) = X ⊕ Y ⊕ Z;
I(X, Y, Z) = Y ⊕(X | ~Z);
K[ 64 ],其中K[ i ] = floor( abs(sin(i + 1)) × 2^32 )
R[ 64 ] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }

假设待转换数据为M,按如下步骤进行:

1.在M后面补1,然后补0,直到其长度模除512等于448;

2.继续在后面追加一个64bit数(小端表示),表示M的原始长度;

3.将M每512位拆分为一组,每一组进行如下操作:

A.拆分为16个32位的word(小端表示),用W[ i ]来标识;

B.将A、B、C、D分别赋值给a、b、c、d;

C.设置循环变量i,从0到63,执行如下操作:

a.若0<=i<=15,则f = F(b, c, d),g = i;

b.若16<=i<=31,则f = G(b, c, d),g = ( 5 * i + 1 ) % 16;

c.若32<=i<=47,则f = H(b, c, d),g = ( 3 * i + 5 ) % 16;

d.若48<=i<=63,则f = I(b, c, d),g = ( 7 * i ) % 16;

e. temp = d, d = c, c = b, b= leftrotate((a + f + K[i] + W[g]),R[i]) + b, a = temp;

D.A += a, B += b, C += c, D += d;

4. ABCD(各自以小端表示后级联)就是M经过MD5转换后形成的最终信息N。

在具体实现(C/C++)中,考虑到补位(bit)比较困难,一般是补字节(byte)。由于1byte=8bits,所以512bits=64bytes,448bits=56bytes,而一开始补位1就变成了补字节0x80(即128D,或者说是10000000B)。需要注意的是小端表示很重要,否则得到的结果会不正确。

下面为具体代码:

  1. /********************************************************
  2. 1.本程序只提供对字符串进行MD5加密的能力
  3. 2.转换过程中相关的信息输出以注释屏蔽了,如有必要可去除
  4. 3.学号:10389203姓名:吴嘉琪日期:2012-10-17
  5. *********************************************************/
  6. #include<cstdio>
  7. #include<iostream>
  8. #include<cmath>
  9. #include<string>
  10. #include<iomanip>
  11. #include<bitset>
  12. usingnamespacestd;
  13. voidMD5(strings);//对字符串s进行MD5加密
  14. voidappending(string&s,unsignedlonglongsize);//为原始信息补位
  15. inttransform(strings);//以小端规则把长度为4的字符串转换成32位(4字节)数据
  16. unsignedlittleEndian(unsignedn);//把n转换成小端规则表示的数据
  17. /*MD5需要用的相关数据*/
  18. unsignedA,B,C,D;
  19. unsignedK[64],W[16];
  20. unsignedR[64]={7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
  21. 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
  22. 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
  23. 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21};
  24. /*MD5需要用的相关函数的宏定义*/
  25. #defineF(x,y,z)(((x)&(y))|((~x)&(z)))
  26. #defineG(x,y,z)(((x)&(z))|((y)&(~z)))
  27. #defineH(x,y,z)((x)^(y)^(z))
  28. #defineI(x,y,z)((y)^((x)|(~z)))
  29. #defineROTATE_LEFT(x,n)(((x)<<(n))|((x)>>(32-(n))))
  30. intmain()
  31. {
  32. for(inti=0;i<64;i++)
  33. K[i]=floor(abs(sinl(i+1))*powl(2,32));
  34. MD5("");
  35. MD5("a");
  36. MD5("abc");
  37. MD5("messagedigest");
  38. return0;
  39. }
  40. voidMD5(strings){
  41. A=0x67452301,B=0xEFCDAB89,C=0x98BADCFE,D=0x10325476;
  42. unsignedsize=s.size();
  43. appending(s,size*8);
  44. /*每512位(64字节)拆分为一组,此为外循环*/
  45. for(intk=0;k<s.size()/64;k++){
  46. /*拆分为16个32位(4字节)的word,用W[i]来标识*/
  47. for(inti=0;i<16;i++)
  48. W[i]=transform(s.substr(64*k+4*i,4));
  49. //cout<<"整理为WORD之后的二进制数据: ";
  50. //for(inti=0;i<16;i++)
  51. //cout<<setw(2)<<i<<":"<<bitset<32>((int)W[i])<<endl;
  52. unsigneda=A,b=B,c=C,d=D,f,g,temp;
  53. for(inti=0;i<64;i++){
  54. if(i>=0&&i<=15){
  55. f=F(b,c,d);
  56. g=i;
  57. }
  58. elseif(i>=16&&i<=31){
  59. f=G(b,c,d);
  60. g=(5*i+1)%16;
  61. }
  62. elseif(i>=32&&i<=47){
  63. f=H(b,c,d);
  64. g=(3*i+5)%16;
  65. }
  66. else{
  67. f=I(b,c,d);
  68. g=(7*i)%16;
  69. }
  70. temp=d;
  71. d=c;
  72. c=b;
  73. b=ROTATE_LEFT((a+f+K[i]+W[g]),R[i])+b;
  74. a=temp;
  75. }
  76. A+=a;
  77. B+=b;
  78. C+=c;
  79. D+=d;
  80. }
  81. /*格式化控制输出*/
  82. printf("MD5("%s")=",s.substr(0,size).c_str());
  83. printf("%08x%08x%08x%08x ",littleEndian(A),littleEndian(B),littleEndian(C),littleEndian(D));
  84. }
  85. voidappending(string&s,unsignedlonglongsize){
  86. /*补位至模除512为448(56字节)*/
  87. s+=(char)128;
  88. intsign=56-s.size()%64;
  89. inttemp=(sign<0?64+sign:sign);
  90. while(temp--)
  91. s+=(char)0;
  92. /*信息尾部添加原信息长度,用64位(8字节)数据以小端规则存储*/
  93. char*now=(char*)&size;
  94. for(inti=0;i<8;i++)
  95. s+=*(now+i);
  96. //printf("检验补位完毕后的信息的二进制数据:");
  97. //for(inti=0;i<s.size();i++){
  98. //if(i%4==0)
  99. //printf(" ");
  100. //printf("%2d:",i,s[i]);
  101. //cout<<bitset<8>((int)s[i])<<"";
  102. //}
  103. //cout<<endl;
  104. }
  105. inttransform(strings){
  106. return(0xFF000000&s[3]<<24)|(0x00FF0000&s[2]<<16)
  107. |(0x0000FF00&s[1]<<8)|(0x000000FF&s[0]);
  108. }
  109. unsignedlittleEndian(unsignedn){
  110. return(0xFF000000&n<<24)|(0x00FF0000&n<<8)
  111. |(0x0000FF00&n>>8)|(0x000000FF&n>>24);
  112. }

免责声明:文章转载自《MD5算法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇XSL基础教程(二)利用dump函数理解oracle如何存储各种类型数据下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

MD5 加盐加密

一、概述   MD5(Message Digest  Algorithm 5),是一种散列算法,是不可逆的,即通过md5加密之后没办法得到原文,没有解密算法。   在一般的项目中都会有登录注册功能,最简单的,登录注册过程完全没有加密,存储在数据库的密码也是明文,安全性是很差的,万一数据泄露就不好了(表一)。所以,通过MD5将密码加密后保存在数据库中(表二)...

.NET Core MD5加密 32位和16位

public class MD5Help {   //此代码示例通过创建哈希字符串适用于任何 MD5 哈希函数 (在任何平台) 上创建 32 个字符的十六进制格式哈希字符串官网案例改编   /// <summary>   ///获取32位md5加密   /// </summary>   /// <param nam...

iOS 几种加密方法

iOS常见的几种加密方法 普通加密方法是讲密码进行加密后保存到用户偏好设置中 钥匙串是以明文形式保存,但是不知道存放的具体位置 1、base64加密 base64 编码是现代密码学的基础 基本原理: 原本是 8个bit 一组表示数据,改为 6个bit一组表示数据,不足的部分补零,每 两个0 用 一个 = 表示 用base64 编码之后,数据长度会变大,增...

Spring Security中的MD5盐值加密

在 spring Security 文档中有这么一句话: "盐值的原理非常简单,就是先把密码和盐值指定的内容合并在一起,再使用md5对合并后的内容进行演算,这样一来,就算密码是一个很常见的字符串,再加上用户名,最后算出来的md5值就没那么容易猜出来了。因为攻击者不知道盐值的值,也很难反算出密码原文。" 问题如何理解这句话: "先把密码和盐值指定的内容合并在...

盐值加密-MD5

盐值加密-MD5 什么叫盐值加密 Spring security怎样进行盐值加密 以前的md5原理是 密码密文=md5算法(密码明文); 这样明文与密文其实还是一一对应的 那么人家就可以用字典攻击(就是一个一个的试)来探测密码 加盐(盐值加密)的算法很多 Spring security用的是: 密码密文=md5算法(密码明文{盐值}); 这个盐值就可以自己...

C# MD5算法 16 32 大小写

MD5算法 /** *┌──────────────────────────────────────────────────────────────┐ *│ 描 述:日志相关的工具类 *│ 作 者:执笔小白...