2

I wish to calculate a file's checksum locally with JS and have been searching for examples of how to accomplish this using the Streams Api and pipeTo, but have only found examples with Node.js which I am not familiar with. What I'm looking for is something like this:

var stream = file.stream();
var hash = CryptoJS.algo.SHA1.create();
await stream.pipeTo(hash);
console.log(hash);

This code does not work since CryptoJS doesn't seem to create WriteableStream. Can I wrap what CryptoJS creates in some kind of shim or sink? Other suggestions?

I could read and append buffers incrementally of course, but the code becomes a bit messy so I was hoping I could leverage pipeTo to avoid complicating the code.

Andreas Zita
  • 7,232
  • 6
  • 54
  • 115
  • Node.js provides helpers to convert web streams to Node streams and vice versa. e.g. https://nodejs.org/api/stream.html#streamwritabletowebstreamwritable – Benjamin Gruenbaum Jan 02 '22 at 11:40

1 Answers1

0
function byteArrayToWordArray(ba) {
    let wa = [], i;
    for (i = 0; i < ba.length; i++) wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i);
    return CryptoJS.lib.WordArray.create(wa, ba.length);
}

const cryptoJsWritableStream = (hash) => {
  return new WritableStream({
    write(chunk) {
      hash.update(byteArrayToWordArray(chunk));
    },
    close() {},
    abort() {},
  });
};

const stream = file.stream();
const hash = CryptoJS.algo.SHA1.create();
await stream.pipeTo(cryptoJsWritableStream(hash));
console.log(hash.finalize().toString());
Andreas Zita
  • 7,232
  • 6
  • 54
  • 115