w3soft.org by unix-world
0.00
Hash methods in Javascript: SHA512, SHA256, SHA1, MD5 - HEX encoded
Sample hex Hash functions in Javascript
programming language: javascript ES6 or later
operating system: any
Updated: 2022-10-20
Copyright notice
All the code below is based, adapted and refactored by w3soft.org (an associate of unix-world) from the following open-source project:
Js/CryptUtils/Hash
[md5
,sha1
,sha256
,sha512
] - (c) 2006-2022 unix-world # license: BSD- Based on: md5, sha1, sha512 (c) 2015 github.com/hirak/phpjs # license: BSD
- Based on: sha256 (c) 2014 github.com/geraintluff # license: Public Domain
Method definition: SHA512 / Hex - String
const sha512Hex = (s, utf8) => {
if(!!utf8) {
s = utf8_encode(s); // make it unicode
}
return bin2hex(crypt_binb2str(sha512_core(s)), !!utf8);
};
Method definition: SHA384 / Hex - String
Method definition: SHA256 / Hex - String
const sha256Hex = (s, utf8) => {
if(!!utf8) {
s = utf8_encode(s); // make it unicode
}
return sha256_core(s); // this method have it's own (internal) mechanism to provide the hex encoded string
};
Method definition: SHA1 / Hex - String
const sha1Hex = (s, utf8) => {
if(!!utf8) {
s = utf8_encode(s); // make it unicode
}
return bin2hex(crypt_binb2str(sha1_core(crypt_str2binb(s), s.length * crypt_chrsz())), !!utf8);
}; //END
Method definition: MD5 / Hex - String
const md5Hex = (s, utf8) => {
if(!!utf8) {
s = utf8_encode(s); // make it unicode
}
return bin2hex(crypt_binl2str(md5_core(crypt_str2binl(s), s.length * crypt_chrsz())), !!utf8);
};
Helper functions - required by the above methods
//-- JS shared helper methods for UTF8 and HEX encodings
const utf8_encode = function(str) {
str = String((str == undefined) ? '' : str);
if(str == '') {
return '';
} //end if
let utftext = '';
str = str.replace(/\r\n/g, /\n/).replace(/\r/g, /\n/); // replace both: \r\n and \r to \n
for(let n = 0; n < str.length; n++) {
let c = str.charCodeAt(n);
if(c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return String(utftext);
};
const bin2hex = function(s, bin=false) {
s = String((s == undefined) ? '' : s);
if(s == '') {
return '';
}
if(bin !== true) { // binary content must not be encoded to UTF-8
s = String(utf8_encode(s));
}
let hex = '';
let i, l, n;
for(i=0, l=s.length; i<l; i++) {
n = s.charCodeAt(i).toString(16);
hex += n.length < 2 ? '0' + n : n;
}
return String(hex).toLowerCase();
};
//-- JS shared helper methods for the Hash algorithm
const crypt_chrsz = () => {
return 8;
};
const crypt_safe_add = function(x, y) {
let lsw = (x & 0xFFFF) + (y & 0xFFFF);
let msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
};
const crypt_bit_rol = (num, cnt) => {
return (num << cnt) | (num >>> (32 - cnt));
};
const crypt_str2binl = function(str) {
let bin = Array();
let mask = (1 << crypt_chrsz()) - 1;
for(let i = 0; i < str.length * crypt_chrsz(); i += crypt_chrsz()) {
bin[i>>5] |= (str.charCodeAt(i / crypt_chrsz()) & mask) << (i%32);
}
return bin;
};
const crypt_binl2str = function(bin) {
let str = '';
let mask = (1 << crypt_chrsz()) - 1;
for(let i = 0; i < bin.length * 32; i += crypt_chrsz()) {
str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
}
return str;
};
const crypt_str2binb = function(str) {
const mask = (1 << crypt_chrsz()) - 1;
let bin = Array();
for(let i = 0; i < str.length * crypt_chrsz(); i += crypt_chrsz()) {
bin[i>>5] |= (str.charCodeAt(i / crypt_chrsz()) & mask) << (32 - crypt_chrsz() - i%32);
}
return bin;
};
const crypt_binb2str = function(bin) {
const mask = (1 << crypt_chrsz()) - 1;
let str = '';
for(let i = 0; i < bin.length * 32; i += crypt_chrsz()) {
str += String.fromCharCode((bin[i>>5] >>> (32 - crypt_chrsz() - i%32)) & mask);
}
return str;
};
const crypt_strtoarr = function(str) {
const l = str.length;
let bytes = new Array(l);
for(let i=0; i<l; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
};
//-- JS helper methods for the SHA512 algorithm
const sha512_int_64 = function(msint_32, lsint_32) { // this is the constructor method !
const _M$ = this; // self referencing
_M$.highOrder = msint_32;
_M$.lowOrder = lsint_32;
};
const sha512_safeadd_2 = function(x, y) {
let lsw, msw, lowOrder, highOrder;
lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF);
msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16);
lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16);
msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16);
highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
return new sha512_int_64(highOrder, lowOrder);
};
const sha512_safeadd_4 = function(a, b, c, d) {
let lsw, msw, lowOrder, highOrder;
lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF);
msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16);
lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16);
msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16);
highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
return new sha512_int_64(highOrder, lowOrder);
};
const sha512_safeadd_5 = function(a, b, c, d, e) {
let lsw, msw, lowOrder, highOrder;
lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + (e.lowOrder & 0xFFFF);
msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) + (lsw >>> 16);
lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (e.highOrder & 0xFFFF) + (msw >>> 16);
msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (e.highOrder >>> 16) + (lsw >>> 16);
highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF);
return new sha512_int_64(highOrder, lowOrder);
};
const sha512_maj = (x, y, z) => {
return new sha512_int_64(
(x.highOrder & y.highOrder) ^ (x.highOrder & z.highOrder) ^ (y.highOrder & z.highOrder),
(x.lowOrder & y.lowOrder) ^ (x.lowOrder & z.lowOrder) ^ (y.lowOrder & z.lowOrder)
);
};
const sha512_ch = (x, y, z) => {
return new sha512_int_64(
(x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder),
(x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)
);
};
const sha512_rot_r = (x, n) => {
if(n <= 32) {
return new sha512_int_64(
(x.highOrder >>> n) | (x.lowOrder << (32 - n)),
(x.lowOrder >>> n) | (x.highOrder << (32 - n))
);
} else {
return new sha512_int_64(
(x.lowOrder >>> n) | (x.highOrder << (32 - n)),
(x.highOrder >>> n) | (x.lowOrder << (32 - n))
);
}
};
const sha512_sh_r = (x, n) => {
if(n <= 32) {
return new sha512_int_64(
x.highOrder >>> n,
x.lowOrder >>> n | (x.highOrder << (32 - n))
);
} else {
return new sha512_int_64(
0,
x.highOrder << (32 - n)
);
}
};
const sha512_sigma_0 = function(x) {
let rotr28 = sha512_rot_r(x, 28);
let rotr34 = sha512_rot_r(x, 34);
let rotr39 = sha512_rot_r(x, 39);
return new sha512_int_64(
rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder,
rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder
);
};
const sha512_sigma_1 = function(x) {
let rotr14 = sha512_rot_r(x, 14);
let rotr18 = sha512_rot_r(x, 18);
let rotr41 = sha512_rot_r(x, 41);
return new sha512_int_64(
rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder,
rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder
);
};
const sha512_gamma_0 = function(x) {
let rotr1 = sha512_rot_r(x, 1), rotr8 = sha512_rot_r(x, 8), shr7 = sha512_sh_r(x, 7);
return new sha512_int_64(
rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder,
rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder
);
};
const sha512_gamma_1 = function(x) {
let rotr19 = sha512_rot_r(x, 19);
let rotr61 = sha512_rot_r(x, 61);
let shr6 = sha512_sh_r(x, 6);
return new sha512_int_64(
rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder,
rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder
);
};
const sha512_core = function(str) {
let H = [
new sha512_int_64(0x6a09e667, 0xf3bcc908), new sha512_int_64(0xbb67ae85, 0x84caa73b),
new sha512_int_64(0x3c6ef372, 0xfe94f82b), new sha512_int_64(0xa54ff53a, 0x5f1d36f1),
new sha512_int_64(0x510e527f, 0xade682d1), new sha512_int_64(0x9b05688c, 0x2b3e6c1f),
new sha512_int_64(0x1f83d9ab, 0xfb41bd6b), new sha512_int_64(0x5be0cd19, 0x137e2179)
];
let K = [
new sha512_int_64(0x428a2f98, 0xd728ae22), new sha512_int_64(0x71374491, 0x23ef65cd),
new sha512_int_64(0xb5c0fbcf, 0xec4d3b2f), new sha512_int_64(0xe9b5dba5, 0x8189dbbc),
new sha512_int_64(0x3956c25b, 0xf348b538), new sha512_int_64(0x59f111f1, 0xb605d019),
new sha512_int_64(0x923f82a4, 0xaf194f9b), new sha512_int_64(0xab1c5ed5, 0xda6d8118),
new sha512_int_64(0xd807aa98, 0xa3030242), new sha512_int_64(0x12835b01, 0x45706fbe),
new sha512_int_64(0x243185be, 0x4ee4b28c), new sha512_int_64(0x550c7dc3, 0xd5ffb4e2),
new sha512_int_64(0x72be5d74, 0xf27b896f), new sha512_int_64(0x80deb1fe, 0x3b1696b1),
new sha512_int_64(0x9bdc06a7, 0x25c71235), new sha512_int_64(0xc19bf174, 0xcf692694),
new sha512_int_64(0xe49b69c1, 0x9ef14ad2), new sha512_int_64(0xefbe4786, 0x384f25e3),
new sha512_int_64(0x0fc19dc6, 0x8b8cd5b5), new sha512_int_64(0x240ca1cc, 0x77ac9c65),
new sha512_int_64(0x2de92c6f, 0x592b0275), new sha512_int_64(0x4a7484aa, 0x6ea6e483),
new sha512_int_64(0x5cb0a9dc, 0xbd41fbd4), new sha512_int_64(0x76f988da, 0x831153b5),
new sha512_int_64(0x983e5152, 0xee66dfab), new sha512_int_64(0xa831c66d, 0x2db43210),
new sha512_int_64(0xb00327c8, 0x98fb213f), new sha512_int_64(0xbf597fc7, 0xbeef0ee4),
new sha512_int_64(0xc6e00bf3, 0x3da88fc2), new sha512_int_64(0xd5a79147, 0x930aa725),
new sha512_int_64(0x06ca6351, 0xe003826f), new sha512_int_64(0x14292967, 0x0a0e6e70),
new sha512_int_64(0x27b70a85, 0x46d22ffc), new sha512_int_64(0x2e1b2138, 0x5c26c926),
new sha512_int_64(0x4d2c6dfc, 0x5ac42aed), new sha512_int_64(0x53380d13, 0x9d95b3df),
new sha512_int_64(0x650a7354, 0x8baf63de), new sha512_int_64(0x766a0abb, 0x3c77b2a8),
new sha512_int_64(0x81c2c92e, 0x47edaee6), new sha512_int_64(0x92722c85, 0x1482353b),
new sha512_int_64(0xa2bfe8a1, 0x4cf10364), new sha512_int_64(0xa81a664b, 0xbc423001),
new sha512_int_64(0xc24b8b70, 0xd0f89791), new sha512_int_64(0xc76c51a3, 0x0654be30),
new sha512_int_64(0xd192e819, 0xd6ef5218), new sha512_int_64(0xd6990624, 0x5565a910),
new sha512_int_64(0xf40e3585, 0x5771202a), new sha512_int_64(0x106aa070, 0x32bbd1b8),
new sha512_int_64(0x19a4c116, 0xb8d2d0c8), new sha512_int_64(0x1e376c08, 0x5141ab53),
new sha512_int_64(0x2748774c, 0xdf8eeb99), new sha512_int_64(0x34b0bcb5, 0xe19b48a8),
new sha512_int_64(0x391c0cb3, 0xc5c95a63), new sha512_int_64(0x4ed8aa4a, 0xe3418acb),
new sha512_int_64(0x5b9cca4f, 0x7763e373), new sha512_int_64(0x682e6ff3, 0xd6b2b8a3),
new sha512_int_64(0x748f82ee, 0x5defb2fc), new sha512_int_64(0x78a5636f, 0x43172f60),
new sha512_int_64(0x84c87814, 0xa1f0ab72), new sha512_int_64(0x8cc70208, 0x1a6439ec),
new sha512_int_64(0x90befffa, 0x23631e28), new sha512_int_64(0xa4506ceb, 0xde82bde9),
new sha512_int_64(0xbef9a3f7, 0xb2c67915), new sha512_int_64(0xc67178f2, 0xe372532b),
new sha512_int_64(0xca273ece, 0xea26619c), new sha512_int_64(0xd186b8c7, 0x21c0c207),
new sha512_int_64(0xeada7dd6, 0xcde0eb1e), new sha512_int_64(0xf57d4f7f, 0xee6ed178),
new sha512_int_64(0x06f067aa, 0x72176fba), new sha512_int_64(0x0a637dc5, 0xa2c898a6),
new sha512_int_64(0x113f9804, 0xbef90dae), new sha512_int_64(0x1b710b35, 0x131c471b),
new sha512_int_64(0x28db77f5, 0x23047d84), new sha512_int_64(0x32caab7b, 0x40c72493),
new sha512_int_64(0x3c9ebe0a, 0x15c9bebc), new sha512_int_64(0x431d67c4, 0x9c100d4c),
new sha512_int_64(0x4cc5d4be, 0xcb3e42b6), new sha512_int_64(0x597f299c, 0xfc657e2a),
new sha512_int_64(0x5fcb6fab, 0x3ad6faec), new sha512_int_64(0x6c44198c, 0x4a475817)
];
let W = new Array(64);
let a, b, c, d, e, f, g, h, i, j;
let T1, T2;
const strlen = str.length * crypt_chrsz();
str = crypt_str2binb(str);
str[strlen >> 5] |= 0x80 << (24 - strlen % 32);
str[(((strlen + 128) >> 10) << 5) + 31] = strlen;
for(let i = 0; i < str.length; i += 32) {
a = H[0];
b = H[1];
c = H[2];
d = H[3];
e = H[4];
f = H[5];
g = H[6];
h = H[7];
for(let j = 0; j < 80; j++) {
if(j < 16) {
W[j] = new sha512_int_64(str[j*2 + i], str[j*2 + i + 1]);
} else {
W[j] = sha512_safeadd_4(sha512_gamma_1(W[j - 2]), W[j - 7], sha512_gamma_0(W[j - 15]), W[j - 16]);
}
T1 = sha512_safeadd_5(h, sha512_sigma_1(e), sha512_ch(e, f, g), K[j], W[j]);
T2 = sha512_safeadd_2(sha512_sigma_0(a), sha512_maj(a, b, c));
h = g;
g = f;
f = e;
e = sha512_safeadd_2(d, T1);
d = c;
c = b;
b = a;
a = sha512_safeadd_2(T1, T2);
}
H[0] = sha512_safeadd_2(a, H[0]);
H[1] = sha512_safeadd_2(b, H[1]);
H[2] = sha512_safeadd_2(c, H[2]);
H[3] = sha512_safeadd_2(d, H[3]);
H[4] = sha512_safeadd_2(e, H[4]);
H[5] = sha512_safeadd_2(f, H[5]);
H[6] = sha512_safeadd_2(g, H[6]);
H[7] = sha512_safeadd_2(h, H[7]);
}
let binarray = [];
for(let i = 0; i < H.length; i++) {
binarray.push(H[i].highOrder);
binarray.push(H[i].lowOrder);
}
return binarray;
};
//-- JS helper methods and variables for the SHA256 algorithm
let sha256_cache_h = [];
let sha256_cache_k = [];
const sha256_core = function(str) {
const rightRotate = (value, amount) => (value>>>amount) | (value<<(32 - amount));
const mathPow = Math.pow;
const maxWord = mathPow(2, 32);
const lengthProperty = 'length';
const lenStr = str[lengthProperty] * 8;
let i, j;
let result = '';
let words = [];
let hash = sha256_cache_h = sha256_cache_h || [];
let k = sha256_cache_k = sha256_cache_k || [];
let primeCounter = k[lengthProperty];
if(primeCounter <= 0) { // only run once - is cached
let isComposite = {};
for(let candidate = 2; primeCounter < 64; candidate++) {
if(!isComposite[candidate]) {
for(i=0; i<313; i+=candidate) {
isComposite[i] = candidate;
}
hash[primeCounter] = (mathPow(candidate, 0.5) * maxWord) | 0;
k[primeCounter++] = (mathPow(candidate, 1/3) * maxWord) | 0;
}
}
}
str += '\x80'; // add Ƈ' bit (plus zero padding)
while(str[lengthProperty] % 64 - 56) {
str += '\x00'; // zero padding
}
for(i=0; i<str[lengthProperty]; i++) {
j = str.charCodeAt(i);
if(j>>8) {
return ''; // ASCII check: only accept characters in range 0-255
}
words[i>>2] |= j << ((3 - i) % 4) * 8;
}
words[words[lengthProperty]] = ((lenStr / maxWord) | 0);
words[words[lengthProperty]] = (lenStr);
for(j=0; j<words[lengthProperty];) {
let w = words.slice(j, j += 16); // expand into 64 words as part of the iteration
let oldHash = hash;
hash = hash.slice(0, 8);
for(i=0; i<64; i++) {
let i2 = i + j;
let w15 = w[i - 15], w2 = w[i - 2];
let a = hash[0], e = hash[4];
let temp1 = hash[7] + (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1
+ ((e&hash[5])^((~e)&hash[6]))
+ k[i]
+ (w[i] = (i < 16) ? w[i] : (
w[i - 16]
+ (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15>>>3)) // s0
+ w[i - 7]
+ (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2>>>10)) // s1
) | 0
);
let temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
+ ((a&hash[1])^(a&hash[2])^(hash[1]&hash[2])); // maj
hash = [(temp1 + temp2) | 0].concat(hash);
hash[4] = (hash[4] + temp1) | 0;
}
for(i=0; i<8; i++) {
hash[i] = (hash[i] + oldHash[i]) | 0;
}
}
for(i=0; i<8; i++) {
for(j=3; j+1; j--) {
let b = (hash[i]>>(j*8))&255;
result += ((b < 16) ? 0 : '') + b.toString(16);
}
}
return String(result || '');
};
//-- JS helper methods for the SHA1 algorithm
const 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;
};
const sha1_kt = (t) => {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514 ;
};
const sha1_core = function(x, len) {
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
let e = -1009589776;
let w = Array(80);
for(let i = 0; i < x.length; i += 16) {
let olda = a;
let oldb = b;
let oldc = c;
let oldd = d;
let olde = e;
for(let j = 0; j < 80; j++) {
if(j < 16) {
w[j] = x[i + j];
} else {
w[j] = crypt_bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
}
let t = crypt_safe_add(crypt_safe_add(crypt_bit_rol(a, 5), sha1_ft(j, b, c, d)), crypt_safe_add(crypt_safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = crypt_bit_rol(b, 30);
b = a;
a = t;
}
a = crypt_safe_add(a, olda);
b = crypt_safe_add(b, oldb);
c = crypt_safe_add(c, oldc);
d = crypt_safe_add(d, oldd);
e = crypt_safe_add(e, olde);
}
return Array(a, b, c, d, e);
};
//-- JS helper methods for the MD5 algorithm
const md5_cmn = (q, a, b, x, s, t) => {
return crypt_safe_add(crypt_bit_rol(crypt_safe_add(crypt_safe_add(a, q), crypt_safe_add(x, t)), s),b);
};
const md5_ff = (a, b, c, d, x, s, t) => {
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
};
const md5_gg = (a, b, c, d, x, s, t) => {
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
};
const md5_hh = (a, b, c, d, x, s, t) => {
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
};
const md5_ii = (a, b, c, d, x, s, t) => {
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
};
const md5_core = function(x, len) {
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for(let i = 0; i < x.length; i += 16) {
let olda = a;
let oldb = b;
let oldc = c;
let oldd = d;
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
a = crypt_safe_add(a, olda);
b = crypt_safe_add(b, oldb);
c = crypt_safe_add(c, oldc);
d = crypt_safe_add(d, oldd);
}
return Array(a, b, c, d);
};