(value: string)
| 569 | * preventing cache key collision attacks. |
| 570 | */ |
| 571 | export function generateHash(value: string): string { |
| 572 | textEncoder ??= new TextEncoder(); |
| 573 | const inputBytes = textEncoder.encode(value); |
| 574 | |
| 575 | // Initial hash values (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19): |
| 576 | let hashState0 = 0x6a09e667; |
| 577 | let hashState1 = 0xbb67ae85; |
| 578 | let hashState2 = 0x3c6ef372; |
| 579 | let hashState3 = 0xa54ff53a; |
| 580 | let hashState4 = 0x510e527f; |
| 581 | let hashState5 = 0x9b05688c; |
| 582 | let hashState6 = 0x1f83d9ab; |
| 583 | let hashState7 = 0x5be0cd19; |
| 584 | |
| 585 | // Pre-processing (Padding): |
| 586 | const messageLengthInBits = inputBytes.length * 8; |
| 587 | |
| 588 | // The total length of the padded message must be a multiple of 64 bytes (512 bits) |
| 589 | const paddedLengthInBytes = (((inputBytes.length + 8) >> 6) + 1) << 6; |
| 590 | const paddedBytes = new Uint8Array(paddedLengthInBytes); |
| 591 | paddedBytes.set(inputBytes); |
| 592 | paddedBytes[inputBytes.length] = 0x80; // Append a single '1' bit (0x80 byte) |
| 593 | |
| 594 | const paddedBytesView = new DataView(paddedBytes.buffer); |
| 595 | const lowBits = messageLengthInBits >>> 0; |
| 596 | const highBits = (messageLengthInBits / 0x100000000) >>> 0; |
| 597 | paddedBytesView.setUint32(paddedLengthInBytes - 8, highBits, false); |
| 598 | paddedBytesView.setUint32(paddedLengthInBytes - 4, lowBits, false); |
| 599 | |
| 600 | // Process the message in successive 64-byte chunks: |
| 601 | const messageSchedule = new Uint32Array(64); |
| 602 | for (let chunkOffset = 0; chunkOffset < paddedLengthInBytes; chunkOffset += 64) { |
| 603 | // Initialize first 16 words of the message schedule: |
| 604 | for (let i = 0; i < 16; i++) { |
| 605 | messageSchedule[i] = paddedBytesView.getUint32(chunkOffset + i * 4, false); |
| 606 | } |
| 607 | |
| 608 | // Extend to 64 words: |
| 609 | for (let i = 16; i < 64; i++) { |
| 610 | const prevWord15 = messageSchedule[i - 15]; |
| 611 | const sigma0 = |
| 612 | (((prevWord15 >>> 7) | (prevWord15 << 25)) ^ |
| 613 | ((prevWord15 >>> 18) | (prevWord15 << 14)) ^ |
| 614 | (prevWord15 >>> 3)) >>> |
| 615 | 0; |
| 616 | |
| 617 | const prevWord2 = messageSchedule[i - 2]; |
| 618 | const sigma1 = |
| 619 | (((prevWord2 >>> 17) | (prevWord2 << 15)) ^ |
| 620 | ((prevWord2 >>> 19) | (prevWord2 << 13)) ^ |
| 621 | (prevWord2 >>> 10)) >>> |
| 622 | 0; |
| 623 | |
| 624 | messageSchedule[i] = |
| 625 | (messageSchedule[i - 16] + sigma0 + messageSchedule[i - 7] + sigma1) >>> 0; |
| 626 | } |
| 627 | |
| 628 | // Initialize working variables to current hash values: |
no test coverage detected
searching dependent graphs…