etag-hash
Version:
Es6 class that generates ETag using the same algorithm as S3 via MD5 sum.
43 lines (42 loc) • 1.33 kB
JavaScript
import { createHash as createCryptoHash } from 'crypto';
export class ETagHash {
partSizeInBytes;
sums;
part;
bytes;
constructor(partSizeInMb = 5) {
this.partSizeInBytes = partSizeInMb * 1024 * 1024;
this.sums = [createCryptoHash('md5')];
this.part = 0;
this.bytes = 0;
}
update(chunk) {
const len = chunk.length;
if (this.bytes + len < this.partSizeInBytes) {
this.sums[this.part].update(chunk);
this.bytes += len;
}
else {
const bytesNeeded = this.partSizeInBytes - this.bytes;
this.sums[this.part].update(chunk.subarray(0, bytesNeeded));
this.part++;
this.sums.push(createCryptoHash('md5'));
this.bytes = len - bytesNeeded;
this.sums[this.part].update(chunk.subarray(bytesNeeded));
}
return this;
}
digest() {
if (!this.part) {
return this.sums[0].digest('hex');
}
const checksum = this.sums.map((s) => s.digest('hex')).join('');
const final = createCryptoHash('md5')
.update(Buffer.from(checksum, 'hex'))
.digest('hex');
return `${final}-${this.part + 1}`;
}
}
export const createHash = (...args) => {
return new ETagHash(...args);
};