1/* 2 Javascript MD5 library - version 0.4 3 4 Coded (2011) by Luigi Galli - [email protected] - http://faultylabs.com 5 6 Thanks to: Roberto Viola 7 8 The below code is PUBLIC DOMAIN - NO WARRANTY! 9 10 Changelog: 11 Version 0.4 - 2011-06-19 12 + added compact version (md5_compact_min.js), this is a slower but smaller version 13 (more than 4KB lighter before stripping/minification) 14 + added preliminary support for Typed Arrays (see: 15 https://developer.mozilla.org/en/JavaScript_typed_arrays and 16 http://www.khronos.org/registry/typedarray/specs/latest/) 17 MD5() now accepts input data as ArrayBuffer, Float32Array, Float64Array, 18 Int16Array, Int32Array, Int8Array, Uint16Array, Uint32Array or Uint8Array 19 - moved unit tests to md5_test.js 20 - minor refactoring 21 22 Version 0.3.* - 2011-06-## 23 - Internal dev versions 24 25 Version 0.2 - 2011-05-22 26 ** FIXED: serious integer overflow problems which could cause a wrong MD5 hash being returned 27 28 Version 0.1 - 2011 29 -Initial version 30*/ 31 32if (typeof faultylabs == 'undefined') { 33 faultylabs = {} 34} 35 36/* 37 MD5() 38 39 Computes the MD5 hash for the given input data 40 41 input : data as String - (Assumes Unicode code points are encoded as UTF-8. If you 42 attempt to digest Unicode strings using other encodings 43 you will get incorrect results!) 44 45 data as array of characters - (Assumes Unicode code points are encoded as UTF-8. If you 46 attempt to digest Unicode strings using other encodings 47 you will get incorrect results!) 48 49 data as array of bytes (plain javascript array of integer numbers) 50 51 data as ArrayBuffer (see: https://developer.mozilla.org/en/JavaScript_typed_arrays) 52 53 data as Float32Array, Float64Array, Int16Array, Int32Array, Int8Array, Uint16Array, Uint32Array or Uint8Array (see: https://developer.mozilla.org/en/JavaScript_typed_arrays) 54 55 (DataView is not supported yet) 56 57 output: MD5 hash (as Hex Uppercase String) 58*/ 59 60faultylabs.MD5 = function(data) { 61 62 // convert number to (unsigned) 32 bit hex, zero filled string 63 function to_zerofilled_hex(n) { 64 var t1 = (n >>> 0).toString(16) 65 return "00000000".substr(0, 8 - t1.length) + t1 66 } 67 68 // convert array of chars to array of bytes 69 function chars_to_bytes(ac) { 70 var retval = [] 71 for (var i = 0; i < ac.length; i++) { 72 retval = retval.concat(str_to_bytes(ac[i])) 73 } 74 return retval 75 } 76 77 78 // convert a 64 bit unsigned number to array of bytes. Little endian 79 function int64_to_bytes(num) { 80 var retval = [] 81 for (var i = 0; i < 8; i++) { 82 retval.push(num & 0xFF) 83 num = num >>> 8 84 } 85 return retval 86 } 87 88 // 32 bit left-rotation 89 function rol(num, places) { 90 return ((num << places) & 0xFFFFFFFF) | (num >>> (32 - places)) 91 } 92 93 // The 4 MD5 functions 94 function fF(b, c, d) { 95 return (b & c) | (~b & d) 96 } 97 98 function fG(b, c, d) { 99 return (d & b) | (~d & c) 100 } 101 102 function fH(b, c, d) { 103 return b ^ c ^ d 104 } 105 106 function fI(b, c, d) { 107 return c ^ (b | ~d) 108 } 109 110 // pick 4 bytes at specified offset. Little-endian is assumed 111 function bytes_to_int32(arr, off) { 112 return (arr[off + 3] << 24) | (arr[off + 2] << 16) | (arr[off + 1] << 8) | (arr[off]) 113 } 114 115 /* 116 Conver string to array of bytes in UTF-8 encoding 117 See: 118 http://www.dangrossman.info/2007/05/25/handling-utf-8-in-javascript-php-and-non-utf8-databases/ 119 http://stackoverflow.com/questions/1240408/reading-bytes-from-a-javascript-string 120 How about a String.getBytes(<ENCODING>) for Javascript!? Isn't it time to add it? 121 */ 122 function str_to_bytes(str) { 123 var retval = [ ] 124 for (var i = 0; i < str.length; i++) 125 if (str.charCodeAt(i) <= 0x7F) { 126 retval.push(str.charCodeAt(i)) 127 } else { 128 var tmp = encodeURIComponent(str.charAt(i)).substr(1).split('%') 129 for (var j = 0; j < tmp.length; j++) { 130 retval.push(parseInt(tmp[j], 0x10)) 131 } 132 } 133 return retval 134 } 135 136 137 // convert the 4 32-bit buffers to a 128 bit hex string. (Little-endian is assumed) 138 function int128le_to_hex(a, b, c, d) { 139 var ra = "" 140 var t = 0 141 var ta = 0 142 for (var i = 3; i >= 0; i--) { 143 ta = arguments[i] 144 t = (ta & 0xFF) 145 ta = ta >>> 8 146 t = t << 8 147 t = t | (ta & 0xFF) 148 ta = ta >>> 8 149 t = t << 8 150 t = t | (ta & 0xFF) 151 ta = ta >>> 8 152 t = t << 8 153 t = t | ta 154 ra = ra + to_zerofilled_hex(t) 155 } 156 return ra 157 } 158 159 // conversion from typed byte array to plain javascript array 160 function typed_to_plain(tarr) { 161 var retval = new Array(tarr.length) 162 for (var i = 0; i < tarr.length; i++) { 163 retval[i] = tarr[i] 164 } 165 return retval 166 } 167 168 // check input data type and perform conversions if needed 169 var databytes = null 170 // String 171 var type_mismatch = null 172 if (typeof data == 'string') { 173 // convert string to array bytes 174 databytes = str_to_bytes(data) 175 } else if (data.constructor == Array) { 176 if (data.length === 0) { 177 // if it's empty, just assume array of bytes 178 databytes = data 179 } else if (typeof data[0] == 'string') { 180 databytes = chars_to_bytes(data) 181 } else if (typeof data[0] == 'number') { 182 databytes = data 183 } else { 184 type_mismatch = typeof data[0] 185 } 186 } else if (typeof ArrayBuffer != 'undefined') { 187 if (data instanceof ArrayBuffer) { 188 databytes = typed_to_plain(new Uint8Array(data)) 189 } else if ((data instanceof Uint8Array) || (data instanceof Int8Array)) { 190 databytes = typed_to_plain(data) 191 } else if ((data instanceof Uint32Array) || (data instanceof Int32Array) || 192 (data instanceof Uint16Array) || (data instanceof Int16Array) || 193 (data instanceof Float32Array) || (data instanceof Float64Array) 194 ) { 195 databytes = typed_to_plain(new Uint8Array(data.buffer)) 196 } else { 197 type_mismatch = typeof data 198 } 199 } else { 200 type_mismatch = typeof data 201 } 202 203 if (type_mismatch) { 204 alert('MD5 type mismatch, cannot process ' + type_mismatch) 205 } 206 207 function _add(n1, n2) { 208 return 0x0FFFFFFFF & (n1 + n2) 209 } 210 211 212 return do_digest() 213 214 function do_digest() { 215 216 // function update partial state for each run 217 function updateRun(nf, sin32, dw32, b32) { 218 var temp = d 219 d = c 220 c = b 221 //b = b + rol(a + (nf + (sin32 + dw32)), b32) 222 b = _add(b, 223 rol( 224 _add(a, 225 _add(nf, _add(sin32, dw32)) 226 ), b32 227 ) 228 ) 229 a = temp 230 } 231 232 // save original length 233 var org_len = databytes.length 234 235 // first append the "1" + 7x "0" 236 databytes.push(0x80) 237 238 // determine required amount of padding 239 var tail = databytes.length % 64 240 // no room for msg length? 241 if (tail > 56) { 242 // pad to next 512 bit block 243 for (var i = 0; i < (64 - tail); i++) { 244 databytes.push(0x0) 245 } 246 tail = databytes.length % 64 247 } 248 for (i = 0; i < (56 - tail); i++) { 249 databytes.push(0x0) 250 } 251 // message length in bits mod 512 should now be 448 252 // append 64 bit, little-endian original msg length (in *bits*!) 253 databytes = databytes.concat(int64_to_bytes(org_len * 8)) 254 255 // initialize 4x32 bit state
256 var h0 = 0x67452301 257 var h1 = 0xEFCDAB89 258 var h2 = 0x98BADCFE 259 var h3 = 0x10325476 260 261 // temp buffers 262 var a = 0, b = 0, c = 0, d = 0 263 264 // Digest message 265 for (i = 0; i < databytes.length / 64; i++) { 266 // initialize run 267 a = h0 268 b = h1 269 c = h2 270 d = h3 271 272 var ptr = i * 64 273 274 // do 64 runs 275 updateRun(fF(b, c, d), 0xd76aa478, bytes_to_int32(databytes, ptr), 7) 276 updateRun(fF(b, c, d), 0xe8c7b756, bytes_to_int32(databytes, ptr + 4), 12) 277 updateRun(fF(b, c, d), 0x242070db, bytes_to_int32(databytes, ptr + 8), 17) 278 updateRun(fF(b, c, d), 0xc1bdceee, bytes_to_int32(databytes, ptr + 12), 22) 279 updateRun(fF(b, c, d), 0xf57c0faf, bytes_to_int32(databytes, ptr + 16), 7) 280 updateRun(fF(b, c, d), 0x4787c62a, bytes_to_int32(databytes, ptr + 20), 12) 281 updateRun(fF(b, c, d), 0xa8304613, bytes_to_int32(databytes, ptr + 24), 17) 282 updateRun(fF(b, c, d), 0xfd469501, bytes_to_int32(databytes, ptr + 28), 22) 283 updateRun(fF(b, c, d), 0x698098d8, bytes_to_int32(databytes, ptr + 32), 7) 284 updateRun(fF(b, c, d), 0x8b44f7af, bytes_to_int32(databytes, ptr + 36), 12) 285 updateRun(fF(b, c, d), 0xffff5bb1, bytes_to_int32(databytes, ptr + 40), 17) 286 updateRun(fF(b, c, d), 0x895cd7be, bytes_to_int32(databytes, ptr + 44), 22) 287 updateRun(fF(b, c, d), 0x6b901122, bytes_to_int32(databytes, ptr + 48), 7) 288 updateRun(fF(b, c, d), 0xfd987193, bytes_to_int32(databytes, ptr + 52), 12) 289 updateRun(fF(b, c, d), 0xa679438e, bytes_to_int32(databytes, ptr + 56), 17) 290 updateRun(fF(b, c, d), 0x49b40821, bytes_to_int32(databytes, ptr + 60), 22) 291 updateRun(fG(b, c, d), 0xf61e2562, bytes_to_int32(databytes, ptr + 4), 5) 292 updateRun(fG(b, c, d), 0xc040b340, bytes_to_int32(databytes, ptr + 24), 9) 293 updateRun(fG(b, c, d), 0x265e5a51, bytes_to_int32(databytes, ptr + 44), 14) 294 updateRun(fG(b, c, d), 0xe9b6c7aa, bytes_to_int32(databytes, ptr), 20) 295 updateRun(fG(b, c, d), 0xd62f105d, bytes_to_int32(databytes, ptr + 20), 5) 296 updateRun(fG(b, c, d), 0x2441453, bytes_to_int32(databytes, ptr + 40), 9) 297 updateRun(fG(b, c, d), 0xd8a1e681, bytes_to_int32(databytes, ptr + 60), 14) 298 updateRun(fG(b, c, d), 0xe7d3fbc8, bytes_to_int32(databytes, ptr + 16), 20) 299 updateRun(fG(b, c, d), 0x21e1cde6, bytes_to_int32(databytes, ptr + 36), 5) 300 updateRun(fG(b, c, d), 0xc33707d6, bytes_to_int32(databytes, ptr + 56), 9) 301 updateRun(fG(b, c, d), 0xf4d50d87, bytes_to_int32(databytes, ptr + 12), 14) 302 updateRun(fG(b, c, d), 0x455a14ed, bytes_to_int32(databytes, ptr + 32), 20) 303 updateRun(fG(b, c, d), 0xa9e3e905, bytes_to_int32(databytes, ptr + 52), 5) 304 updateRun(fG(b, c, d), 0xfcefa3f8, bytes_to_int32(databytes, ptr + 8), 9) 305 updateRun(fG(b, c, d), 0x676f02d9, bytes_to_int32(databytes, ptr + 28), 14) 306 updateRun(fG(b, c, d), 0x8d2a4c8a, bytes_to_int32(databytes, ptr + 48), 20) 307 updateRun(fH(b, c, d), 0xfffa3942, bytes_to_int32(databytes, ptr + 20), 4) 308 updateRun(fH(b, c, d), 0x8771f681, bytes_to_int32(databytes, ptr + 32), 11) 309 updateRun(fH(b, c, d), 0x6d9d6122, bytes_to_int32(databytes, ptr + 44), 16) 310 updateRun(fH(b, c, d), 0xfde5380c, bytes_to_int32(databytes, ptr + 56), 23) 311 updateRun(fH(b, c, d), 0xa4beea44, bytes_to_int32(databytes, ptr + 4), 4) 312 updateRun(fH(b, c, d), 0x4bdecfa9, bytes_to_int32(databytes, ptr + 16), 11) 313 updateRun(fH(b, c, d), 0xf6bb4b60, bytes_to_int32(databytes, ptr + 28), 16) 314 updateRun(fH(b, c, d), 0xbebfbc70, bytes_to_int32(databytes, ptr + 40), 23) 315 updateRun(fH(b, c, d), 0x289b7ec6, bytes_to_int32(databytes, ptr + 52), 4) 316 updateRun(fH(b, c, d), 0xeaa127fa, bytes_to_int32(databytes, ptr), 11) 317 updateRun(fH(b, c, d), 0xd4ef3085, bytes_to_int32(databytes, ptr + 12), 16) 318 updateRun(fH(b, c, d), 0x4881d05, bytes_to_int32(databytes, ptr + 24), 23) 319 updateRun(fH(b, c, d), 0xd9d4d039, bytes_to_int32(databytes, ptr + 36), 4) 320 updateRun(fH(b, c, d), 0xe6db99e5, bytes_to_int32(databytes, ptr + 48), 11) 321 updateRun(fH(b, c, d), 0x1fa27cf8, bytes_to_int32(databytes, ptr + 60), 16)
322 updateRun(fH(b, c, d), 0xc4ac5665, bytes_to_int32(databytes, ptr + 8), 23) 323 updateRun(fI(b, c, d), 0xf4292244, bytes_to_int32(databytes, ptr), 6) 324 updateRun(fI(b, c, d), 0x432aff97, bytes_to_int32(databytes, ptr + 28), 10) 325 updateRun(fI(b, c, d), 0xab9423a7, bytes_to_int32(databytes, ptr + 56), 15) 326 updateRun(fI(b, c, d), 0xfc93a039, bytes_to_int32(databytes, ptr + 20), 21) 327 updateRun(fI(b, c, d), 0x655b59c3, bytes_to_int32(databytes, ptr + 48), 6) 328 updateRun(fI(b, c, d), 0x8f0ccc92, bytes_to_int32(databytes, ptr + 12), 10) 329 updateRun(fI(b, c, d), 0xffeff47d, bytes_to_int32(databytes, ptr + 40), 15) 330 updateRun(fI(b, c, d), 0x85845dd1, bytes_to_int32(databytes, ptr + 4), 21) 331 updateRun(fI(b, c, d), 0x6fa87e4f, bytes_to_int32(databytes, ptr + 32), 6) 332 updateRun(fI(b, c, d), 0xfe2ce6e0, bytes_to_int32(databytes, ptr + 60), 10) 333 updateRun(fI(b, c, d), 0xa3014314, bytes_to_int32(databytes, ptr + 24), 15) 334 updateRun(fI(b, c, d), 0x4e0811a1, bytes_to_int32(databytes, ptr + 52), 21) 335 updateRun(fI(b, c, d), 0xf7537e82, bytes_to_int32(databytes, ptr + 16), 6) 336 updateRun(fI(b, c, d), 0xbd3af235, bytes_to_int32(databytes, ptr + 44), 10) 337 updateRun(fI(b, c, d), 0x2ad7d2bb, bytes_to_int32(databytes, ptr + 8), 15) 338 updateRun(fI(b, c, d), 0xeb86d391, bytes_to_int32(databytes, ptr + 36), 21) 339 340 // update buffers 341 h0 = _add(h0, a) 342 h1 = _add(h1, b) 343 h2 = _add(h2, c) 344 h3 = _add(h3, d) 345 } 346 // Done! Convert buffers to 128 bit (LE) 347 return int128le_to_hex(h3, h2, h1, h0).toUpperCase() 348 } 349 350 351} 352
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.