UNPKG

15.6 kBJavaScriptView Raw
1/*
2
3TypeScript Md5
4==============
5
6Based on work by
7* Joseph Myers: http://www.myersdaily.org/joseph/javascript/md5-text.html
8* André Cruz: https://github.com/satazor/SparkMD5
9* Raymond Hill: https://github.com/gorhill/yamd5.js
10
11Effectively a TypeScrypt re-write of Raymond Hill JS Library
12
13The MIT License (MIT)
14
15Copyright (C) 2014 Raymond Hill
16
17Permission is hereby granted, free of charge, to any person obtaining a copy
18of this software and associated documentation files (the "Software"), to deal
19in the Software without restriction, including without limitation the rights
20to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21copies of the Software, and to permit persons to whom the Software is
22furnished to do so, subject to the following conditions:
23
24The above copyright notice and this permission notice shall be included in
25all copies or substantial portions of the Software.
26
27THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33THE SOFTWARE.
34
35
36
37 DO WHAT YOU WANT TO PUBLIC LICENSE
38 Version 2, December 2004
39
40 Copyright (C) 2015 André Cruz <amdfcruz@gmail.com>
41
42 Everyone is permitted to copy and distribute verbatim or modified
43 copies of this license document, and changing it is allowed as long
44 as the name is changed.
45
46 DO WHAT YOU WANT TO PUBLIC LICENSE
47 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
48
49 0. You just DO WHAT YOU WANT TO.
50
51
52*/
53;
54export class Md5 {
55 constructor() {
56 this._dataLength = 0;
57 this._bufferLength = 0;
58 this._state = new Int32Array(4);
59 this._buffer = new ArrayBuffer(68);
60 this._buffer8 = new Uint8Array(this._buffer, 0, 68);
61 this._buffer32 = new Uint32Array(this._buffer, 0, 17);
62 this.start();
63 }
64 static hashStr(str, raw = false) {
65 return this.onePassHasher
66 .start()
67 .appendStr(str)
68 .end(raw);
69 }
70 static hashAsciiStr(str, raw = false) {
71 return this.onePassHasher
72 .start()
73 .appendAsciiStr(str)
74 .end(raw);
75 }
76 static _hex(x) {
77 const hc = Md5.hexChars;
78 const ho = Md5.hexOut;
79 let n;
80 let offset;
81 let j;
82 let i;
83 for (i = 0; i < 4; i += 1) {
84 offset = i * 8;
85 n = x[i];
86 for (j = 0; j < 8; j += 2) {
87 ho[offset + 1 + j] = hc.charAt(n & 0x0F);
88 n >>>= 4;
89 ho[offset + 0 + j] = hc.charAt(n & 0x0F);
90 n >>>= 4;
91 }
92 }
93 return ho.join('');
94 }
95 static _md5cycle(x, k) {
96 let a = x[0];
97 let b = x[1];
98 let c = x[2];
99 let d = x[3];
100 // ff()
101 a += (b & c | ~b & d) + k[0] - 680876936 | 0;
102 a = (a << 7 | a >>> 25) + b | 0;
103 d += (a & b | ~a & c) + k[1] - 389564586 | 0;
104 d = (d << 12 | d >>> 20) + a | 0;
105 c += (d & a | ~d & b) + k[2] + 606105819 | 0;
106 c = (c << 17 | c >>> 15) + d | 0;
107 b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
108 b = (b << 22 | b >>> 10) + c | 0;
109 a += (b & c | ~b & d) + k[4] - 176418897 | 0;
110 a = (a << 7 | a >>> 25) + b | 0;
111 d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
112 d = (d << 12 | d >>> 20) + a | 0;
113 c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
114 c = (c << 17 | c >>> 15) + d | 0;
115 b += (c & d | ~c & a) + k[7] - 45705983 | 0;
116 b = (b << 22 | b >>> 10) + c | 0;
117 a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
118 a = (a << 7 | a >>> 25) + b | 0;
119 d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
120 d = (d << 12 | d >>> 20) + a | 0;
121 c += (d & a | ~d & b) + k[10] - 42063 | 0;
122 c = (c << 17 | c >>> 15) + d | 0;
123 b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
124 b = (b << 22 | b >>> 10) + c | 0;
125 a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
126 a = (a << 7 | a >>> 25) + b | 0;
127 d += (a & b | ~a & c) + k[13] - 40341101 | 0;
128 d = (d << 12 | d >>> 20) + a | 0;
129 c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
130 c = (c << 17 | c >>> 15) + d | 0;
131 b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
132 b = (b << 22 | b >>> 10) + c | 0;
133 // gg()
134 a += (b & d | c & ~d) + k[1] - 165796510 | 0;
135 a = (a << 5 | a >>> 27) + b | 0;
136 d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
137 d = (d << 9 | d >>> 23) + a | 0;
138 c += (d & b | a & ~b) + k[11] + 643717713 | 0;
139 c = (c << 14 | c >>> 18) + d | 0;
140 b += (c & a | d & ~a) + k[0] - 373897302 | 0;
141 b = (b << 20 | b >>> 12) + c | 0;
142 a += (b & d | c & ~d) + k[5] - 701558691 | 0;
143 a = (a << 5 | a >>> 27) + b | 0;
144 d += (a & c | b & ~c) + k[10] + 38016083 | 0;
145 d = (d << 9 | d >>> 23) + a | 0;
146 c += (d & b | a & ~b) + k[15] - 660478335 | 0;
147 c = (c << 14 | c >>> 18) + d | 0;
148 b += (c & a | d & ~a) + k[4] - 405537848 | 0;
149 b = (b << 20 | b >>> 12) + c | 0;
150 a += (b & d | c & ~d) + k[9] + 568446438 | 0;
151 a = (a << 5 | a >>> 27) + b | 0;
152 d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
153 d = (d << 9 | d >>> 23) + a | 0;
154 c += (d & b | a & ~b) + k[3] - 187363961 | 0;
155 c = (c << 14 | c >>> 18) + d | 0;
156 b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
157 b = (b << 20 | b >>> 12) + c | 0;
158 a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
159 a = (a << 5 | a >>> 27) + b | 0;
160 d += (a & c | b & ~c) + k[2] - 51403784 | 0;
161 d = (d << 9 | d >>> 23) + a | 0;
162 c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
163 c = (c << 14 | c >>> 18) + d | 0;
164 b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
165 b = (b << 20 | b >>> 12) + c | 0;
166 // hh()
167 a += (b ^ c ^ d) + k[5] - 378558 | 0;
168 a = (a << 4 | a >>> 28) + b | 0;
169 d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
170 d = (d << 11 | d >>> 21) + a | 0;
171 c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
172 c = (c << 16 | c >>> 16) + d | 0;
173 b += (c ^ d ^ a) + k[14] - 35309556 | 0;
174 b = (b << 23 | b >>> 9) + c | 0;
175 a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
176 a = (a << 4 | a >>> 28) + b | 0;
177 d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
178 d = (d << 11 | d >>> 21) + a | 0;
179 c += (d ^ a ^ b) + k[7] - 155497632 | 0;
180 c = (c << 16 | c >>> 16) + d | 0;
181 b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
182 b = (b << 23 | b >>> 9) + c | 0;
183 a += (b ^ c ^ d) + k[13] + 681279174 | 0;
184 a = (a << 4 | a >>> 28) + b | 0;
185 d += (a ^ b ^ c) + k[0] - 358537222 | 0;
186 d = (d << 11 | d >>> 21) + a | 0;
187 c += (d ^ a ^ b) + k[3] - 722521979 | 0;
188 c = (c << 16 | c >>> 16) + d | 0;
189 b += (c ^ d ^ a) + k[6] + 76029189 | 0;
190 b = (b << 23 | b >>> 9) + c | 0;
191 a += (b ^ c ^ d) + k[9] - 640364487 | 0;
192 a = (a << 4 | a >>> 28) + b | 0;
193 d += (a ^ b ^ c) + k[12] - 421815835 | 0;
194 d = (d << 11 | d >>> 21) + a | 0;
195 c += (d ^ a ^ b) + k[15] + 530742520 | 0;
196 c = (c << 16 | c >>> 16) + d | 0;
197 b += (c ^ d ^ a) + k[2] - 995338651 | 0;
198 b = (b << 23 | b >>> 9) + c | 0;
199 // ii()
200 a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
201 a = (a << 6 | a >>> 26) + b | 0;
202 d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
203 d = (d << 10 | d >>> 22) + a | 0;
204 c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
205 c = (c << 15 | c >>> 17) + d | 0;
206 b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
207 b = (b << 21 | b >>> 11) + c | 0;
208 a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
209 a = (a << 6 | a >>> 26) + b | 0;
210 d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
211 d = (d << 10 | d >>> 22) + a | 0;
212 c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
213 c = (c << 15 | c >>> 17) + d | 0;
214 b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
215 b = (b << 21 | b >>> 11) + c | 0;
216 a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
217 a = (a << 6 | a >>> 26) + b | 0;
218 d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
219 d = (d << 10 | d >>> 22) + a | 0;
220 c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
221 c = (c << 15 | c >>> 17) + d | 0;
222 b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
223 b = (b << 21 | b >>> 11) + c | 0;
224 a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
225 a = (a << 6 | a >>> 26) + b | 0;
226 d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
227 d = (d << 10 | d >>> 22) + a | 0;
228 c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
229 c = (c << 15 | c >>> 17) + d | 0;
230 b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
231 b = (b << 21 | b >>> 11) + c | 0;
232 x[0] = a + x[0] | 0;
233 x[1] = b + x[1] | 0;
234 x[2] = c + x[2] | 0;
235 x[3] = d + x[3] | 0;
236 }
237 /**
238 * Initialise buffer to be hashed
239 */
240 start() {
241 this._dataLength = 0;
242 this._bufferLength = 0;
243 this._state.set(Md5.stateIdentity);
244 return this;
245 }
246 // Char to code point to to array conversion:
247 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt
248 // #Example.3A_Fixing_charCodeAt_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_unknown
249 /**
250 * Append a UTF-8 string to the hash buffer
251 * @param str String to append
252 */
253 appendStr(str) {
254 const buf8 = this._buffer8;
255 const buf32 = this._buffer32;
256 let bufLen = this._bufferLength;
257 let code;
258 let i;
259 for (i = 0; i < str.length; i += 1) {
260 code = str.charCodeAt(i);
261 if (code < 128) {
262 buf8[bufLen++] = code;
263 }
264 else if (code < 0x800) {
265 buf8[bufLen++] = (code >>> 6) + 0xC0;
266 buf8[bufLen++] = code & 0x3F | 0x80;
267 }
268 else if (code < 0xD800 || code > 0xDBFF) {
269 buf8[bufLen++] = (code >>> 12) + 0xE0;
270 buf8[bufLen++] = (code >>> 6 & 0x3F) | 0x80;
271 buf8[bufLen++] = (code & 0x3F) | 0x80;
272 }
273 else {
274 code = ((code - 0xD800) * 0x400) + (str.charCodeAt(++i) - 0xDC00) + 0x10000;
275 if (code > 0x10FFFF) {
276 throw new Error('Unicode standard supports code points up to U+10FFFF');
277 }
278 buf8[bufLen++] = (code >>> 18) + 0xF0;
279 buf8[bufLen++] = (code >>> 12 & 0x3F) | 0x80;
280 buf8[bufLen++] = (code >>> 6 & 0x3F) | 0x80;
281 buf8[bufLen++] = (code & 0x3F) | 0x80;
282 }
283 if (bufLen >= 64) {
284 this._dataLength += 64;
285 Md5._md5cycle(this._state, buf32);
286 bufLen -= 64;
287 buf32[0] = buf32[16];
288 }
289 }
290 this._bufferLength = bufLen;
291 return this;
292 }
293 /**
294 * Append an ASCII string to the hash buffer
295 * @param str String to append
296 */
297 appendAsciiStr(str) {
298 const buf8 = this._buffer8;
299 const buf32 = this._buffer32;
300 let bufLen = this._bufferLength;
301 let i;
302 let j = 0;
303 for (;;) {
304 i = Math.min(str.length - j, 64 - bufLen);
305 while (i--) {
306 buf8[bufLen++] = str.charCodeAt(j++);
307 }
308 if (bufLen < 64) {
309 break;
310 }
311 this._dataLength += 64;
312 Md5._md5cycle(this._state, buf32);
313 bufLen = 0;
314 }
315 this._bufferLength = bufLen;
316 return this;
317 }
318 /**
319 * Append a byte array to the hash buffer
320 * @param input array to append
321 */
322 appendByteArray(input) {
323 const buf8 = this._buffer8;
324 const buf32 = this._buffer32;
325 let bufLen = this._bufferLength;
326 let i;
327 let j = 0;
328 for (;;) {
329 i = Math.min(input.length - j, 64 - bufLen);
330 while (i--) {
331 buf8[bufLen++] = input[j++];
332 }
333 if (bufLen < 64) {
334 break;
335 }
336 this._dataLength += 64;
337 Md5._md5cycle(this._state, buf32);
338 bufLen = 0;
339 }
340 this._bufferLength = bufLen;
341 return this;
342 }
343 /**
344 * Get the state of the hash buffer
345 */
346 getState() {
347 const s = this._state;
348 return {
349 buffer: String.fromCharCode.apply(null, Array.from(this._buffer8)),
350 buflen: this._bufferLength,
351 length: this._dataLength,
352 state: [s[0], s[1], s[2], s[3]]
353 };
354 }
355 /**
356 * Override the current state of the hash buffer
357 * @param state New hash buffer state
358 */
359 setState(state) {
360 const buf = state.buffer;
361 const x = state.state;
362 const s = this._state;
363 let i;
364 this._dataLength = state.length;
365 this._bufferLength = state.buflen;
366 s[0] = x[0];
367 s[1] = x[1];
368 s[2] = x[2];
369 s[3] = x[3];
370 for (i = 0; i < buf.length; i += 1) {
371 this._buffer8[i] = buf.charCodeAt(i);
372 }
373 }
374 /**
375 * Hash the current state of the hash buffer and return the result
376 * @param raw Whether to return the value as an `Int32Array`
377 */
378 end(raw = false) {
379 const bufLen = this._bufferLength;
380 const buf8 = this._buffer8;
381 const buf32 = this._buffer32;
382 const i = (bufLen >> 2) + 1;
383 this._dataLength += bufLen;
384 const dataBitsLen = this._dataLength * 8;
385 buf8[bufLen] = 0x80;
386 buf8[bufLen + 1] = buf8[bufLen + 2] = buf8[bufLen + 3] = 0;
387 buf32.set(Md5.buffer32Identity.subarray(i), i);
388 if (bufLen > 55) {
389 Md5._md5cycle(this._state, buf32);
390 buf32.set(Md5.buffer32Identity);
391 }
392 // Do the final computation based on the tail and length
393 // Beware that the final length may not fit in 32 bits so we take care of that
394 if (dataBitsLen <= 0xFFFFFFFF) {
395 buf32[14] = dataBitsLen;
396 }
397 else {
398 const matches = dataBitsLen.toString(16).match(/(.*?)(.{0,8})$/);
399 if (matches === null) {
400 return;
401 }
402 const lo = parseInt(matches[2], 16);
403 const hi = parseInt(matches[1], 16) || 0;
404 buf32[14] = lo;
405 buf32[15] = hi;
406 }
407 Md5._md5cycle(this._state, buf32);
408 return raw ? this._state : Md5._hex(this._state);
409 }
410}
411// Private Static Variables
412Md5.stateIdentity = new Int32Array([1732584193, -271733879, -1732584194, 271733878]);
413Md5.buffer32Identity = new Int32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
414Md5.hexChars = '0123456789abcdef';
415Md5.hexOut = [];
416// Permanent instance is to use for one-call hashing
417Md5.onePassHasher = new Md5();
418if (Md5.hashStr('hello') !== '5d41402abc4b2a76b9719d911017c592') {
419 throw new Error('Md5 self test failed.');
420}
421//# sourceMappingURL=md5.js.map
\No newline at end of file