@vinothnb/smb2
Version:
193 lines (155 loc) • 4.05 kB
JavaScript
var BigInt = (module.exports = function(n, v) {
if (BigInt.isBigInt(n)) {
this.buffer = Buffer.allocUnsafe(n.buffer.length);
n.buffer.copy(this.buffer, 0);
this.sign = n.sign;
} else {
this.buffer = Buffer.alloc(n);
this.sign = 1;
v = v || 0;
if (v !== 0) {
if (v < 0) {
this.sign = -1;
v = -v;
}
v = v.toString(16);
var size = Math.ceil(v.length / 2);
var carry = size * 2 - v.length;
for (var i = 0; i < size; i++) {
var start = (size - i - 1) * 2 - carry;
this.buffer.writeUInt8(
parseInt(start === -1 ? v.substr(0, 1) : v.substr(start, 2), 16),
i
);
}
}
}
});
/*
* STATICS
*/
BigInt.isBigInt = function(v) {
return v && v.buffer && Buffer.isBuffer(v.buffer);
};
BigInt.toBigInt = function(n, v) {
return new BigInt(n, v);
};
BigInt.fromBuffer = function(b, sign) {
sign = typeof sign === 'undefined' ? 1 : sign;
var bi = new BigInt(0);
bi.sign = sign;
bi.buffer = b;
return bi;
};
/*
* ADD / SUB
*/
BigInt.prototype.add = function(v) {
if (!BigInt.isBigInt(v)) {
v = BigInt.toBigInt(this.buffer.length, v);
}
if (this.sign !== v.sign) {
return this.neg().sub(v);
}
var carry = 0;
var n = Math.max(v.buffer.length, this.buffer.length);
var result = new BigInt(n);
for (var i = 0; i < n; i++) {
var r =
(i < this.buffer.length ? this.buffer.readUInt8(i) : 0) +
(i < v.buffer.length ? v.buffer.readUInt8(i) : 0) +
carry;
result.buffer.writeUInt8(r & 0xff, i);
carry = r >> 8;
}
result.sign = this.sign;
return result;
};
BigInt.prototype.neg = function() {
var result = new BigInt(this);
result.sign *= -1;
return result;
};
BigInt.prototype.abs = function() {
var result = new BigInt(this);
result.sign = 1;
return result;
};
BigInt.prototype.sub = function(v) {
if (!BigInt.isBigInt(v)) {
v = BigInt.toBigInt(this.buffer.length, v);
}
if (this.sign !== v.sign) {
return this.add(v.neg());
}
var carry = 0;
var a = new BigInt(this);
var b = new BigInt(v);
var n = Math.max(a.buffer.length, b.buffer.length);
var result = new BigInt(n);
var sign = this.sign;
if (a.abs().lt(b.abs())) {
var t = a;
a = b;
b = t;
sign *= -1;
}
for (var i = 0; i < n; i++) {
var va = i < a.buffer.length ? a.buffer.readUInt8(i) : 0;
var vb = i < b.buffer.length ? b.buffer.readUInt8(i) : 0;
var c = 0;
var r = va - vb - carry;
while (r < 0) {
r += 0xff;
c--;
}
result.buffer.writeUInt8(r & 0xff, i);
carry = (r >> 8) + c;
}
result.sign = sign;
return result;
};
/*
* EXPORTS
*/
BigInt.prototype.toBuffer = function() {
return this.buffer;
};
BigInt.prototype.toNumber = function() {
var b = Buffer.allocUnsafe(this.buffer.length);
for (var i = 0; i < this.buffer.length; i++) {
b.writeUInt8(this.buffer.readUInt8(this.buffer.length - i - 1), i);
}
return parseInt(b.toString('hex'), 16);
};
/*
* COMPARE
*/
BigInt.prototype.compare = function(v) {
if (!BigInt.isBigInt(v)) {
v = BigInt.toBigInt(this.buffer.length, v);
}
var n = Math.max(v.buffer.length, this.buffer.length);
if (this.sign > v.sign) return 1;
if (this.sign < v.sign) return -1;
for (var i = n - 1; i >= 0; i--) {
var a = i < this.buffer.length ? this.buffer.readUInt8(i) : 0;
var b = i < v.buffer.length ? v.buffer.readUInt8(i) : 0;
if (a !== b) {
return a > b ? this.sign : -this.sign;
}
}
return 0;
};
BigInt.prototype.lt = function(v) {
return this.compare(v) < 0;
};
BigInt.prototype.le = function(v) {
return this.compare(v) <= 0;
};
BigInt.prototype.gt = function(v) {
return this.compare(v) > 0;
};
BigInt.prototype.ge = function(v) {
return this.compare(v) >= 0;
};