山东省建设部网站官网,jsp网站开发技术,北京室内设计师电话,地推接单大厅appMD5#xff08;单向散列算法#xff09;
的全称是Message-Digest Algorithm 5#xff08;信息-摘要算法#xff09;#xff0c;经MD2、MD3和MD4发展而来。MD5算法的使用不需要支付任何版权费用。MD5功能#xff1a;输入任意长度的信息#xff0c;经过处理#xff0c;输…MD5单向散列算法
的全称是Message-Digest Algorithm 5信息-摘要算法经MD2、MD3和MD4发展而来。MD5算法的使用不需要支付任何版权费用。MD5功能输入任意长度的信息经过处理输出为128位的信息数字指纹不同的输入得到的不同的结果唯一性根据128位的输出结果不可能反推出输入的信息不可逆 MD5属不属于加密算法认为不属于的人是因为他们觉得不能从密文散列值反过来得到原文即没有解密算法所以这部分人认为MD5只能属于算法不能称为加密算法认为属于的人是因为他们觉得经过MD5处理后看不到原文即已经将原文加密所以认为MD5属于加密算法我个人支持后者。MD5用途 1、
防止被篡改1比如发送一个电子文档发送前我先得到MD5的输出结果a。然后在对方收到电子文档后对方也得到一个MD5的输出结果b。如果a与b一样就代表中途未被篡改。2比如我提供文件下载为了防止不法分子在安装程序中添加木马我可以在网站上公布由安装文件得到的MD5输出结果。3SVN在检测文件是否在CheckOut后被修改过也是用到了MD5.2、
防止直接看到明文现在很多网站在数据库存储用户的密码的时候都是存储用户密码的MD5值。这样就算不法分子得到数据库的用户密码的MD5值也无法知道用户的密码(其实这样是不安全的后面我会提到)。比如在UNIX系统中用户的密码就是以MD5或其它类似的算法经加密后存储在文件系统中。当用户登录的时候系统把用户输入的密码计算成MD5值然后再去和保存在文件系统中的MD5值进行比较进而确定输入的密码是否正确。通过这样的步骤系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道而且还在一定程度上增加了密码被破解的难度。3、
防止抵赖数字签名这需要一个第三方认证机构。例如A写了一个文件认证机构对此文件用MD5算法产生摘要信息并做好记录。若以后A说这文件不是他写的权威机构只需对此文件重新产生摘要信息然后跟记录在册的摘要信息进行比对相同的话就证明是A写的了。这就是所谓的“数字签名”。MD5算法过程对MD5算法简要的叙述可以为MD5以512位分组来处理输入的信息且每一分组又被划分为16个32位子分组经过了一系列的处理后算法的输出由四个32位分组组成将这四个32位分组级联后将生成一个128位散列值。第一步、填充如果输入信息的长度(bit)对512求余的结果不等于448就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后信息的长度就为N*512448(bit)第二步、记录信息长度用64位来存储填充前信息长度。这64位加在第一步结果的后面这样信息长度就变为N*51244864(N1)*512位。第三步、装入标准的幻数四个整数标准的幻数物理顺序是A(01234567)
16
B(89ABCDEF)
16
C(FEDCBA98)
16
D(76543210)
16
。如果在程序中定义应该是A0X67452301LB0XEFCDAB89LC0X98BADCFELD0X10325476L。有点晕哈其实想一想就明白了。第四步、四轮循环运算循环的次数是分组的个数N1 1将每一512字节细分成16个小组每个小组64位8个字节2先认识四个线性函数(是与,|是或,~是非,^是异或)F(X,Y,Z)(XY)|((~X)Z) G(X,Y,Z)(XZ)|(Y(~Z)) H(X,Y,Z)X^Y^Z I(X,Y,Z)Y^(X|(~Z))3设Mj表示消息的第j个子分组从0到15s表示循环左移s位则四种操作为FF(a,b,c,d,Mj,s,ti)表示ab((aF(b,c,d)Mjti)s) GG(a,b,c,d,Mj,s,ti)表示ab((aG(b,c,d)Mjti)s) HH(a,b,c,d,Mj,s,ti)表示ab((aH(b,c,d)Mjti)s) II(a,b,c,d,Mj,s,ti)表示ab((aI(b,c,d)Mjti)s)4四轮运算第一轮 aFF(a,b,c,d,M0,7,0xd76aa478) bFF(d,a,b,c,M1,12,0xe8c7b756) cFF(c,d,a,b,M2,17,0x242070db) dFF(b,c,d,a,M3,22,0xc1bdceee) aFF(a,b,c,d,M4,7,0xf57c0faf) bFF(d,a,b,c,M5,12,0x4787c62a) cFF(c,d,a,b,M6,17,0xa8304613) dFF(b,c,d,a,M7,22,0xfd469501) aFF(a,b,c,d,M8,7,0x698098d8) bFF(d,a,b,c,M9,12,0x8b44f7af) cFF(c,d,a,b,M10,17,0xffff5bb1) dFF(b,c,d,a,M11,22,0x895cd7be) aFF(a,b,c,d,M12,7,0x6b901122) bFF(d,a,b,c,M13,12,0xfd987193) cFF(c,d,a,b,M14,17,0xa679438e) dFF(b,c,d,a,M15,22,0x49b40821) 第二轮 aGG(a,b,c,d,M1,5,0xf61e2562) bGG(d,a,b,c,M6,9,0xc040b340) cGG(c,d,a,b,M11,14,0x265e5a51) dGG(b,c,d,a,M0,20,0xe9b6c7aa) aGG(a,b,c,d,M5,5,0xd62f105d) bGG(d,a,b,c,M10,9,0x02441453) cGG(c,d,a,b,M15,14,0xd8a1e681) dGG(b,c,d,a,M4,20,0xe7d3fbc8) aGG(a,b,c,d,M9,5,0x21e1cde6) bGG(d,a,b,c,M14,9,0xc33707d6) cGG(c,d,a,b,M3,14,0xf4d50d87) dGG(b,c,d,a,M8,20,0x455a14ed) aGG(a,b,c,d,M13,5,0xa9e3e905) bGG(d,a,b,c,M2,9,0xfcefa3f8) cGG(c,d,a,b,M7,14,0x676f02d9) dGG(b,c,d,a,M12,20,0x8d2a4c8a) 第三轮 aHH(a,b,c,d,M5,4,0xfffa3942) bHH(d,a,b,c,M8,11,0x8771f681) cHH(c,d,a,b,M11,16,0x6d9d6122) dHH(b,c,d,a,M14,23,0xfde5380c) aHH(a,b,c,d,M1,4,0xa4beea44) bHH(d,a,b,c,M4,11,0x4bdecfa9) cHH(c,d,a,b,M7,16,0xf6bb4b60) dHH(b,c,d,a,M10,23,0xbebfbc70) aHH(a,b,c,d,M13,4,0x289b7ec6) bHH(d,a,b,c,M0,11,0xeaa127fa) cHH(c,d,a,b,M3,16,0xd4ef3085) dHH(b,c,d,a,M6,23,0x04881d05) aHH(a,b,c,d,M9,4,0xd9d4d039) bHH(d,a,b,c,M12,11,0xe6db99e5) cHH(c,d,a,b,M15,16,0x1fa27cf8) dHH(b,c,d,a,M2,23,0xc4ac5665) 第四轮 aII(a,b,c,d,M0,6,0xf4292244) bII(d,a,b,c,M7,10,0x432aff97) cII(c,d,a,b,M14,15,0xab9423a7) dII(b,c,d,a,M5,21,0xfc93a039) aII(a,b,c,d,M12,6,0x655b59c3) bII(d,a,b,c,M3,10,0x8f0ccc92) cII(c,d,a,b,M10,15,0xffeff47d) dII(b,c,d,a,M1,21,0x85845dd1) aII(a,b,c,d,M8,6,0x6fa87e4f) bII(d,a,b,c,M15,10,0xfe2ce6e0) cII(c,d,a,b,M6,15,0xa3014314) dII(b,c,d,a,M13,21,0x4e0811a1) aII(a,b,c,d,M4,6,0xf7537e82) bII(d,a,b,c,M11,10,0xbd3af235) cII(c,d,a,b,M2,15,0x2ad7d2bb) dII(b,c,d,a,M9,21,0xeb86d391)5每轮循环后将ABCD分别加上abcd然后进入下一循环。如果上面的过程用JAVA代码来实现的话代码如下 package woxingwosu; /************************************************ * MD5 算法 * author 我行我素 * Date 2007-07-01 *************************************************/ public class MD5 { static final String hexs[]{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}; //标准的幻数 private static final long A0x67452301L; private static final long B0xefcdab89L; private static final long C0x98badcfeL; private static final long D0x10325476L; //下面这些S11-S44实际上是一个4*4的矩阵在四轮循环运算中用到 static final int S11 7; static final int S12 12; static final int S13 17; static final int S14 22; static final int S21 5; static final int S22 9; static final int S23 14; static final int S24 20; static final int S31 4; static final int S32 11; static final int S33 16; static final int S34 23; static final int S41 6; static final int S42 10; static final int S43 15; static final int S44 21; //java不支持无符号的基本数据unsigned private long [] result{A,B,C,D};//存储hash结果共4×32128位初始化值为幻数的级联 public static void main(String []args){ MD5 mdnew MD5(); System.out.println(md5(abc)md.digest(abc)); } private String digest(String inputStr){ byte [] inputBytesinputStr.getBytes(); int byteLeninputBytes.length;//长度字节 int groupCount0;//完整分组的个数 groupCountbyteLen/64;//每组512位64字节 long []groupsnull;//每个小组(64字节)再细分后的16个小组(4字节) //处理每一个完整 分组 for(int step0;stepgroupCount;step){ groupsdivGroup(inputBytes,step*64); trans(groups);//处理分组核心算法 } //处理完整分组后的尾巴 int restbyteLen%64;//512位分组后的余数 byte [] tempBytesnew byte[64]; if(rest56){ for(int i0;irest;i) tempBytes[i]inputBytes[byteLen-resti]; if(rest56){ tempBytes[rest](byte)(17); for(int i1;i56-rest;i) tempBytes[resti]0; } long len(long)(byteLen3); for(int i0;i8;i){ tempBytes[56i](byte)(len0xFFL); lenlen8; } groupsdivGroup(tempBytes,0); trans(groups);//处理分组 }else{ for(int i0;irest;i) tempBytes[i]inputBytes[byteLen-resti]; tempBytes[rest](byte)(17); for(int irest1;i64;i) tempBytes[i]0; groupsdivGroup(tempBytes,0); trans(groups);//处理分组 for(int i0;i56;i) tempBytes[i]0; long len(long)(byteLen3); for(int i0;i8;i){ tempBytes[56i](byte)(len0xFFL); lenlen8; } groupsdivGroup(tempBytes,0); trans(groups);//处理分组 } //将Hash值转换成十六进制的字符串 String resStr; long temp0; for(int i0;i4;i){ for(int j0;j4;j){ tempresult[i]0x0FL; String ahexs[(int)(temp)]; result[i]result[i]4; tempresult[i]0x0FL; resStrhexs[(int)(temp)]a; result[i]result[i]4; } } return resStr; } /** * 从inputBytes的index开始取512位作为新的分组 * 将每一个512位的分组再细分成16个小组每个小组64位8个字节 * param inputBytes * param index * return */ private static long[] divGroup(byte[] inputBytes,int index){ long [] tempnew long[16]; for(int i0;i16;i){ temp[i]b2iu(inputBytes[4*iindex])| (b2iu(inputBytes[4*i1index]))8| (b2iu(inputBytes[4*i2index]))16| (b2iu(inputBytes[4*i3index]))24; } return temp; } /** * 这时不存在符号位符号位存储不再是代表正负所以需要处理一下 * param b * return */ public static long b2iu(byte b){ return b 0 ? b 0x7F 128 : b; } /** * 主要的操作四轮循环 * param groups[]--每一个分组512位64字节 */ private void trans(long[] groups) { long a result[0], b result[1], c result[2], d result[3]; /*第一轮*/ a FF(a, b, c, d, groups[0], S11, 0xd76aa478L); /* 1 */ d FF(d, a, b, c, groups[1], S12, 0xe8c7b756L); /* 2 */ c FF(c, d, a, b, groups[2], S13, 0x242070dbL); /* 3 */ b FF(b, c, d, a, groups[3], S14, 0xc1bdceeeL); /* 4 */ a FF(a, b, c, d, groups[4], S11, 0xf57c0fafL); /* 5 */ d FF(d, a, b, c, groups[5], S12, 0x4787c62aL); /* 6 */ c FF(c, d, a, b, groups[6], S13, 0xa8304613L); /* 7 */ b FF(b, c, d, a, groups[7], S14, 0xfd469501L); /* 8 */ a FF(a, b, c, d, groups[8], S11, 0x698098d8L); /* 9 */ d FF(d, a, b, c, groups[9], S12, 0x8b44f7afL); /* 10 */ c FF(c, d, a, b, groups[10], S13, 0xffff5bb1L); /* 11 */ b FF(b, c, d, a, groups[11], S14, 0x895cd7beL); /* 12 */ a FF(a, b, c, d, groups[12], S11, 0x6b901122L); /* 13 */ d FF(d, a, b, c, groups[13], S12, 0xfd987193L); /* 14 */ c FF(c, d, a, b, groups[14], S13, 0xa679438eL); /* 15 */ b FF(b, c, d, a, groups[15], S14, 0x49b40821L); /* 16 */ /*第二轮*/ a GG(a, b, c, d, groups[1], S21, 0xf61e2562L); /* 17 */ d GG(d, a, b, c, groups[6], S22, 0xc040b340L); /* 18 */ c GG(c, d, a, b, groups[11], S23, 0x265e5a51L); /* 19 */ b GG(b, c, d, a, groups[0], S24, 0xe9b6c7aaL); /* 20 */ a GG(a, b, c, d, groups[5], S21, 0xd62f105dL); /* 21 */ d GG(d, a, b, c, groups[10], S22, 0x2441453L); /* 22 */ c GG(c, d, a, b, groups[15], S23, 0xd8a1e681L); /* 23 */ b GG(b, c, d, a, groups[4], S24, 0xe7d3fbc8L); /* 24 */ a GG(a, b, c, d, groups[9], S21, 0x21e1cde6L); /* 25 */ d GG(d, a, b, c, groups[14], S22, 0xc33707d6L); /* 26 */ c GG(c, d, a, b, groups[3], S23, 0xf4d50d87L); /* 27 */ b GG(b, c, d, a, groups[8], S24, 0x455a14edL); /* 28 */ a GG(a, b, c, d, groups[13], S21, 0xa9e3e905L); /* 29 */ d GG(d, a, b, c, groups[2], S22, 0xfcefa3f8L); /* 30 */ c GG(c, d, a, b, groups[7], S23, 0x676f02d9L); /* 31 */ b GG(b, c, d, a, groups[12], S24, 0x8d2a4c8aL); /* 32 */ /*第三轮*/ a HH(a, b, c, d, groups[5], S31, 0xfffa3942L); /* 33 */ d HH(d, a, b, c, groups[8], S32, 0x8771f681L); /* 34 */ c HH(c, d, a, b, groups[11], S33, 0x6d9d6122L); /* 35 */ b HH(b, c, d, a, groups[14], S34, 0xfde5380cL); /* 36 */ a HH(a, b, c, d, groups[1], S31, 0xa4beea44L); /* 37 */ d HH(d, a, b, c, groups[4], S32, 0x4bdecfa9L); /* 38 */ c HH(c, d, a, b, groups[7], S33, 0xf6bb4b60L); /* 39 */ b HH(b, c, d, a, groups[10], S34, 0xbebfbc70L); /* 40 */ a HH(a, b, c, d, groups[13], S31, 0x289b7ec6L); /* 41 */ d HH(d, a, b, c, groups[0], S32, 0xeaa127faL); /* 42 */ c HH(c, d, a, b, groups[3], S33, 0xd4ef3085L); /* 43 */ b HH(b, c, d, a, groups[6], S34, 0x4881d05L); /* 44 */ a HH(a, b, c, d, groups[9], S31, 0xd9d4d039L); /* 45 */ d HH(d, a, b, c, groups[12], S32, 0xe6db99e5L); /* 46 */ c HH(c, d, a, b, groups[15], S33, 0x1fa27cf8L); /* 47 */ b HH(b, c, d, a, groups[2], S34, 0xc4ac5665L); /* 48 */ /*第四轮*/ a II(a, b, c, d, groups[0], S41, 0xf4292244L); /* 49 */ d II(d, a, b, c, groups[7], S42, 0x432aff97L); /* 50 */ c II(c, d, a, b, groups[14], S43, 0xab9423a7L); /* 51 */ b II(b, c, d, a, groups[5], S44, 0xfc93a039L); /* 52 */ a II(a, b, c, d, groups[12], S41, 0x655b59c3L); /* 53 */ d II(d, a, b, c, groups[3], S42, 0x8f0ccc92L); /* 54 */ c II(c, d, a, b, groups[10], S43, 0xffeff47dL); /* 55 */ b II(b, c, d, a, groups[1], S44, 0x85845dd1L); /* 56 */ a II(a, b, c, d, groups[8], S41, 0x6fa87e4fL); /* 57 */ d II(d, a, b, c, groups[15], S42, 0xfe2ce6e0L); /* 58 */ c II(c, d, a, b, groups[6], S43, 0xa3014314L); /* 59 */ b II(b, c, d, a, groups[13], S44, 0x4e0811a1L); /* 60 */ a II(a, b, c, d, groups[4], S41, 0xf7537e82L); /* 61 */ d II(d, a, b, c, groups[11], S42, 0xbd3af235L); /* 62 */ c II(c, d, a, b, groups[2], S43, 0x2ad7d2bbL); /* 63 */ b II(b, c, d, a, groups[9], S44, 0xeb86d391L); /* 64 */ /*加入到之前计算的结果当中*/ result[0] a; result[1] b; result[2] c; result[3] d; result[0]result[0]0xFFFFFFFFL; result[1]result[1]0xFFFFFFFFL; result[2]result[2]0xFFFFFFFFL; result[3]result[3]0xFFFFFFFFL; } /** * 下面是处理要用到的线性函数 */ private static long F(long x, long y, long z) { return (x y) | ((~x) z); } private static long G(long x, long y, long z) { return (x z) | (y (~z)); } private static long H(long x, long y, long z) { return x ^ y ^ z; } private static long I(long x, long y, long z) { return y ^ (x | (~z)); } private static long FF(long a, long b, long c, long d, long x, long s, long ac) { a (F(b, c, d)0xFFFFFFFFL) x ac; a ((a0xFFFFFFFFL) s) | ((a0xFFFFFFFFL) (32 - s)); a b; return (a0xFFFFFFFFL); } private static long GG(long a, long b, long c, long d, long x, long s, long ac) { a (G(b, c, d)0xFFFFFFFFL) x ac; a ((a0xFFFFFFFFL) s) | ((a0xFFFFFFFFL) (32 - s)); a b; return (a0xFFFFFFFFL); } private static long HH(long a, long b, long c, long d, long x, long s, long ac) { a (H(b, c, d)0xFFFFFFFFL) x ac; a ((a0xFFFFFFFFL) s) | ((a0xFFFFFFFFL) (32 - s)); a b; return (a0xFFFFFFFFL); } private static long II(long a, long b, long c, long d, long x, long s, long ac) { a (I(b, c, d)0xFFFFFFFFL) x ac; a ((a0xFFFFFFFFL) s) | ((a0xFFFFFFFFL) (32 - s)); a b; return (a0xFFFFFFFFL); } } MD5安全性 普遍认为MD5是很安全因为暴力破解的时间是一般人无法接受的。实际上如果把用户的密码MD5处理后再存储到数据库其实是很不安全的。因为用户的密码是比较短的而且很多用户的密码都使用生日手机号码身份证号码电话号码等等。或者使用常用的一些吉利的数字或者某个英文单词。如果我把常用的密码先MD5处理把数据存储起来然后再跟你的MD5结果匹配这时我就有可能得到明文。比如某个MD5破解网站
http://www.cmd5.com/default.aspx
我把其网站下的公告复制如下md5破解、动网论坛密码破解等不再需要用穷举法本站共有md5记录235亿条还在不断增长中已包含10位及10位以下数字、7位字母、部分7位字母数字,全部6位及以下字母加数字等组合并针对国内用户做了大量优化例如已经包含所有手机号码、全国部分大中城市固定电话号码、百家姓、常用拼音等大量组合另加入了某大型网站真实会员密码数据10万条。本站数据量大查询速度快同时支持16位及32位密码查询。通过对10万会员的真实动网论坛样本数据的测试本站对于动网论坛密码的命中率达到83%。 本站4T的硬盘已经上线正在生成数据预计需要2个月左右时间到时候本站能查询到12位数字和9位字母。你可以用你的生日手机号码去测试一下。我觉得只需要将上面我写的MD5的标准幻数A,B,C,D的值修改一下修改后也不是MD5算法了因为不能保证唯一性。这样就算别人得到32位的值他如果不知道幻数的值是无法还原明文的。就算得到了幻数也是很难破解的。JAVA实现MD5 在java中实现MD5是很简单的在包java.security有个类MessageDigest。官方文档如下MessageDigest 类为应用程序提供信息摘要算法的功能如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数它接收任意大小的数据输出固定长度的哈希值。 MessageDigest 对象开始被初始化。该对象通过使用 update 方法处理数据。任何时候都可以调用 reset 方法重置摘要。一旦所有需要更新的数据都已经被更新了应该调用 digest 方法之一完成哈希计算。 对于给定数量的更新数据digest 方法只能被调用一次。digest 被调用后MessageDigest 对象被重新设置成其初始状态。使用MessageDigest很简单例如 package woxingwosu; /************************************************ * MD5 算法 * author 我行我素 * Date 2007-07-06 *************************************************/ import java.security.MessageDigest; public class MyMD5 { static char[] hex {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}; public static void main(String[] args) { try{ MessageDigest md5 MessageDigest.getInstance(MD5);//申明使用MD5算法 md5.update(a.getBytes());// System.out.println(md5(a)byte2str(md5.digest())); md5.update(a.getBytes()); md5.update(bc.getBytes()); System.out.println(md5(abc)byte2str(md5.digest())); }catch(Exception e){ e.printStackTrace(); } } /** * 将字节数组转换成十六进制字符串 * param bytes * return */ private static String byte2str(byte []bytes){ int len bytes.length; StringBuffer result new StringBuffer(); for (int i 0; i len; i) { byte byte0 bytes[i]; result.append(hex[byte0 4 0xf]); result.append(hex[byte0 0xf]); } return result.toString(); } } 另外附上其他版本的MD5算法的实现(
来自网络
)1)
JS版的MD5
(调用方法md5(明文))/* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase 1; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad ; /* base-64 pad character. for strict RFC compliance */ var chrsz 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ /* * These are the functions youll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } /* * Calculate the MD5 of an array of little-endian words, and a bit length */ function core_md5(x, len) { /* append padding */ x[len 5] | 0x80 ((len) % 32); x[(((len 64) 9) 4) 14] len; var a 1732584193; var b -271733879; var c -1732584194; var d 271733878; for(var i 0; i x.length; i 16) { var olda a; var oldb b; var oldc c; var oldd d; a md5_ff(a, b, c, d, x[i 0], 7 , -680876936); d md5_ff(d, a, b, c, x[i 1], 12, -389564586); c md5_ff(c, d, a, b, x[i 2], 17, 606105819); b md5_ff(b, c, d, a, x[i 3], 22, -1044525330); a md5_ff(a, b, c, d, x[i 4], 7 , -176418897); d md5_ff(d, a, b, c, x[i 5], 12, 1200080426); c md5_ff(c, d, a, b, x[i 6], 17, -1473231341); b md5_ff(b, c, d, a, x[i 7], 22, -45705983); a md5_ff(a, b, c, d, x[i 8], 7 , 1770035416); d md5_ff(d, a, b, c, x[i 9], 12, -1958414417); c md5_ff(c, d, a, b, x[i10], 17, -42063); b md5_ff(b, c, d, a, x[i11], 22, -1990404162); a md5_ff(a, b, c, d, x[i12], 7 , 1804603682); d md5_ff(d, a, b, c, x[i13], 12, -40341101); c md5_ff(c, d, a, b, x[i14], 17, -1502002290); b md5_ff(b, c, d, a, x[i15], 22, 1236535329); a md5_gg(a, b, c, d, x[i 1], 5 , -165796510); d md5_gg(d, a, b, c, x[i 6], 9 , -1069501632); c md5_gg(c, d, a, b, x[i11], 14, 643717713); b md5_gg(b, c, d, a, x[i 0], 20, -373897302); a md5_gg(a, b, c, d, x[i 5], 5 , -701558691); d md5_gg(d, a, b, c, x[i10], 9 , 38016083); c md5_gg(c, d, a, b, x[i15], 14, -660478335); b md5_gg(b, c, d, a, x[i 4], 20, -405537848); a md5_gg(a, b, c, d, x[i 9], 5 , 568446438); d md5_gg(d, a, b, c, x[i14], 9 , -1019803690); c md5_gg(c, d, a, b, x[i 3], 14, -187363961); b md5_gg(b, c, d, a, x[i 8], 20, 1163531501); a md5_gg(a, b, c, d, x[i13], 5 , -1444681467); d md5_gg(d, a, b, c, x[i 2], 9 , -51403784); c md5_gg(c, d, a, b, x[i 7], 14, 1735328473); b md5_gg(b, c, d, a, x[i12], 20, -1926607734); a md5_hh(a, b, c, d, x[i 5], 4 , -378558); d md5_hh(d, a, b, c, x[i 8], 11, -2022574463); c md5_hh(c, d, a, b, x[i11], 16, 1839030562); b md5_hh(b, c, d, a, x[i14], 23, -35309556); a md5_hh(a, b, c, d, x[i 1], 4 , -1530992060); d md5_hh(d, a, b, c, x[i 4], 11, 1272893353); c md5_hh(c, d, a, b, x[i 7], 16, -155497632); b md5_hh(b, c, d, a, x[i10], 23, -1094730640); a md5_hh(a, b, c, d, x[i13], 4 , 681279174); d md5_hh(d, a, b, c, x[i 0], 11, -358537222); c md5_hh(c, d, a, b, x[i 3], 16, -722521979); b md5_hh(b, c, d, a, x[i 6], 23, 76029189); a md5_hh(a, b, c, d, x[i 9], 4 , -640364487); d md5_hh(d, a, b, c, x[i12], 11, -421815835); c md5_hh(c, d, a, b, x[i15], 16, 530742520); b md5_hh(b, c, d, a, x[i 2], 23, -995338651); a md5_ii(a, b, c, d, x[i 0], 6 , -198630844); d md5_ii(d, a, b, c, x[i 7], 10, 1126891415); c md5_ii(c, d, a, b, x[i14], 15, -1416354905); b md5_ii(b, c, d, a, x[i 5], 21, -57434055); a md5_ii(a, b, c, d, x[i12], 6 , 1700485571); d md5_ii(d, a, b, c, x[i 3], 10, -1894986606); c md5_ii(c, d, a, b, x[i10], 15, -1051523); b md5_ii(b, c, d, a, x[i 1], 21, -2054922799); a md5_ii(a, b, c, d, x[i 8], 6 , 1873313359); d md5_ii(d, a, b, c, x[i15], 10, -30611744); c md5_ii(c, d, a, b, x[i 6], 15, -1560198380); b md5_ii(b, c, d, a, x[i13], 21, 1309151649); a md5_ii(a, b, c, d, x[i 4], 6 , -145523070); d md5_ii(d, a, b, c, x[i11], 10, -1120210379); c md5_ii(c, d, a, b, x[i 2], 15, 718787259); b md5_ii(b, c, d, a, x[i 9], 21, -343485551); a safe_add(a, olda); b safe_add(b, oldb); c safe_add(c, oldc); d safe_add(d, oldd); } return Array(a, b, c, d); } /* * These functions implement the four basic operations the algorithm uses. */ function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); } function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b c) | ((~b) d), a, b, x, s, t); } function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b d) | (c (~d)), a, b, x, s, t); } function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); } function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); } /* * Calculate the HMAC-MD5, of a key and some data */ function core_hmac_md5(key, data) { var bkey str2binl(key); if(bkey.length 16) bkey core_md5(bkey, key.length * chrsz); var ipad Array(16), opad Array(16); for(var i 0; i 16; i) { ipad[i] bkey[i] ^ 0x36363636; opad[i] bkey[i] ^ 0x5C5C5C5C; } var hash core_md5(ipad.concat(str2binl(data)), 512 data.length * chrsz); return core_md5(opad.concat(hash), 512 128); } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw (x 0xFFFF) (y 0xFFFF); var msw (x 16) (y 16) (lsw 16); return (msw 16) | (lsw 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num cnt) | (num (32 - cnt)); } /* * Convert a string to an array of little-endian words * If chrsz is ASCII, characters 255 have their hi-byte silently ignored. */ function str2binl(str) { var bin Array(); var mask (1 chrsz) - 1; for(var i 0; i str.length * chrsz; i chrsz) bin[i5] | (str.charCodeAt(i / chrsz) mask) (i%32); return bin; } /* * Convert an array of little-endian words to a string */ function binl2str(bin) { var str ; var mask (1 chrsz) - 1; for(var i 0; i bin.length * 32; i chrsz) str String.fromCharCode((bin[i5] (i % 32)) mask); return str; } /* * Convert an array of little-endian words to a hex string. */ function binl2hex(binarray) { var hex_tab hexcase ? 0123456789ABCDEF : 0123456789abcdef; var str ; for(var i 0; i binarray.length * 4; i) { str hex_tab.charAt((binarray[i2] ((i%4)*84)) 0xF) hex_tab.charAt((binarray[i2] ((i%4)*8 )) 0xF); } return str; } String.prototype.trim function(){return this.replace(/(^s*)|(s*$)/g, );} function md5(text) { return hex_md5(text.trim()); }