File indexing completed on 2024-04-28 15:28:38
0001 // shouldBe() (base.js) test at very end of this file (Harri) 0002 0003 /* 0004 * md5.jvs 1.0b 27/06/96 0005 * 0006 * Javascript implementation of the RSA Data Security, Inc. MD5 0007 * Message-Digest Algorithm. 0008 * 0009 * Copyright (c) 1996 Henri Torgemane. All Rights Reserved. 0010 * 0011 * Permission to use, copy, modify, and distribute this software 0012 * and its documentation for any purposes and without 0013 * fee is hereby granted provided that this copyright notice 0014 * appears in all copies. 0015 * 0016 * Of course, this soft is provided "as is" without express or implied 0017 * warranty of any kind. 0018 0019 */ 0020 0021 // $Id: md5-1.js 419016 2005-05-28 10:50:56Z porten $ 0022 0023 function array(n) { 0024 for(i=0;i<n;i++) this[i]=0; 0025 this.length=n; 0026 } 0027 0028 /* Some basic logical functions had to be rewritten because of a bug in 0029 * Javascript.. Just try to compute 0xffffffff >> 4 with it.. 0030 * Of course, these functions are slower than the original would be, but 0031 * at least, they work! 0032 */ 0033 0034 function integer(n) { return n%(0xffffffff+1); } 0035 0036 function shr(a,b) { 0037 a=integer(a); 0038 b=integer(b); 0039 if (a-0x80000000>=0) { 0040 a=a%0x80000000; 0041 a>>=b; 0042 a+=0x40000000>>(b-1); 0043 } else 0044 a>>=b; 0045 return a; 0046 } 0047 0048 function shl1(a) { 0049 a=a%0x80000000; 0050 if (a&0x40000000==0x40000000) 0051 { 0052 a-=0x40000000; 0053 a*=2; 0054 a+=0x80000000; 0055 } else 0056 a*=2; 0057 return a; 0058 } 0059 0060 function shl(a,b) { 0061 a=integer(a); 0062 b=integer(b); 0063 for (var i=0;i<b;i++) a=shl1(a); 0064 return a; 0065 } 0066 0067 function and(a,b) { 0068 a=integer(a); 0069 b=integer(b); 0070 var t1=(a-0x80000000); 0071 var t2=(b-0x80000000); 0072 if (t1>=0) 0073 if (t2>=0) 0074 return ((t1&t2)+0x80000000); 0075 else 0076 return (t1&b); 0077 else 0078 if (t2>=0) 0079 return (a&t2); 0080 else 0081 return (a&b); 0082 } 0083 0084 function or(a,b) { 0085 a=integer(a); 0086 b=integer(b); 0087 var t1=(a-0x80000000); 0088 var t2=(b-0x80000000); 0089 if (t1>=0) 0090 if (t2>=0) 0091 return ((t1|t2)+0x80000000); 0092 else 0093 return ((t1|b)+0x80000000); 0094 else 0095 if (t2>=0) 0096 return ((a|t2)+0x80000000); 0097 else 0098 return (a|b); 0099 } 0100 0101 function xor(a,b) { 0102 a=integer(a); 0103 b=integer(b); 0104 var t1=(a-0x80000000); 0105 var t2=(b-0x80000000); 0106 if (t1>=0) 0107 if (t2>=0) 0108 return (t1^t2); 0109 else 0110 return ((t1^b)+0x80000000); 0111 else 0112 if (t2>=0) 0113 return ((a^t2)+0x80000000); 0114 else 0115 return (a^b); 0116 } 0117 0118 0119 function not(a) { 0120 a=integer(a); 0121 return (0xffffffff-a); 0122 } 0123 0124 /* Here begin the real algorithm */ 0125 0126 var state = new array(4); 0127 var count = new array(2); 0128 count[0] = 0; 0129 count[1] = 0; 0130 0131 var buffer = new array(64); 0132 var transformBuffer = new array(16); 0133 var digestBits = new array(16); 0134 0135 var S11 = 7; 0136 var S12 = 12; 0137 var S13 = 17; 0138 var S14 = 22; 0139 var S21 = 5; 0140 var S22 = 9; 0141 var S23 = 14; 0142 var S24 = 20; 0143 var S31 = 4; 0144 var S32 = 11; 0145 var S33 = 16; 0146 var S34 = 23; 0147 var S41 = 6; 0148 var S42 = 10; 0149 var S43 = 15; 0150 var S44 = 21; 0151 0152 0153 function F(x,y,z) { 0154 return or(and(x,y),and(not(x),z)); 0155 } 0156 0157 function G(x,y,z) { 0158 return or(and(x,z),and(y,not(z))); 0159 } 0160 0161 function H(x,y,z) { 0162 return xor(xor(x,y),z); 0163 } 0164 0165 function I(x,y,z) { 0166 return xor(y ,or(x , not(z))); 0167 } 0168 0169 function rotateLeft(a,n) { 0170 return or(shl(a, n),(shr(a,(32 - n)))); 0171 } 0172 0173 function FF(a,b,c,d,x,s,ac) { 0174 a = a+F(b, c, d) + x + ac; 0175 a = rotateLeft(a, s); 0176 a = a+b; 0177 return a; 0178 } 0179 0180 function GG(a,b,c,d,x,s,ac) { 0181 a = a+G(b, c, d) +x + ac; 0182 a = rotateLeft(a, s); 0183 a = a+b; 0184 return a; 0185 } 0186 0187 function HH(a,b,c,d,x,s,ac) { 0188 a = a+H(b, c, d) + x + ac; 0189 a = rotateLeft(a, s); 0190 a = a+b; 0191 return a; 0192 } 0193 0194 function II(a,b,c,d,x,s,ac) { 0195 a = a+I(b, c, d) + x + ac; 0196 a = rotateLeft(a, s); 0197 a = a+b; 0198 return a; 0199 } 0200 0201 function transform(buf,offset) { 0202 var a=0, b=0, c=0, d=0; 0203 var x = transformBuffer; 0204 0205 a = state[0]; 0206 b = state[1]; 0207 c = state[2]; 0208 d = state[3]; 0209 0210 for (i = 0; i < 16; i++) { 0211 x[i] = and(buf[i*4+offset],0xff); 0212 for (j = 1; j < 4; j++) { 0213 x[i]+=shl(and(buf[i*4+j+offset] ,0xff), j * 8); 0214 } 0215 } 0216 0217 /* Round 1 */ 0218 a = FF ( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 0219 d = FF ( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 0220 c = FF ( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 0221 b = FF ( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 0222 a = FF ( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 0223 d = FF ( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 0224 c = FF ( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 0225 b = FF ( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 0226 a = FF ( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 0227 d = FF ( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 0228 c = FF ( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 0229 b = FF ( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 0230 a = FF ( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 0231 d = FF ( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 0232 c = FF ( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 0233 b = FF ( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 0234 0235 /* Round 2 */ 0236 a = GG ( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 0237 d = GG ( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 0238 c = GG ( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 0239 b = GG ( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 0240 a = GG ( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 0241 d = GG ( d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 0242 c = GG ( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 0243 b = GG ( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 0244 a = GG ( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 0245 d = GG ( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 0246 c = GG ( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 0247 b = GG ( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 0248 a = GG ( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 0249 d = GG ( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 0250 c = GG ( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 0251 b = GG ( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 0252 0253 /* Round 3 */ 0254 a = HH ( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 0255 d = HH ( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 0256 c = HH ( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 0257 b = HH ( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 0258 a = HH ( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 0259 d = HH ( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 0260 c = HH ( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 0261 b = HH ( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 0262 a = HH ( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 0263 d = HH ( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 0264 c = HH ( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 0265 b = HH ( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 0266 a = HH ( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 0267 d = HH ( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 0268 c = HH ( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 0269 b = HH ( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 0270 0271 /* Round 4 */ 0272 a = II ( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 0273 d = II ( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 0274 c = II ( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 0275 b = II ( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 0276 a = II ( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 0277 d = II ( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 0278 c = II ( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 0279 b = II ( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 0280 a = II ( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 0281 d = II ( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 0282 c = II ( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 0283 b = II ( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 0284 a = II ( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 0285 d = II ( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 0286 c = II ( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 0287 b = II ( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 0288 0289 state[0] +=a; 0290 state[1] +=b; 0291 state[2] +=c; 0292 state[3] +=d; 0293 } 0294 0295 function init() { 0296 count[0]=count[1] = 0; 0297 state[0] = 0x67452301; 0298 state[1] = 0xefcdab89; 0299 state[2] = 0x98badcfe; 0300 state[3] = 0x10325476; 0301 for (i = 0; i < digestBits.length; i++) 0302 digestBits[i] = 0; 0303 } 0304 0305 function update(b) { 0306 var index,i; 0307 0308 index = and(shr(count[0],3) , 0x3f); 0309 if (count[0]<0xffffffff-7) 0310 count[0] += 8; 0311 else { 0312 count[1]++; 0313 count[0]-=0xffffffff+1; 0314 count[0]+=8; 0315 } 0316 0317 buffer[index] = and(b,0xff); 0318 if (index >= 63) { 0319 transform(buffer, 0); 0320 } 0321 } 0322 0323 function finish() { 0324 var bits = new array(8); 0325 var padding; 0326 var i=0, index=0, padLen=0; 0327 0328 for (i = 0; i < 4; i++) { 0329 bits[i] = and(shr(count[0],(i * 8)), 0xff); 0330 } 0331 0332 for (i = 0; i < 4; i++) { 0333 bits[i+4]=and(shr(count[1],(i * 8)), 0xff); 0334 } 0335 0336 index = and(shr(count[0], 3) ,0x3f); 0337 padLen = (index < 56) ? (56 - index) : (120 - index); 0338 padding = new array(64); 0339 padding[0] = 0x80; 0340 for (i=0;i<padLen;i++) 0341 update(padding[i]); 0342 0343 for (i=0;i<8;i++) 0344 update(bits[i]); 0345 0346 for (i = 0; i < 4; i++) { 0347 for (j = 0; j < 4; j++) { 0348 digestBits[i*4+j] = and(shr(state[i], (j * 8)) , 0xff); 0349 } 0350 } 0351 } 0352 0353 /* End of the MD5 algorithm */ 0354 0355 function hexa(n) { 0356 var hexa_h = "0123456789abcdef"; 0357 var hexa_c=""; 0358 var hexa_m=n; 0359 for (hexa_i=0;hexa_i<8;hexa_i++) { 0360 hexa_c=hexa_h.charAt(Math.abs(hexa_m)%16)+hexa_c; 0361 hexa_m=Math.floor(hexa_m/16); 0362 } 0363 return hexa_c; 0364 } 0365 0366 var ascii="01234567890123456789012345678901" + 0367 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ 0368 "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; 0369 0370 function MD5(entree) 0371 { 0372 var l,s,k,ka,kb,kc,kd; 0373 0374 init(); 0375 for (k=0;k<entree.length;k++) { 0376 l=entree.charAt(k); 0377 update(ascii.lastIndexOf(l)); 0378 } 0379 finish(); 0380 ka=kb=kc=kd=0; 0381 for (i=0;i<4;i++) ka+=shl(digestBits[15-i], (i*8)); 0382 for (i=4;i<8;i++) kb+=shl(digestBits[15-i], ((i-4)*8)); 0383 for (i=8;i<12;i++) kc+=shl(digestBits[15-i], ((i-8)*8)); 0384 for (i=12;i<16;i++) kd+=shl(digestBits[15-i], ((i-12)*8)); 0385 s=hexa(kd)+hexa(kc)+hexa(kb)+hexa(ka); 0386 return s; 0387 } 0388 0389 shouldBe("MD5('kde')", "'186cf28b76f2264e9fea8fcf91cb4f5d'");