unzipper
Version:
Unzip cross-platform streaming API
71 lines (55 loc) • 1.53 kB
JavaScript
var bigInt = require('big-integer');
var Stream = require('stream');
// Backwards compatibility for node 0.8
if (!Stream.Writable)
Stream = require('readable-stream');
var table;
function generateTable() {
var poly = 0xEDB88320,c,n,k;
table = [];
for (n = 0; n < 256; n++) {
c = n;
for (k = 0; k < 8; k++)
c = (c & 1) ? poly ^ (c >>> 1) : c = c >>> 1;
table[n] = c >>> 0;
}
}
function crc(ch,crc) {
if (!table)
generateTable();
if (ch.charCodeAt)
ch = ch.charCodeAt(0);
return (bigInt(crc).shiftRight(8).and(0xffffff)).xor(table[(crc ^ ch) & 0xff]).value;
}
function Decrypt() {
if (!(this instanceof Decrypt))
return new Decrypt();
this.key0 = 305419896;
this.key1 = 591751049;
this.key2 = 878082192;
}
Decrypt.prototype.update = function(h) {
this.key0 = crc(h,this.key0);
this.key1 = this.key1 + (this.key0 & 255) & 4294967295;
this.key1 = bigInt(this.key1).multiply(134775813).add(1).and(4294967295).value;
this.key2 = crc((this.key1 >> 24) & 255,this.key2);
};
Decrypt.prototype.decryptByte = function(c) {
var k = this.key2 | 2;
c = c ^ bigInt(k).multiply(bigInt(k^1)).shiftRight(8).and(255);
this.update(c);
return c;
};
Decrypt.prototype.stream = function() {
var stream = Stream.Transform(),
self = this;
stream._transform = function(d,e,cb) {
for (var i = 0; i<d.length;i++) {
d[i] = self.decryptByte(d[i]);
}
this.push(d);
cb();
};
return stream;
};
module.exports = Decrypt;