1 var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 2 var base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 3 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 5 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1); 6 7 function base64encode(str) { 8 var out, i, len; 9 var c1, c2, c3; 10 11 len = str.length; 12 i = 0; 13 out = ""; 14 while (i < len) { 15 c1 = str.charCodeAt(i++) & 0xff; 16 if (i == len) { 17 out += base64EncodeChars.charAt(c1 >> 2); 18 out += base64EncodeChars.charAt((c1 & 0x3) << 4); 19 out += "=="; 20 break; 21 } 22 c2 = str.charCodeAt(i++); 23 if (i == len) { 24 out += base64EncodeChars.charAt(c1 >> 2); 25 out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); 26 out += base64EncodeChars.charAt((c2 & 0xF) << 2); 27 out += "="; 28 break; 29 } 30 c3 = str.charCodeAt(i++); 31 out += base64EncodeChars.charAt(c1 >> 2); 32 out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); 33 out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)); 34 out += base64EncodeChars.charAt(c3 & 0x3F); 35 } 36 return out; 37 } 38 39 function base64decode(str) { 40 var c1, c2, c3, c4; 41 var i, len, out; 42 43 len = str.length; 44 i = 0; 45 out = ""; 46 while (i < len) { 47 /* c1 */ 48 do { 49 c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; 50 } while (i < len && c1 == -1); 51 if (c1 == -1) 52 break; 53 54 /* c2 */ 55 do { 56 c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; 57 } while (i < len && c2 == -1); 58 if (c2 == -1) 59 break; 60 61 out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); 62 63 /* c3 */ 64 do { 65 c3 = str.charCodeAt(i++) & 0xff; 66 if (c3 == 61) 67 return out; 68 c3 = base64DecodeChars[c3]; 69 } while (i < len && c3 == -1); 70 if (c3 == -1) 71 break; 72 73 out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); 74 75 /* c4 */ 76 do { 77 c4 = str.charCodeAt(i++) & 0xff; 78 if (c4 == 61) 79 return out; 80 c4 = base64DecodeChars[c4]; 81 } while (i < len && c4 == -1); 82 if (c4 == -1) 83 break; 84 out += String.fromCharCode(((c3 & 0x03) << 6) | c4); 85 } 86 return out; 87 }
function hexToBytes(hex) { for (var bytes = [], c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16)); return bytes; } function stringToBytes(str) { var ch, st, re = []; for (var i = 0; i < str.length; i++) { ch = str.charCodeAt(i); // get char st = []; // set up "stack" do { st.push(ch & 0xFF); // push byte to stack ch = ch >> 8; // shift value down by 1 byte } while (ch); // add stack contents to result // done because chars have "wrong" endianness re = re.concat(st.reverse()); } // return an array of bytes return re; } function wordToByteArray(wordArray) { var byteArray = [], word, i, j; for (i = 0; i < wordArray.length; ++i) { word = wordArray[i]; for (j = 3; j >= 0; --j) { byteArray.push((word >> 8 * j) & 0xFF); } } return byteArray; }
1 (function(factory) { 2 if (typeof exports === 'object') { 3 // Node/CommonJS 4 module.exports = factory(); 5 } else if (typeof define === 'function' && define.amd) { 6 // AMD 7 define(factory); 8 } else { 9 // Browser globals (with support for web workers) 10 var glob; 11 12 try { 13 glob = window; 14 } catch (e) { 15 glob = self; 16 } 17 18 glob.SparkMD5 = factory(); 19 } 20 }(function(undefined) { 21 22 'use strict'; 23 24 /* 25 * Fastest md5 implementation around (JKM md5). 26 * Credits: Joseph Myers 27 * 28 * @see http://www.myersdaily.org/joseph/javascript/md5-text.html 29 * @see http://jsperf.com/md5-shootout/7 30 */ 31 32 /* this function is much faster, 33 so if possible we use it. Some IEs 34 are the only ones I know of that 35 need the idiotic second function, 36 generated by an if clause. */ 37 var add32 = function(a, b) { 38 return (a + b) & 0xFFFFFFFF; 39 }, 40 hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; 41 42 43 function cmn(q, a, b, x, s, t) { 44 a = add32(add32(a, q), add32(x, t)); 45 return add32((a << s) | (a >>> (32 - s)), b); 46 } 47 48 function md5cycle(x, k) { 49 var a = x[0], 50 b = x[1], 51 c = x[2], 52 d = x[3]; 53 54 a += (b & c | ~b & d) + k[0] - 680876936 | 0; 55 a = (a << 7 | a >>> 25) + b | 0; 56 d += (a & b | ~a & c) + k[1] - 389564586 | 0; 57 d = (d << 12 | d >>> 20) + a | 0; 58 c += (d & a | ~d & b) + k[2] + 606105819 | 0; 59 c = (c << 17 | c >>> 15) + d | 0; 60 b += (c & d | ~c & a) + k[3] - 1044525330 | 0; 61 b = (b << 22 | b >>> 10) + c | 0; 62 a += (b & c | ~b & d) + k[4] - 176418897 | 0; 63 a = (a << 7 | a >>> 25) + b | 0; 64 d += (a & b | ~a & c) + k[5] + 1200080426 | 0; 65 d = (d << 12 | d >>> 20) + a | 0; 66 c += (d & a | ~d & b) + k[6] - 1473231341 | 0; 67 c = (c << 17 | c >>> 15) + d | 0; 68 b += (c & d | ~c & a) + k[7] - 45705983 | 0; 69 b = (b << 22 | b >>> 10) + c | 0; 70 a += (b & c | ~b & d) + k[8] + 1770035416 | 0; 71 a = (a << 7 | a >>> 25) + b | 0; 72 d += (a & b | ~a & c) + k[9] - 1958414417 | 0; 73 d = (d << 12 | d >>> 20) + a | 0; 74 c += (d & a | ~d & b) + k[10] - 42063 | 0; 75 c = (c << 17 | c >>> 15) + d | 0; 76 b += (c & d | ~c & a) + k[11] - 1990404162 | 0; 77 b = (b << 22 | b >>> 10) + c | 0; 78 a += (b & c | ~b & d) + k[12] + 1804603682 | 0; 79 a = (a << 7 | a >>> 25) + b | 0; 80 d += (a & b | ~a & c) + k[13] - 40341101 | 0; 81 d = (d << 12 | d >>> 20) + a | 0; 82 c += (d & a | ~d & b) + k[14] - 1502002290 | 0; 83 c = (c << 17 | c >>> 15) + d | 0; 84 b += (c & d | ~c & a) + k[15] + 1236535329 | 0; 85 b = (b << 22 | b >>> 10) + c | 0; 86 87 a += (b & d | c & ~d) + k[1] - 165796510 | 0; 88 a = (a << 5 | a >>> 27) + b | 0; 89 d += (a & c | b & ~c) + k[6] - 1069501632 | 0; 90 d = (d << 9 | d >>> 23) + a | 0; 91 c += (d & b | a & ~b) + k[11] + 643717713 | 0; 92 c = (c << 14 | c >>> 18) + d | 0; 93 b += (c & a | d & ~a) + k[0] - 373897302 | 0; 94 b = (b << 20 | b >>> 12) + c | 0; 95 a += (b & d | c & ~d) + k[5] - 701558691 | 0; 96 a = (a << 5 | a >>> 27) + b | 0; 97 d += (a & c | b & ~c) + k[10] + 38016083 | 0; 98 d = (d << 9 | d >>> 23) + a | 0; 99 c += (d & b | a & ~b) + k[15] - 660478335 | 0; 100 c = (c << 14 | c >>> 18) + d | 0; 101 b += (c & a | d & ~a) + k[4] - 405537848 | 0; 102 b = (b << 20 | b >>> 12) + c | 0; 103 a += (b & d | c & ~d) + k[9] + 568446438 | 0; 104 a = (a << 5 | a >>> 27) + b | 0; 105 d += (a & c | b & ~c) + k[14] - 1019803690 | 0; 106 d = (d << 9 | d >>> 23) + a | 0; 107 c += (d & b | a & ~b) + k[3] - 187363961 | 0; 108 c = (c << 14 | c >>> 18) + d | 0; 109 b += (c & a | d & ~a) + k[8] + 1163531501 | 0; 110 b = (b << 20 | b >>> 12) + c | 0; 111 a += (b & d | c & ~d) + k[13] - 1444681467 | 0; 112 a = (a << 5 | a >>> 27) + b | 0; 113 d += (a & c | b & ~c) + k[2] - 51403784 | 0; 114 d = (d << 9 | d >>> 23) + a | 0; 115 c += (d & b | a & ~b) + k[7] + 1735328473 | 0; 116 c = (c << 14 | c >>> 18) + d | 0; 117 b += (c & a | d & ~a) + k[12] - 1926607734 | 0; 118 b = (b << 20 | b >>> 12) + c | 0; 119 120 a += (b ^ c ^ d) + k[5] - 378558 | 0; 121 a = (a << 4 | a >>> 28) + b | 0; 122 d += (a ^ b ^ c) + k[8] - 2022574463 | 0; 123 d = (d << 11 | d >>> 21) + a | 0; 124 c += (d ^ a ^ b) + k[11] + 1839030562 | 0; 125 c = (c << 16 | c >>> 16) + d | 0; 126 b += (c ^ d ^ a) + k[14] - 35309556 | 0; 127 b = (b << 23 | b >>> 9) + c | 0; 128 a += (b ^ c ^ d) + k[1] - 1530992060 | 0; 129 a = (a << 4 | a >>> 28) + b | 0; 130 d += (a ^ b ^ c) + k[4] + 1272893353 | 0; 131 d = (d << 11 | d >>> 21) + a | 0; 132 c += (d ^ a ^ b) + k[7] - 155497632 | 0; 133 c = (c << 16 | c >>> 16) + d | 0; 134 b += (c ^ d ^ a) + k[10] - 1094730640 | 0; 135 b = (b << 23 | b >>> 9) + c | 0; 136 a += (b ^ c ^ d) + k[13] + 681279174 | 0; 137 a = (a << 4 | a >>> 28) + b | 0; 138 d += (a ^ b ^ c) + k[0] - 358537222 | 0; 139 d = (d << 11 | d >>> 21) + a | 0; 140 c += (d ^ a ^ b) + k[3] - 722521979 | 0; 141 c = (c << 16 | c >>> 16) + d | 0; 142 b += (c ^ d ^ a) + k[6] + 76029189 | 0; 143 b = (b << 23 | b >>> 9) + c | 0; 144 a += (b ^ c ^ d) + k[9] - 640364487 | 0; 145 a = (a << 4 | a >>> 28) + b | 0; 146 d += (a ^ b ^ c) + k[12] - 421815835 | 0; 147 d = (d << 11 | d >>> 21) + a | 0; 148 c += (d ^ a ^ b) + k[15] + 530742520 | 0; 149 c = (c << 16 | c >>> 16) + d | 0; 150 b += (c ^ d ^ a) + k[2] - 995338651 | 0; 151 b = (b << 23 | b >>> 9) + c | 0; 152 153 a += (c ^ (b | ~d)) + k[0] - 198630844 | 0; 154 a = (a << 6 | a >>> 26) + b | 0; 155 d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0; 156 d = (d << 10 | d >>> 22) + a | 0; 157 c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0; 158 c = (c << 15 | c >>> 17) + d | 0; 159 b += (d ^ (c | ~a)) + k[5] - 57434055 | 0; 160 b = (b << 21 | b >>> 11) + c | 0; 161 a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0; 162 a = (a << 6 | a >>> 26) + b | 0; 163 d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0; 164 d = (d << 10 | d >>> 22) + a | 0; 165 c += (a ^ (d | ~b)) + k[10] - 1051523 | 0; 166 c = (c << 15 | c >>> 17) + d | 0; 167 b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0; 168 b = (b << 21 | b >>> 11) + c | 0; 169 a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0; 170 a = (a << 6 | a >>> 26) + b | 0; 171 d += (b ^ (a | ~c)) + k[15] - 30611744 | 0; 172 d = (d << 10 | d >>> 22) + a | 0; 173 c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0; 174 c = (c << 15 | c >>> 17) + d | 0; 175 b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0; 176 b = (b << 21 | b >>> 11) + c | 0; 177 a += (c ^ (b | ~d)) + k[4] - 145523070 | 0; 178 a = (a << 6 | a >>> 26) + b | 0; 179 d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0; 180 d = (d << 10 | d >>> 22) + a | 0; 181 c += (a ^ (d | ~b)) + k[2] + 718787259 | 0; 182 c = (c << 15 | c >>> 17) + d | 0; 183 b += (d ^ (c | ~a)) + k[9] - 343485551 | 0; 184 b = (b << 21 | b >>> 11) + c | 0; 185 186 x[0] = a + x[0] | 0; 187 x[1] = b + x[1] | 0; 188 x[2] = c + x[2] | 0; 189 x[3] = d + x[3] | 0; 190 } 191 192 function md5blk(s) { 193 var md5blks = [], 194 i; /* Andy King said do it this way. */ 195 196 for (i = 0; i < 64; i += 4) { 197 md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); 198 } 199 return md5blks; 200 } 201 202 function md5blk_array(a) { 203 var md5blks = [], 204 i; /* Andy King said do it this way. */ 205 206 for (i = 0; i < 64; i += 4) { 207 md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24); 208 } 209 return md5blks; 210 } 211 212 function md51(s) { 213 var n = s.length, 214 state = [1732584193, -271733879, -1732584194, 271733878], 215 i, 216 length, 217 tail, 218 tmp, 219 lo, 220 hi; 221 222 for (i = 64; i <= n; i += 64) { 223 md5cycle(state, md5blk(s.substring(i - 64, i))); 224 } 225 s = s.substring(i - 64); 226 length = s.length; 227 tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 228 for (i = 0; i < length; i += 1) { 229 tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3); 230 } 231 tail[i >> 2] |= 0x80 << ((i % 4) << 3); 232 if (i > 55) { 233 md5cycle(state, tail); 234 for (i = 0; i < 16; i += 1) { 235 tail[i] = 0; 236 } 237 } 238 239 // Beware that the final length might not fit in 32 bits so we take care of that 240 tmp = n * 8; 241 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); 242 lo = parseInt(tmp[2], 16); 243 hi = parseInt(tmp[1], 16) || 0; 244 245 tail[14] = lo; 246 tail[15] = hi; 247 248 md5cycle(state, tail); 249 return state; 250 } 251 252 function md51_array(a) { 253 var n = a.length, 254 state = [1732584193, -271733879, -1732584194, 271733878], 255 i, 256 length, 257 tail, 258 tmp, 259 lo, 260 hi; 261 262 for (i = 64; i <= n; i += 64) { 263 md5cycle(state, md5blk_array(a.subarray(i - 64, i))); 264 } 265 266 // Not sure if it is a bug, however IE10 will always produce a sub array of length 1 267 // containing the last element of the parent array if the sub array specified starts 268 // beyond the length of the parent array - weird. 269 // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue 270 a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0); 271 272 length = a.length; 273 tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 274 for (i = 0; i < length; i += 1) { 275 tail[i >> 2] |= a[i] << ((i % 4) << 3); 276 } 277 278 tail[i >> 2] |= 0x80 << ((i % 4) << 3); 279 if (i > 55) { 280 md5cycle(state, tail); 281 for (i = 0; i < 16; i += 1) { 282 tail[i] = 0; 283 } 284 } 285 286 // Beware that the final length might not fit in 32 bits so we take care of that 287 tmp = n * 8; 288 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); 289 lo = parseInt(tmp[2], 16); 290 hi = parseInt(tmp[1], 16) || 0; 291 292 tail[14] = lo; 293 tail[15] = hi; 294 295 md5cycle(state, tail); 296 297 return state; 298 } 299 300 function rhex(n) { 301 var s = '', 302 j; 303 for (j = 0; j < 4; j += 1) { 304 s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; 305 } 306 return s; 307 } 308 309 function hex(x) { 310 var i; 311 for (i = 0; i < x.length; i += 1) { 312 x[i] = rhex(x[i]); 313 } 314 return x.join(''); 315 } 316 317 // In some cases the fast add32 function cannot be used.. 318 if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') { 319 add32 = function(x, y) { 320 var lsw = (x & 0xFFFF) + (y & 0xFFFF), 321 msw = (x >> 16) + (y >> 16) + (lsw >> 16); 322 return (msw << 16) | (lsw & 0xFFFF); 323 }; 324 } 325 326 // --------------------------------------------------- 327 328 /** 329 * ArrayBuffer slice polyfill. 330 * 331 * @see https://github.com/ttaubert/node-arraybuffer-slice 332 */ 333 334 if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) { 335 (function() { 336 function clamp(val, length) { 337 val = (val | 0) || 0; 338 339 if (val < 0) { 340 return Math.max(val + length, 0); 341 } 342 343 return Math.min(val, length); 344 } 345 346 ArrayBuffer.prototype.slice = function(from, to) { 347 var length = this.byteLength, 348 begin = clamp(from, length), 349 end = length, 350 num, 351 target, 352 targetArray, 353 sourceArray; 354 355 if (to !== undefined) { 356 end = clamp(to, length); 357 } 358 359 if (begin > end) { 360 return new ArrayBuffer(0); 361 } 362 363 num = end - begin; 364 target = new ArrayBuffer(num); 365 targetArray = new Uint8Array(target); 366 367 sourceArray = new Uint8Array(this, begin, num); 368 targetArray.set(sourceArray); 369 370 return target; 371 }; 372 })(); 373 } 374 375 // --------------------------------------------------- 376 377 /** 378 * Helpers. 379 */ 380 381 function toUtf8(str) { 382 if (/[u0080-uFFFF]/.test(str)) { 383 str = unescape(encodeURIComponent(str)); 384 } 385 386 return str; 387 } 388 389 function utf8Str2ArrayBuffer(str, returnUInt8Array) { 390 var length = str.length, 391 buff = new ArrayBuffer(length), 392 arr = new Uint8Array(buff), 393 i; 394 395 for (i = 0; i < length; i += 1) { 396 arr[i] = str.charCodeAt(i); 397 } 398 399 return returnUInt8Array ? arr : buff; 400 } 401 402 function arrayBuffer2Utf8Str(buff) { 403 return String.fromCharCode.apply(null, new Uint8Array(buff)); 404 } 405 406 function concatenateArrayBuffers(first, second, returnUInt8Array) { 407 var result = new Uint8Array(first.byteLength + second.byteLength); 408 409 result.set(new Uint8Array(first)); 410 result.set(new Uint8Array(second), first.byteLength); 411 412 return returnUInt8Array ? result : result.buffer; 413 } 414 415 function hexToBinaryString(hex) { 416 var bytes = [], 417 length = hex.length, 418 x; 419 420 for (x = 0; x < length - 1; x += 2) { 421 bytes.push(parseInt(hex.substr(x, 2), 16)); 422 } 423 424 return String.fromCharCode.apply(String, bytes); 425 } 426 427 // --------------------------------------------------- 428 429 /** 430 * SparkMD5 OOP implementation. 431 * 432 * Use this class to perform an incremental md5, otherwise use the 433 * static methods instead. 434 */ 435 436 function SparkMD5() { 437 // call reset to init the instance 438 this.reset(); 439 } 440 441 /** 442 * Appends a string. 443 * A conversion will be applied if an utf8 string is detected. 444 * 445 * @param {String} str The string to be appended 446 * 447 * @return {SparkMD5} The instance itself 448 */ 449 SparkMD5.prototype.append = function(str) { 450 // Converts the string to utf8 bytes if necessary 451 // Then append as binary 452 this.appendBinary(toUtf8(str)); 453 454 return this; 455 }; 456 457 /** 458 * Appends a binary string. 459 * 460 * @param {String} contents The binary string to be appended 461 * 462 * @return {SparkMD5} The instance itself 463 */ 464 SparkMD5.prototype.appendBinary = function(contents) { 465 this._buff += contents; 466 this._length += contents.length; 467 468 var length = this._buff.length, 469 i; 470 471 for (i = 64; i <= length; i += 64) { 472 md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i))); 473 } 474 475 this._buff = this._buff.substring(i - 64); 476 477 return this; 478 }; 479 480 /** 481 * Finishes the incremental computation, reseting the internal state and 482 * returning the result. 483 * 484 * @param {Boolean} raw True to get the raw string, false to get the hex string 485 * 486 * @return {String} The result 487 */ 488 SparkMD5.prototype.end = function(raw) { 489 var buff = this._buff, 490 length = buff.length, 491 i, 492 tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 493 ret; 494 495 for (i = 0; i < length; i += 1) { 496 tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3); 497 } 498 499 this._finish(tail, length); 500 ret = hex(this._hash); 501 502 if (raw) { 503 ret = hexToBinaryString(ret); 504 } 505 506 this.reset(); 507 508 return ret; 509 }; 510 511 /** 512 * Resets the internal state of the computation. 513 * 514 * @return {SparkMD5} The instance itself 515 */ 516 SparkMD5.prototype.reset = function() { 517 this._buff = ''; 518 this._length = 0; 519 this._hash = [1732584193, -271733879, -1732584194, 271733878]; 520 521 return this; 522 }; 523 524 /** 525 * Gets the internal state of the computation. 526 * 527 * @return {Object} The state 528 */ 529 SparkMD5.prototype.getState = function() { 530 return { 531 buff: this._buff, 532 length: this._length, 533 hash: this._hash 534 }; 535 }; 536 537 /** 538 * Gets the internal state of the computation. 539 * 540 * @param {Object} state The state 541 * 542 * @return {SparkMD5} The instance itself 543 */ 544 SparkMD5.prototype.setState = function(state) { 545 this._buff = state.buff; 546 this._length = state.length; 547 this._hash = state.hash; 548 549 return this; 550 }; 551 552 /** 553 * Releases memory used by the incremental buffer and other additional 554 * resources. If you plan to use the instance again, use reset instead. 555 */ 556 SparkMD5.prototype.destroy = function() { 557 delete this._hash; 558 delete this._buff; 559 delete this._length; 560 }; 561 562 /** 563 * Finish the final calculation based on the tail. 564 * 565 * @param {Array} tail The tail (will be modified) 566 * @param {Number} length The length of the remaining buffer 567 */ 568 SparkMD5.prototype._finish = function(tail, length) { 569 var i = length, 570 tmp, 571 lo, 572 hi; 573 574 tail[i >> 2] |= 0x80 << ((i % 4) << 3); 575 if (i > 55) { 576 md5cycle(this._hash, tail); 577 for (i = 0; i < 16; i += 1) { 578 tail[i] = 0; 579 } 580 } 581 582 // Do the final computation based on the tail and length 583 // Beware that the final length may not fit in 32 bits so we take care of that 584 tmp = this._length * 8; 585 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); 586 lo = parseInt(tmp[2], 16); 587 hi = parseInt(tmp[1], 16) || 0; 588 589 tail[14] = lo; 590 tail[15] = hi; 591 md5cycle(this._hash, tail); 592 }; 593 594 /** 595 * Performs the md5 hash on a string. 596 * A conversion will be applied if utf8 string is detected. 597 * 598 * @param {String} str The string 599 * @param {Boolean} [raw] True to get the raw string, false to get the hex string 600 * 601 * @return {String} The result 602 */ 603 SparkMD5.hash = function(str, raw) { 604 // Converts the string to utf8 bytes if necessary 605 // Then compute it using the binary function 606 return SparkMD5.hashBinary(toUtf8(str), raw); 607 }; 608 609 /** 610 * Performs the md5 hash on a binary string. 611 * 612 * @param {String} content The binary string 613 * @param {Boolean} [raw] True to get the raw string, false to get the hex string 614 * 615 * @return {String} The result 616 */ 617 SparkMD5.hashBinary = function(content, raw) { 618 var hash = md51(content), 619 ret = hex(hash); 620 621 return raw ? hexToBinaryString(ret) : ret; 622 }; 623 624 // --------------------------------------------------- 625 626 /** 627 * SparkMD5 OOP implementation for array buffers. 628 * 629 * Use this class to perform an incremental md5 ONLY for array buffers. 630 */ 631 SparkMD5.ArrayBuffer = function() { 632 // call reset to init the instance 633 this.reset(); 634 }; 635 636 /** 637 * Appends an array buffer. 638 * 639 * @param {ArrayBuffer} arr The array to be appended 640 * 641 * @return {SparkMD5.ArrayBuffer} The instance itself 642 */ 643 SparkMD5.ArrayBuffer.prototype.append = function(arr) { 644 var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), 645 length = buff.length, 646 i; 647 648 this._length += arr.byteLength; 649 650 for (i = 64; i <= length; i += 64) { 651 md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i))); 652 } 653 654 this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0); 655 656 return this; 657 }; 658 659 /** 660 * Finishes the incremental computation, reseting the internal state and 661 * returning the result. 662 * 663 * @param {Boolean} raw True to get the raw string, false to get the hex string 664 * 665 * @return {String} The result 666 */ 667 SparkMD5.ArrayBuffer.prototype.end = function(raw) { 668 var buff = this._buff, 669 length = buff.length, 670 tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 671 i, 672 ret; 673 674 for (i = 0; i < length; i += 1) { 675 tail[i >> 2] |= buff[i] << ((i % 4) << 3); 676 } 677 678 this._finish(tail, length); 679 ret = hex(this._hash); 680 681 if (raw) { 682 ret = hexToBinaryString(ret); 683 } 684 685 this.reset(); 686 687 return ret; 688 }; 689 690 /** 691 * Resets the internal state of the computation. 692 * 693 * @return {SparkMD5.ArrayBuffer} The instance itself 694 */ 695 SparkMD5.ArrayBuffer.prototype.reset = function() { 696 this._buff = new Uint8Array(0); 697 this._length = 0; 698 this._hash = [1732584193, -271733879, -1732584194, 271733878]; 699 700 return this; 701 }; 702 703 /** 704 * Gets the internal state of the computation. 705 * 706 * @return {Object} The state 707 */ 708 SparkMD5.ArrayBuffer.prototype.getState = function() { 709 var state = SparkMD5.prototype.getState.call(this); 710 711 // Convert buffer to a string 712 state.buff = arrayBuffer2Utf8Str(state.buff); 713 714 return state; 715 }; 716 717 /** 718 * Gets the internal state of the computation. 719 * 720 * @param {Object} state The state 721 * 722 * @return {SparkMD5.ArrayBuffer} The instance itself 723 */ 724 SparkMD5.ArrayBuffer.prototype.setState = function(state) { 725 // Convert string to buffer 726 state.buff = utf8Str2ArrayBuffer(state.buff, true); 727 728 return SparkMD5.prototype.setState.call(this, state); 729 }; 730 731 SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy; 732 733 SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish; 734 735 /** 736 * Performs the md5 hash on an array buffer. 737 * 738 * @param {ArrayBuffer} arr The array buffer 739 * @param {Boolean} [raw] True to get the raw string, false to get the hex one 740 * 741 * @return {String} The result 742 */ 743 SparkMD5.ArrayBuffer.hash = function(arr, raw) { 744 var hash = md51_array(new Uint8Array(arr)), 745 ret = hex(hash); 746 747 return raw ? hexToBinaryString(ret) : ret; 748 }; 749 750 return SparkMD5; 751 }));
/* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 * Version 2.1-BETA Copyright Paul Johnston 2000 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* 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 you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_sha1(s) { return binb2hex(core_sha1(str2binb(s), s.length * chrsz)); } function b64_sha1(s) { return binb2b64(core_sha1(str2binb(s), s.length * chrsz)); } function str_sha1(s) { return binb2str(core_sha1(str2binb(s), s.length * chrsz)); } function hex_hmac_sha1(key, data) { return binb2hex(core_hmac_sha1(key, data)); } function b64_hmac_sha1(key, data) { return binb2b64(core_hmac_sha1(key, data)); } function str_hmac_sha1(key, data) { return binb2str(core_hmac_sha1(key, data)); } /* * Perform a simple self-test to see if the VM is working */ function sha1_vm_test() { return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; } /* * Calculate the SHA-1 of an array of big-endian words, and a bit length */ function core_sha1(x, len) { /* append padding */ x[len >> 5] |= 0x80 << (24 - len % 32); x[((len + 64 >> 9) << 4) + 15] = len; var w = Array(80); var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var e = -1009589776; for (var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; var olde = e; for (var j = 0; j < 80; j++) { if (j < 16) w[j] = x[i + j]; else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); e = d; d = c; c = rol(b, 30); b = a; a = t; } a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); e = safe_add(e, olde); } return Array(a, b, c, d, e); } function reverse_word(x) { var a = (x[0] & 0xff) << 24 | (x[0] >> 8 & 0xff) << 16 | (x[0] >> 16 & 0xff) << 8 | (x[0] >> 24 & 0xff); var b = (x[1] & 0xff) << 24 | (x[1] >> 8 & 0xff) << 16 | (x[1] >> 16 & 0xff) << 8 | (x[1] >> 24 & 0xff); var c = (x[2] & 0xff) << 24 | (x[2] >> 8 & 0xff) << 16 | (x[2] >> 16 & 0xff) << 8 | (x[2] >> 24 & 0xff); var d = (x[3] & 0xff) << 24 | (x[3] >> 8 & 0xff) << 16 | (x[3] >> 16 & 0xff) << 8 | (x[3] >> 24 & 0xff); var e = (x[4] & 0xff) << 24 | (x[4] >> 8 & 0xff) << 16 | (x[4] >> 16 & 0xff) << 8 | (x[4] >> 24 & 0xff); return Array(a, b, c, d, e); } /* * Perform the appropriate triplet combination function for the current * iteration */ function sha1_ft(t, b, c, d) { if (t < 20) return (b & c) | ((~b) & d); if (t < 40) return b ^ c ^ d; if (t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d; } /* * Determine the appropriate additive constant for the current iteration */ function sha1_kt(t) { return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; } /* * Calculate the HMAC-SHA1 of a key and some data */ function core_hmac_sha1(key, data) { var bkey = str2binb(key); if (bkey.length > 16) bkey = core_sha1(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_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); return core_sha1(opad.concat(hash), 512 + 160); } /* * 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 rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * Convert an 8-bit or 16-bit string to an array of big-endian words * In 8-bit function, characters >255 have their hi-byte silently ignored. */ function str2binb(str) { var bin = Array(); var mask = (1 << chrsz) - 1; for (var i = 0; i < str.length * chrsz; i += chrsz) bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32); return bin; } /* * Convert an array of big-endian words to a string */ function binb2str(bin) { var str = ""; var mask = (1 << chrsz) - 1; for (var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & mask); return str; } /* * Convert an array of big-endian words to a hex string. */ function binb2hex(binarray) { var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for (var i = 0; i < binarray.length * 4; i++) { str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF); } return str; } /* * Convert an array of big-endian words to a base-64 string */ function binb2b64(binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = ""; for (var i = 0; i < binarray.length * 4; i += 3) { var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); for (var j = 0; j < 4; j++) { if (i * 8 + j * 6 > binarray.length * 32) str += b64pad; else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); } } return str; }
getCommonParamMap: function() { var _self = this; var map = {}; map.app_key = window.juli.ximalaya_app_key; map.device_id = window.juli.ximalaya_device_id; map.client_os_type = "3"; map.access_token = _self.getAccessToken(); console.log("getCommonParamMap"); console.log(map); }, getAccessToken: function() { var expireTime = localStorage.getItem(juli.ximalaya_expiresTimestamp); var currentTimeStamp = new Date().getTime(); if (expireTime === '' || expireTime === null || expireTime < currentTimeStamp) { this.getXimalayaToken(); } var token = localStorage.getItem(juli.ximalaya_tokenKey); if (token === '' || token === null) { //this.getXimalayaToken(); } return localStorage.getItem(juli.ximalaya_tokenKey); }, getXimalayaToken: function() { var _self = this; var url = "http://api.ximalaya.com/oauth2/secure_access_token?grant_type=client_credentials"; var params = "&sig=30a6d709d0a2aa45efb9154203bc664f&device_id=123456&nonce=1234567890&client_id=458d1314d02ce72f070dc31e7cd83dde×tamp=1516431468557"; //url += params; var currentTimestamp = new Date().getTime(); var map = {}; map.client_id = juli.ximalaya_app_key; map.grant_type = "client_credentials"; map.device_id = juli.ximalaya_device_id; map.nonce = this.getRandomString(10); map.timestamp = currentTimestamp; var sig = this.caculateSignature(juli.ximalaya_app_secret, map); console.log(sig + "-------"); map.sig = sig; var xhr = null; if (window.XMLHttpRequest) { xhr = window.XMLHttpRequest; } else if (window.ActiveXObject('Microsoft.XMLHTTP')) { // I do not know if this works xhr = window.ActiveXObject('Microsoft.XMLHTTP'); } var send = xhr.prototype.send; xhr.prototype.send = function(data) { try { //TODO: comment the next line console.log('pre send', data); send.call(this, data); //TODO: comment the next line console.log('pos send'); } catch (e) { //TODO: comment the next line console.log('err send', e); } }; var xhr = new XMLHttpRequest(); //设置xhr请求的超时时间 xhr.timeout = 3000; //设置响应返回的数据格式 xhr.responseType = "text"; //创建一个 post 请求,采用异步 xhr.open('POST', url, true); //注册相关事件回调处理函数 xhr.onload = function(e) { if (this.status == 200 || this.status == 304) { alert(this.responseText); } }; xhr.send(params); try { $.ajax({ url: url, type: 'POST', async: false, cache: false, contentType: 'application/json', dataType: 'json', data: { "sig": "30a6d709d0a2aa45efb9154203bc664f", "device_id": "123456", "nonce": "1234567890", "client_id": "458d1314d02ce72f070dc31e7cd83dde", "timestamp": "1516431468557" } //_self.getParamAppendString(map) }) .done(function(res) { console.log("ximalaya token: " + res); var obj = res.parseJSON(); console.log(obj.access_token); console.log(obj.expires_in); }) } catch (e) { console.log(e); } }, getRandomString: function(len) { len = len || 32; var $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; var maxPos = $chars.length; var pwd = ''; for (i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; }, caculateSignature: function(seed, map) { var params = ""; var list = []; for (var key in map) { list.push(key); } list.sort(); for (key in list) { console.log("list: " + list[key] + " : " + map[list[key]]); params += list[key] + "=" + map[list[key]] + "&"; } params = params.substring(0, params.length - 1); var paramsEncodeStr = base64encode(params); console.log("base64encode param: " + paramsEncodeStr); var sha1 = core_hmac_sha1(seed, paramsEncodeStr); var bytes = wordToByteArray(sha1); console.log("bytes: " + bytes); var spark = new SparkMD5.ArrayBuffer(); spark.append(new Uint8Array(bytes)); var sig = spark.end(); return sig; }, getParamAppendString: function(map) { var params = ""; for (var key in map) { console.log(key + " : " + map[key]); var value = map[key]; if (key == "q" || key == "tag_name") { value = encodeURI(encodeURI(map[key])); } params += key + "=" + value + "&"; } params = params.substring(0, params.length - 1); console.log(params); return params; }