王朝网络
分享
 
 
 

MD5加密[JavaScript实现]

王朝html/css/js·作者佚名  2006-01-10
宽屏版  字体: |||超大  

MD5加密的JavaScript实现。

MD5加密,共分5步:详细内容大家可以查看http://www.leepig.com/rfc/RFC1321.txt

(1) 补位

MD5算法是对输入的数据进行补位,使得如果数据位长度LEN对512求余的结果是448。即数

据扩展至K*512+448位。即K*64+56个字节,K为整数。补位操作始终要执行,即使数据长度LEN

对512求余的结果已是448。

具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补一位,最多补512位。

(2) 补数据长度

用一个64位的数字表示数据的原始长度b,把b用两个32位数表示。那么只取B的低64位。

当遇到b大于2^64这种极少遇到的情况时,这时,数据就被填补成长度为512位的倍数。也就是说,

此时的数据长度是16个字(32位)的整数倍数。用M[0 ... N-1]表示此时的数据,其中的N是16

的倍数。

(3) 初始化MD缓冲器

(4)处理位操作函数

(5)16进制形式输出结果。

OK,下面就开始用JavaScript实现MD5加密。

首先,我们要思考一下为了实现以上五步,我们需要哪些功能函数。

第一、补位、补数据长度需要,可以定义为Inital(str),其中str是需要加密的原始字符串,该函数输出处理完后的数组。

第二、处理位操作的四个函数,FF、GG、HH、II需要定义。

第三、最后输出时要用16进制输出,并且高位0不可省略。

好了,首先写第一个Inital函数。

function Inital(str)

{

var len = str.length,count=0,wordIndex = 0;

var m = len + 8;

var wordNum = (m - m%64)/64 + 1;

wordNum = wordNum * 16;

var WordByte = new Array(wordNum -1);

for(count = 0; count < len; count++)

{

wordIndex = (count - (count%4))/4;

WordByte[wordIndex] |= ( str.charCodeAt(count)<<((count%4)*8));

}

wordIndex = (count - (count%4))/4;

WordByte[wordIndex] |= (0x80<<((count%4)/8));

wordIndex++;

while(wordIndex < wordNum - 2)

{

WordByte[wordIndex] =0;

wordIndex++;

}

WordByte[wordNum - 2] = len <<3;

WordByte[wordNum - 1] = len >> 29;

return WordByte;

}

下面简单说明一下这个函数,因为最后2个32位是用原始字符串长度来填充的(不明白的先去看MD5算法描述!哪个地方有?-_-!文章开头的链接就是。)所以我们先把原始字符串长度 + 8,(64位就是8个字节,这样就是假设最后的2个32位已经补充好了)。然后把中间的第一位补1,其余补0即可。

不过呢,这里要注意一下字符串的顺序,假如字符串"abc",那么他们一共占3*8=24位,其中a先进入数组,然后b左移8位后进入,c左移16位后进入,作后要补的1000000(16进制的0x80)左移24位后进入。

好了,下面就要定义位操作函数FF、GG、HH、II

这里要注意的是,我们要重新定义32位操作数的+的操作和移位操作。

function F(x,y,z) { return (x & y) | ((~x) & z); }

function G(x,y,z) { return (x & z) | (y & (~z)); }

function H(x,y,z) { return (x ^ y ^ z); }

function I(x,y,z) { return (y ^ (x | (~z))); }

function ADD(x, y){ return (x+y)&0xFFFFFFFF; }

function RotateLeft(lValue, iShiftBits)

{ return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits)); }

function FF(a,b,c,d,x,s,ac)

{

a = ADD(a, ADD(ADD(F(b, c, d), x), ac));

return ADD(RotateLeft(a, s), b);

}

function GG(a,b,c,d,x,s,ac)

{

a = ADD(a, ADD(ADD(G(b, c, d), x), ac));

return ADD(RotateLeft(a, s), b);

}

function HH(a,b,c,d,x,s,ac)

{

a = ADD(a, ADD(ADD(H(b, c, d), x), ac));

return ADD(RotateLeft(a, s), b);

}

function II(a,b,c,d,x,s,ac) {

a = ADD(a, ADD(ADD(I(b, c, d), x), ac));

return ADD(RotateLeft(a, s), b);

}

说明一下FF(a,b,c,d,x,s,ac) 其实就是a = a + F(b, c, d) + x +ac;然后返回(a<<s) + b;只不过这里的+要用我们自己定义的加,就是mod 2^32后的结果,<<也是我们自己定义的左移。很容易理解的。

下面就是输出16进制数的函数了

function Word2Hex(str)

{

var hexValue = "",temp_str="";

var i = 0,lByte;

for(; i < 4; i++)

{

lByte = (str>>(i*8))& 0xFF;

temp_str = "0" + lByte.toString(16);

hexValue += temp_str.substr(temp_str.length - 2, 2);

}

return hexValue;

}

这个函数就是为了防止漏掉0而设的。

好了,最后的就是主要的函数MD5(str)了。

function MD55(str)

{

var smessage =new Array();

// step 1 and 2:补位、补数据长度

smessage = Inital(str);

var i = 0,j =0;

var a, b, c, d;

// step 3 初始化位操作数

a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

// step 4位处理

for(i = 0; i< smessage.length; i+=16)

{

AA = a;

BB = b;

CC = c;

DD = d;

for(j = 0; j < 4; j++)

{

a = FF(a, b, c, d, smessage[i + 4*j+0], SS[0], TT[4*j+0]);

d = FF(d, a, b, c, smessage[i + 4*j+1], SS[1], TT[4*j+1]);

c = FF(c, d, a, b, smessage[i + 4*j+2], SS[2], TT[4*j+2]);

b = FF(b, c, d, a, smessage[i + 4*j+3], SS[3], TT[4*j+3]);

}

for(j = 0; j < 4; j++)

{

a = GG(a, b, c, d, smessage[i + Rotal[4*j+0]], SS[4],TT[16+4*j+0]);

d = GG(d, a, b, c, smessage[i + Rotal[4*j+1]], SS[5],TT[16+4*j+1]);

c = GG(c, d, a, b, smessage[i + Rotal[4*j+2]], SS[6],TT[16+4*j+2]);

b = GG(b, c, d, a, smessage[i + Rotal[4*j+3]], SS[7],TT[16+4*j+3]);

}

for(j = 0; j < 4; j++)

{

a = HH(a, b, c, d, smessage[i + Rotal[16+4*j+0]], SS[8], TT[32+4*j+0]);

d = HH(d, a, b, c, smessage[i + Rotal[16+4*j+1]], SS[9], TT[32+4*j+1]);

c = HH(c, d, a, b, smessage[i + Rotal[16+4*j+2]], SS[10], TT[32+4*j+2]);

b = HH(b, c, d, a, smessage[i + Rotal[16+4*j+3]], SS[11], TT[32+4*j+3]);

}

for(j= 0; j < 4; j++)

{

a = II(a, b, c, d, smessage[i + Rotal[4*j+32]], SS[12], TT[48+4*j+0]);

d = II(d, a, b, c, smessage[i + Rotal[4*j+33]], SS[13], TT[48+4*j+1]);

c = II(c, d, a, b, smessage[i + Rotal[4*j+34]], SS[14], TT[48+4*j+2]);

b = II(b, c, d, a, smessage[i + Rotal[4*j+35]], SS[15], TT[48+4*j+3]);

}

a = ADD(a, AA);

b = ADD(b, BB);

c = ADD(c, CC);

d = ADD(d, DD);

}

// step5

var lResult = Word2Hex(a)+Word2Hex(b)+Word2Hex(c)+Word2Hex(d);

document.message.test1.value = lResult.toLowerCase();

}

大家可以看到里面用了Rotal[]、SS[]、TT[]数组,其中Rotal[]是定义每次smessage移位数的,不明白的看看MD5算法描述。

var AA = 0x67452301, BB = 0xEFCDAB89, CC = 0x98BADCFE, DD = 0x10325476;

var SS = [7, 12, 17, 22, // step1

5, 9, 14, 20, // step2

4, 11, 16, 23,// step3

6, 10, 15, 21];// step4

var TT = [0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d, 0x2441453,0xd8a1e681,0xe7d3fbc8,0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085, 0x4881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391];

var Rotal = [1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8,13, 2, 7,12,

5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,

0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9];

OK了,大功告成。这里再提供几组测试数据:

MD5 ("") = d41d8cd98f00b204e9800998ecf8427e

MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661

MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72

MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0

MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b

MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =

d174ab98d277d9f5a5611c2c9f419d9f

MD5 ("123456789012345678901234567890123456789012345678901234567890123456

78901234567890") = 57edf4a22be3c955ac49da2e2107b67a

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有