etebase
Version:
Etebase TypeScript API for the web and node
38 lines • 1.53 kB
JavaScript
/*
* The rolling sum implementation is based on Rollsum from bup which is in turn based on rollsum from librsync:
* https://github.com/bup/bup/blob/master/lib/bup/bupsplit.c
* https://github.com/librsync/librsync/blob/master/src/rollsum.h
*
* We tried a few alternatives (see experiments/chunker/ for details) though this was by far the best one.
*
* The problem with using such a chunker is that it leaks information about the sizes of different chunks which
* in turn leaks information about the original file (because the chunking is deterministic).
* Therefore one needs to make sure to pad the chunks in a way that doesn't leak this information.
*/
const windowSize = 64;
const charOffset = 31;
export class Rollsum {
constructor() {
this.window = new Uint8Array(windowSize);
this.s1 = windowSize * charOffset;
this.s2 = windowSize * (windowSize - 1) * charOffset;
this.wofs = 0;
}
update(ch) {
this.rollsumAdd(this.window[this.wofs], ch);
this.window[this.wofs] = (ch);
this.wofs = (this.wofs + 1) % windowSize;
}
rollsumAdd(drop, add) {
this.s1 = (this.s1 + add - drop) >>> 0;
this.s2 = (this.s2 + this.s1 - (windowSize * (drop + charOffset))) >>> 0;
}
/**
* Returns true if splitting is needed, that is when the current digest
* reaches the given number of the same consecutive low bits.
*/
split(mask) {
return ((this.s2 & (mask)) === mask);
}
}
//# sourceMappingURL=Chunker.js.map