const Constants = [
0x428a2f98d728ae22n, 0x7137449123ef65cdn, 0xb5c0fbcfec4d3b2fn,
0xe9b5dba58189dbbcn, 0x3956c25bf348b538n, 0x59f111f1b605d019n,
0x923f82a4af194f9bn, 0xab1c5ed5da6d8118n, 0xd807aa98a3030242n,
0x12835b0145706fben, 0x243185be4ee4b28cn, 0x550c7dc3d5ffb4e2n,
0x72be5d74f27b896fn, 0x80deb1fe3b1696b1n, 0x9bdc06a725c71235n,
0xc19bf174cf692694n, 0xe49b69c19ef14ad2n, 0xefbe4786384f25e3n,
0x0fc19dc68b8cd5b5n, 0x240ca1cc77ac9c65n, 0x2de92c6f592b0275n,
0x4a7484aa6ea6e483n, 0x5cb0a9dcbd41fb44n, 0x76f988da831153b5n,
0x983e5152ee66dfabn, 0xa831c66d2db43210n, 0xb00327c898fb213fn,
0xbf597fc7beef0ee4n, 0xc6e00bf33da88fc2n, 0xd5a79147930aa725n,
0x06ca6351e003826fn, 0x142929670a0e6e70n, 0x27b70a8546d22ffcn,
0x2e1b21385c26c926n, 0x4d2c6dfc5ac42aedn, 0x53380d139d95b3dfn,
0x650a73548baf63den, 0x766a0abb3c77b2a8n, 0x81c2c92e47edaee6n,
0x92722c851482353bn, 0xa2bfe8a14cf10364n, 0xa81a664bbc423001n,
0xc24b8b70d0f89791n, 0xc76c51a30654be30n, 0xd192e819d6ef5218n,
0xd69906245565a910n, 0xf40e35855771202an, 0x106aa07032bbd1b8n,
0x19a4c116b8d2d0c8n, 0x1e376c085141ab53n, 0x2748774cdf8eeb99n,
0x34b0bcb5e19b48a8n, 0x391c0cb3c5c95a63n, 0x4ed8aa4ae3418acbn,
0x5b9cca4f7763e373n, 0x682e6ff3d6b2b8a3n, 0x748f82ee5defb2fcn,
0x78a5636f43172f60n, 0x84c87814a1f0ab72n, 0x8cc702081a6439ecn,
0x90befffa23631e28n, 0xa4506cebde82bde9n, 0xbef9a3f7b2c67915n,
0xc67178f2e372532bn, 0xca273eceea26619cn, 0xd186b8c721c0c207n,
0xeada7dd6cde0eb1en, 0xf57d4f7fee6ed178n, 0x06f067aa72176fban,
0x0a637dc5a2c898a6n, 0x113f9804bef90daen, 0x1b710b35131c471bn,
0x28db77f523047d84n, 0x32caab7b40c72493n, 0x3c9ebe0a15c9bebcn,
0x431d67c49c100d4cn, 0x4cc5d4becb3e42b6n, 0x597f299cfc657e2an,
0x5fcb6fab3ad6faecn, 0x6c44198c4a475817n
];
let Message = new Array(80).fill(BigInt(0));
function getHex(bin) {
const hexValues = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
const index = parseInt(bin, 2);
return hexValues[index];
}
function decimalToHex(deci) {
let hexstring = '';
let EQBIN = deci.toString(2).padStart(64, '0');
for (let i = 0; i < EQBIN.length; i += 4) {
hexstring += getHex(EQBIN.substr(i, 4));
}
return hexstring;
}
function binaryToDecimal(bin) {
return BigInt('0b' + bin);
}
function rotateRight(x, n) {
return (x >> n) | (x << (BigInt(64) - n));
}
function shiftRight(x, n) {
return x >> n;
}
function separator(getBlock) {
for (let g = 16; g < 80; ++g) {
const WordA = rotateRight(Message[g - 2], 19n) ^ rotateRight(Message[g - 2], 61n) ^ shiftRight(Message[g - 2], 6n);
const WordB = Message[g - 7];
const WordC = rotateRight(Message[g - 15], 1n) ^ rotateRight(Message[g - 15], 8n) ^ shiftRight(Message[g - 15], 7n);
const WordD = Message[g - 16];
const T = WordA + WordB + WordC + WordD;
Message[g] = T;
}
}
function maj(a, b, c) {
return (a & b) ^ (b & c) ^ (c & a);
}
function Ch(e, f, g) {
return (e & f) ^ (~e & g);
}
function sigmaE(e) {
return rotateRight(e, 14n) ^ rotateRight(e, 18n) ^ rotateRight(e, 41n);
}
function sigmaA(a) {
return rotateRight(a, 28n) ^ rotateRight(a, 34n) ^ rotateRight(a, 39n);
}
function Func(a, b, c, d, e, f, g, h, K) {
const T1 = h + Ch(e, f, g) + sigmaE(e) + Message[K] + Constants[K];
const T2 = sigmaA(a) + maj(a, b, c);
d += T1;
h = T1 + T2;
}
function SHA512(myString) {
let A = 0x6a09e667f3bcc908n;
let B = 0xbb67ae8584caa73bn;
let C = 0x3c6ef372fe94f82bn;
let D = 0xa54ff53a5f1d36f1n;
let E = 0x510e527fade682d1n;
let F = 0x9b05688c2b3e6c1fn;
let G = 0x1f83d9abfb41bd6bn;
let H = 0x5be0cd19137e2179n;
const fixedStream = [];
for (let i = 0; i < myString.length; ++i) {
fixedStream.push(myString.charCodeAt(i).toString(2).padStart(8, '0'));
}
let s1024 = fixedStream.join('');
const orilen = s1024.length;
let tobeadded = 0;
const modded = s1024.length % 1024;
if (1024 - modded >= 128) {
tobeadded = 1024 - modded;
} else {
tobeadded = 2048 - modded;
}
s1024 += '1';
s1024 += '0'.repeat(tobeadded - 129);
const lengthbits = orilen.toString(2).padStart(128, '0');
s1024 += lengthbits;
const blocksnumber = Math.ceil(s1024.length / 1024);
const Blocks = new Array(blocksnumber).fill('');
for (let i = 0; i < s1024.length; i += 1024) {
Blocks[i / 1024] = s1024.substr(i, 1024);
}
for (let letsgo = 0; letsgo < blocksnumber; ++letsgo) {
separator(Blocks[letsgo]);
let AA = A, BB = B, CC = C, DD = D, EE = E, FF = F, GG = G, HH = H;
let count = 0;
for (let i = 0; i < 10; i++) {
Func(A, B, C, D, E, F, G, H, count);
count++;
Func(H, A, B, C, D, E, F, G, count);
count++;
Func(G, H, A, B, C, D, E, F, count);
count++;
Func(F, G, H, A, B, C, D, E, count);
count++;
Func(E, F, G, H, A, B, C, D, count);
count++;
Func(D, E, F, G, H, A, B, C, count);
count++;
Func(C, D, E, F, G, H, A, B, count);
count++;
Func(B, C, D, E, F, G, H, A, count);
count++;
}
A += AA;
B += BB;
C += CC;
D += DD;
E += EE;
F += FF;
G += GG;
H += HH;
}
let output = '';
output += decimalToHex(A);
output += decimalToHex(B);
output += decimalToHex(C);
output += decimalToHex(D);
output += decimalToHex(E);
output += decimalToHex(F);
output += decimalToHex(G);
output += decimalToHex(H);
return output;
}
// Driver Code
const S = 'GeeksForGeeks';
console.log(S + ': ' + SHA512(S));