spark-md5.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  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. try {
  12. glob = window;
  13. } catch (e) {
  14. glob = self;
  15. }
  16. glob.SparkMD5 = factory();
  17. }
  18. }(function (undefined) {
  19. 'use strict';
  20. /*
  21. * Fastest md5 implementation around (JKM md5).
  22. * Credits: Joseph Myers
  23. *
  24. * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
  25. * @see http://jsperf.com/md5-shootout/7
  26. */
  27. /* this function is much faster,
  28. so if possible we use it. Some IEs
  29. are the only ones I know of that
  30. need the idiotic second function,
  31. generated by an if clause. */
  32. var add32 = function (a, b) {
  33. return (a + b) & 0xFFFFFFFF;
  34. },
  35. hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
  36. function cmn(q, a, b, x, s, t) {
  37. a = add32(add32(a, q), add32(x, t));
  38. return add32((a << s) | (a >>> (32 - s)), b);
  39. }
  40. function md5cycle(x, k) {
  41. var a = x[0],
  42. b = x[1],
  43. c = x[2],
  44. d = x[3];
  45. a += (b & c | ~b & d) + k[0] - 680876936 | 0;
  46. a = (a << 7 | a >>> 25) + b | 0;
  47. d += (a & b | ~a & c) + k[1] - 389564586 | 0;
  48. d = (d << 12 | d >>> 20) + a | 0;
  49. c += (d & a | ~d & b) + k[2] + 606105819 | 0;
  50. c = (c << 17 | c >>> 15) + d | 0;
  51. b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
  52. b = (b << 22 | b >>> 10) + c | 0;
  53. a += (b & c | ~b & d) + k[4] - 176418897 | 0;
  54. a = (a << 7 | a >>> 25) + b | 0;
  55. d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
  56. d = (d << 12 | d >>> 20) + a | 0;
  57. c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
  58. c = (c << 17 | c >>> 15) + d | 0;
  59. b += (c & d | ~c & a) + k[7] - 45705983 | 0;
  60. b = (b << 22 | b >>> 10) + c | 0;
  61. a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
  62. a = (a << 7 | a >>> 25) + b | 0;
  63. d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
  64. d = (d << 12 | d >>> 20) + a | 0;
  65. c += (d & a | ~d & b) + k[10] - 42063 | 0;
  66. c = (c << 17 | c >>> 15) + d | 0;
  67. b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
  68. b = (b << 22 | b >>> 10) + c | 0;
  69. a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
  70. a = (a << 7 | a >>> 25) + b | 0;
  71. d += (a & b | ~a & c) + k[13] - 40341101 | 0;
  72. d = (d << 12 | d >>> 20) + a | 0;
  73. c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
  74. c = (c << 17 | c >>> 15) + d | 0;
  75. b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
  76. b = (b << 22 | b >>> 10) + c | 0;
  77. a += (b & d | c & ~d) + k[1] - 165796510 | 0;
  78. a = (a << 5 | a >>> 27) + b | 0;
  79. d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
  80. d = (d << 9 | d >>> 23) + a | 0;
  81. c += (d & b | a & ~b) + k[11] + 643717713 | 0;
  82. c = (c << 14 | c >>> 18) + d | 0;
  83. b += (c & a | d & ~a) + k[0] - 373897302 | 0;
  84. b = (b << 20 | b >>> 12) + c | 0;
  85. a += (b & d | c & ~d) + k[5] - 701558691 | 0;
  86. a = (a << 5 | a >>> 27) + b | 0;
  87. d += (a & c | b & ~c) + k[10] + 38016083 | 0;
  88. d = (d << 9 | d >>> 23) + a | 0;
  89. c += (d & b | a & ~b) + k[15] - 660478335 | 0;
  90. c = (c << 14 | c >>> 18) + d | 0;
  91. b += (c & a | d & ~a) + k[4] - 405537848 | 0;
  92. b = (b << 20 | b >>> 12) + c | 0;
  93. a += (b & d | c & ~d) + k[9] + 568446438 | 0;
  94. a = (a << 5 | a >>> 27) + b | 0;
  95. d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
  96. d = (d << 9 | d >>> 23) + a | 0;
  97. c += (d & b | a & ~b) + k[3] - 187363961 | 0;
  98. c = (c << 14 | c >>> 18) + d | 0;
  99. b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
  100. b = (b << 20 | b >>> 12) + c | 0;
  101. a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
  102. a = (a << 5 | a >>> 27) + b | 0;
  103. d += (a & c | b & ~c) + k[2] - 51403784 | 0;
  104. d = (d << 9 | d >>> 23) + a | 0;
  105. c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
  106. c = (c << 14 | c >>> 18) + d | 0;
  107. b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
  108. b = (b << 20 | b >>> 12) + c | 0;
  109. a += (b ^ c ^ d) + k[5] - 378558 | 0;
  110. a = (a << 4 | a >>> 28) + b | 0;
  111. d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
  112. d = (d << 11 | d >>> 21) + a | 0;
  113. c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
  114. c = (c << 16 | c >>> 16) + d | 0;
  115. b += (c ^ d ^ a) + k[14] - 35309556 | 0;
  116. b = (b << 23 | b >>> 9) + c | 0;
  117. a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
  118. a = (a << 4 | a >>> 28) + b | 0;
  119. d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
  120. d = (d << 11 | d >>> 21) + a | 0;
  121. c += (d ^ a ^ b) + k[7] - 155497632 | 0;
  122. c = (c << 16 | c >>> 16) + d | 0;
  123. b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
  124. b = (b << 23 | b >>> 9) + c | 0;
  125. a += (b ^ c ^ d) + k[13] + 681279174 | 0;
  126. a = (a << 4 | a >>> 28) + b | 0;
  127. d += (a ^ b ^ c) + k[0] - 358537222 | 0;
  128. d = (d << 11 | d >>> 21) + a | 0;
  129. c += (d ^ a ^ b) + k[3] - 722521979 | 0;
  130. c = (c << 16 | c >>> 16) + d | 0;
  131. b += (c ^ d ^ a) + k[6] + 76029189 | 0;
  132. b = (b << 23 | b >>> 9) + c | 0;
  133. a += (b ^ c ^ d) + k[9] - 640364487 | 0;
  134. a = (a << 4 | a >>> 28) + b | 0;
  135. d += (a ^ b ^ c) + k[12] - 421815835 | 0;
  136. d = (d << 11 | d >>> 21) + a | 0;
  137. c += (d ^ a ^ b) + k[15] + 530742520 | 0;
  138. c = (c << 16 | c >>> 16) + d | 0;
  139. b += (c ^ d ^ a) + k[2] - 995338651 | 0;
  140. b = (b << 23 | b >>> 9) + c | 0;
  141. a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
  142. a = (a << 6 | a >>> 26) + b | 0;
  143. d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
  144. d = (d << 10 | d >>> 22) + a | 0;
  145. c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
  146. c = (c << 15 | c >>> 17) + d | 0;
  147. b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
  148. b = (b << 21 |b >>> 11) + c | 0;
  149. a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
  150. a = (a << 6 | a >>> 26) + b | 0;
  151. d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
  152. d = (d << 10 | d >>> 22) + a | 0;
  153. c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
  154. c = (c << 15 | c >>> 17) + d | 0;
  155. b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
  156. b = (b << 21 |b >>> 11) + c | 0;
  157. a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
  158. a = (a << 6 | a >>> 26) + b | 0;
  159. d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
  160. d = (d << 10 | d >>> 22) + a | 0;
  161. c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
  162. c = (c << 15 | c >>> 17) + d | 0;
  163. b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
  164. b = (b << 21 |b >>> 11) + c | 0;
  165. a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
  166. a = (a << 6 | a >>> 26) + b | 0;
  167. d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
  168. d = (d << 10 | d >>> 22) + a | 0;
  169. c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
  170. c = (c << 15 | c >>> 17) + d | 0;
  171. b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
  172. b = (b << 21 | b >>> 11) + c | 0;
  173. x[0] = a + x[0] | 0;
  174. x[1] = b + x[1] | 0;
  175. x[2] = c + x[2] | 0;
  176. x[3] = d + x[3] | 0;
  177. }
  178. function md5blk(s) {
  179. var md5blks = [],
  180. i; /* Andy King said do it this way. */
  181. for (i = 0; i < 64; i += 4) {
  182. md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
  183. }
  184. return md5blks;
  185. }
  186. function md5blk_array(a) {
  187. var md5blks = [],
  188. i; /* Andy King said do it this way. */
  189. for (i = 0; i < 64; i += 4) {
  190. md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
  191. }
  192. return md5blks;
  193. }
  194. function md51(s) {
  195. var n = s.length,
  196. state = [1732584193, -271733879, -1732584194, 271733878],
  197. i,
  198. length,
  199. tail,
  200. tmp,
  201. lo,
  202. hi;
  203. for (i = 64; i <= n; i += 64) {
  204. md5cycle(state, md5blk(s.substring(i - 64, i)));
  205. }
  206. s = s.substring(i - 64);
  207. length = s.length;
  208. tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  209. for (i = 0; i < length; i += 1) {
  210. tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
  211. }
  212. tail[i >> 2] |= 0x80 << ((i % 4) << 3);
  213. if (i > 55) {
  214. md5cycle(state, tail);
  215. for (i = 0; i < 16; i += 1) {
  216. tail[i] = 0;
  217. }
  218. }
  219. // Beware that the final length might not fit in 32 bits so we take care of that
  220. tmp = n * 8;
  221. tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
  222. lo = parseInt(tmp[2], 16);
  223. hi = parseInt(tmp[1], 16) || 0;
  224. tail[14] = lo;
  225. tail[15] = hi;
  226. md5cycle(state, tail);
  227. return state;
  228. }
  229. function md51_array(a) {
  230. var n = a.length,
  231. state = [1732584193, -271733879, -1732584194, 271733878],
  232. i,
  233. length,
  234. tail,
  235. tmp,
  236. lo,
  237. hi;
  238. for (i = 64; i <= n; i += 64) {
  239. md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
  240. }
  241. // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
  242. // containing the last element of the parent array if the sub array specified starts
  243. // beyond the length of the parent array - weird.
  244. // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
  245. a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
  246. length = a.length;
  247. tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  248. for (i = 0; i < length; i += 1) {
  249. tail[i >> 2] |= a[i] << ((i % 4) << 3);
  250. }
  251. tail[i >> 2] |= 0x80 << ((i % 4) << 3);
  252. if (i > 55) {
  253. md5cycle(state, tail);
  254. for (i = 0; i < 16; i += 1) {
  255. tail[i] = 0;
  256. }
  257. }
  258. // Beware that the final length might not fit in 32 bits so we take care of that
  259. tmp = n * 8;
  260. tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
  261. lo = parseInt(tmp[2], 16);
  262. hi = parseInt(tmp[1], 16) || 0;
  263. tail[14] = lo;
  264. tail[15] = hi;
  265. md5cycle(state, tail);
  266. return state;
  267. }
  268. function rhex(n) {
  269. var s = '',
  270. j;
  271. for (j = 0; j < 4; j += 1) {
  272. s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
  273. }
  274. return s;
  275. }
  276. function hex(x) {
  277. var i;
  278. for (i = 0; i < x.length; i += 1) {
  279. x[i] = rhex(x[i]);
  280. }
  281. return x.join('');
  282. }
  283. // In some cases the fast add32 function cannot be used..
  284. if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
  285. add32 = function (x, y) {
  286. var lsw = (x & 0xFFFF) + (y & 0xFFFF),
  287. msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  288. return (msw << 16) | (lsw & 0xFFFF);
  289. };
  290. }
  291. // ---------------------------------------------------
  292. /**
  293. * ArrayBuffer slice polyfill.
  294. *
  295. * @see https://github.com/ttaubert/node-arraybuffer-slice
  296. */
  297. if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
  298. (function () {
  299. function clamp(val, length) {
  300. val = (val | 0) || 0;
  301. if (val < 0) {
  302. return Math.max(val + length, 0);
  303. }
  304. return Math.min(val, length);
  305. }
  306. ArrayBuffer.prototype.slice = function (from, to) {
  307. var length = this.byteLength,
  308. begin = clamp(from, length),
  309. end = length,
  310. num,
  311. target,
  312. targetArray,
  313. sourceArray;
  314. if (to !== undefined) {
  315. end = clamp(to, length);
  316. }
  317. if (begin > end) {
  318. return new ArrayBuffer(0);
  319. }
  320. num = end - begin;
  321. target = new ArrayBuffer(num);
  322. targetArray = new Uint8Array(target);
  323. sourceArray = new Uint8Array(this, begin, num);
  324. targetArray.set(sourceArray);
  325. return target;
  326. };
  327. })();
  328. }
  329. // ---------------------------------------------------
  330. /**
  331. * Helpers.
  332. */
  333. function toUtf8(str) {
  334. if (/[\u0080-\uFFFF]/.test(str)) {
  335. str = unescape(encodeURIComponent(str));
  336. }
  337. return str;
  338. }
  339. function utf8Str2ArrayBuffer(str, returnUInt8Array) {
  340. var length = str.length,
  341. buff = new ArrayBuffer(length),
  342. arr = new Uint8Array(buff),
  343. i;
  344. for (i = 0; i < length; i += 1) {
  345. arr[i] = str.charCodeAt(i);
  346. }
  347. return returnUInt8Array ? arr : buff;
  348. }
  349. function arrayBuffer2Utf8Str(buff) {
  350. return String.fromCharCode.apply(null, new Uint8Array(buff));
  351. }
  352. function concatenateArrayBuffers(first, second, returnUInt8Array) {
  353. var result = new Uint8Array(first.byteLength + second.byteLength);
  354. result.set(new Uint8Array(first));
  355. result.set(new Uint8Array(second), first.byteLength);
  356. return returnUInt8Array ? result : result.buffer;
  357. }
  358. function hexToBinaryString(hex) {
  359. var bytes = [],
  360. length = hex.length,
  361. x;
  362. for (x = 0; x < length - 1; x += 2) {
  363. bytes.push(parseInt(hex.substr(x, 2), 16));
  364. }
  365. return String.fromCharCode.apply(String, bytes);
  366. }
  367. // ---------------------------------------------------
  368. /**
  369. * SparkMD5 OOP implementation.
  370. *
  371. * Use this class to perform an incremental md5, otherwise use the
  372. * static methods instead.
  373. */
  374. function SparkMD5() {
  375. // call reset to init the instance
  376. this.reset();
  377. }
  378. /**
  379. * Appends a string.
  380. * A conversion will be applied if an utf8 string is detected.
  381. *
  382. * @param {String} str The string to be appended
  383. *
  384. * @return {SparkMD5} The instance itself
  385. */
  386. SparkMD5.prototype.append = function (str) {
  387. // Converts the string to utf8 bytes if necessary
  388. // Then append as binary
  389. this.appendBinary(toUtf8(str));
  390. return this;
  391. };
  392. /**
  393. * Appends a binary string.
  394. *
  395. * @param {String} contents The binary string to be appended
  396. *
  397. * @return {SparkMD5} The instance itself
  398. */
  399. SparkMD5.prototype.appendBinary = function (contents) {
  400. this._buff += contents;
  401. this._length += contents.length;
  402. var length = this._buff.length,
  403. i;
  404. for (i = 64; i <= length; i += 64) {
  405. md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
  406. }
  407. this._buff = this._buff.substring(i - 64);
  408. return this;
  409. };
  410. /**
  411. * Finishes the incremental computation, reseting the internal state and
  412. * returning the result.
  413. *
  414. * @param {Boolean} raw True to get the raw string, false to get the hex string
  415. *
  416. * @return {String} The result
  417. */
  418. SparkMD5.prototype.end = function (raw) {
  419. var buff = this._buff,
  420. length = buff.length,
  421. i,
  422. tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  423. ret;
  424. for (i = 0; i < length; i += 1) {
  425. tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
  426. }
  427. this._finish(tail, length);
  428. ret = hex(this._hash);
  429. if (raw) {
  430. ret = hexToBinaryString(ret);
  431. }
  432. this.reset();
  433. return ret;
  434. };
  435. /**
  436. * Resets the internal state of the computation.
  437. *
  438. * @return {SparkMD5} The instance itself
  439. */
  440. SparkMD5.prototype.reset = function () {
  441. this._buff = '';
  442. this._length = 0;
  443. this._hash = [1732584193, -271733879, -1732584194, 271733878];
  444. return this;
  445. };
  446. /**
  447. * Gets the internal state of the computation.
  448. *
  449. * @return {Object} The state
  450. */
  451. SparkMD5.prototype.getState = function () {
  452. return {
  453. buff: this._buff,
  454. length: this._length,
  455. hash: this._hash
  456. };
  457. };
  458. /**
  459. * Gets the internal state of the computation.
  460. *
  461. * @param {Object} state The state
  462. *
  463. * @return {SparkMD5} The instance itself
  464. */
  465. SparkMD5.prototype.setState = function (state) {
  466. this._buff = state.buff;
  467. this._length = state.length;
  468. this._hash = state.hash;
  469. return this;
  470. };
  471. /**
  472. * Releases memory used by the incremental buffer and other additional
  473. * resources. If you plan to use the instance again, use reset instead.
  474. */
  475. SparkMD5.prototype.destroy = function () {
  476. delete this._hash;
  477. delete this._buff;
  478. delete this._length;
  479. };
  480. /**
  481. * Finish the final calculation based on the tail.
  482. *
  483. * @param {Array} tail The tail (will be modified)
  484. * @param {Number} length The length of the remaining buffer
  485. */
  486. SparkMD5.prototype._finish = function (tail, length) {
  487. var i = length,
  488. tmp,
  489. lo,
  490. hi;
  491. tail[i >> 2] |= 0x80 << ((i % 4) << 3);
  492. if (i > 55) {
  493. md5cycle(this._hash, tail);
  494. for (i = 0; i < 16; i += 1) {
  495. tail[i] = 0;
  496. }
  497. }
  498. // Do the final computation based on the tail and length
  499. // Beware that the final length may not fit in 32 bits so we take care of that
  500. tmp = this._length * 8;
  501. tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
  502. lo = parseInt(tmp[2], 16);
  503. hi = parseInt(tmp[1], 16) || 0;
  504. tail[14] = lo;
  505. tail[15] = hi;
  506. md5cycle(this._hash, tail);
  507. };
  508. /**
  509. * Performs the md5 hash on a string.
  510. * A conversion will be applied if utf8 string is detected.
  511. *
  512. * @param {String} str The string
  513. * @param {Boolean} [raw] True to get the raw string, false to get the hex string
  514. *
  515. * @return {String} The result
  516. */
  517. SparkMD5.hash = function (str, raw) {
  518. // Converts the string to utf8 bytes if necessary
  519. // Then compute it using the binary function
  520. return SparkMD5.hashBinary(toUtf8(str), raw);
  521. };
  522. /**
  523. * Performs the md5 hash on a binary string.
  524. *
  525. * @param {String} content The binary string
  526. * @param {Boolean} [raw] True to get the raw string, false to get the hex string
  527. *
  528. * @return {String} The result
  529. */
  530. SparkMD5.hashBinary = function (content, raw) {
  531. var hash = md51(content),
  532. ret = hex(hash);
  533. return raw ? hexToBinaryString(ret) : ret;
  534. };
  535. // ---------------------------------------------------
  536. /**
  537. * SparkMD5 OOP implementation for array buffers.
  538. *
  539. * Use this class to perform an incremental md5 ONLY for array buffers.
  540. */
  541. SparkMD5.ArrayBuffer = function () {
  542. // call reset to init the instance
  543. this.reset();
  544. };
  545. /**
  546. * Appends an array buffer.
  547. *
  548. * @param {ArrayBuffer} arr The array to be appended
  549. *
  550. * @return {SparkMD5.ArrayBuffer} The instance itself
  551. */
  552. SparkMD5.ArrayBuffer.prototype.append = function (arr) {
  553. var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
  554. length = buff.length,
  555. i;
  556. this._length += arr.byteLength;
  557. for (i = 64; i <= length; i += 64) {
  558. md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
  559. }
  560. this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
  561. return this;
  562. };
  563. /**
  564. * Finishes the incremental computation, reseting the internal state and
  565. * returning the result.
  566. *
  567. * @param {Boolean} raw True to get the raw string, false to get the hex string
  568. *
  569. * @return {String} The result
  570. */
  571. SparkMD5.ArrayBuffer.prototype.end = function (raw) {
  572. var buff = this._buff,
  573. length = buff.length,
  574. tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  575. i,
  576. ret;
  577. for (i = 0; i < length; i += 1) {
  578. tail[i >> 2] |= buff[i] << ((i % 4) << 3);
  579. }
  580. this._finish(tail, length);
  581. ret = hex(this._hash);
  582. if (raw) {
  583. ret = hexToBinaryString(ret);
  584. }
  585. this.reset();
  586. return ret;
  587. };
  588. /**
  589. * Resets the internal state of the computation.
  590. *
  591. * @return {SparkMD5.ArrayBuffer} The instance itself
  592. */
  593. SparkMD5.ArrayBuffer.prototype.reset = function () {
  594. this._buff = new Uint8Array(0);
  595. this._length = 0;
  596. this._hash = [1732584193, -271733879, -1732584194, 271733878];
  597. return this;
  598. };
  599. /**
  600. * Gets the internal state of the computation.
  601. *
  602. * @return {Object} The state
  603. */
  604. SparkMD5.ArrayBuffer.prototype.getState = function () {
  605. var state = SparkMD5.prototype.getState.call(this);
  606. // Convert buffer to a string
  607. state.buff = arrayBuffer2Utf8Str(state.buff);
  608. return state;
  609. };
  610. /**
  611. * Gets the internal state of the computation.
  612. *
  613. * @param {Object} state The state
  614. *
  615. * @return {SparkMD5.ArrayBuffer} The instance itself
  616. */
  617. SparkMD5.ArrayBuffer.prototype.setState = function (state) {
  618. // Convert string to buffer
  619. state.buff = utf8Str2ArrayBuffer(state.buff, true);
  620. return SparkMD5.prototype.setState.call(this, state);
  621. };
  622. SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
  623. SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
  624. /**
  625. * Performs the md5 hash on an array buffer.
  626. *
  627. * @param {ArrayBuffer} arr The array buffer
  628. * @param {Boolean} [raw] True to get the raw string, false to get the hex one
  629. *
  630. * @return {String} The result
  631. */
  632. SparkMD5.ArrayBuffer.hash = function (arr, raw) {
  633. var hash = md51_array(new Uint8Array(arr)),
  634. ret = hex(hash);
  635. return raw ? hexToBinaryString(ret) : ret;
  636. };
  637. return SparkMD5;
  638. }));