UNPKG

bigjs

Version:

A big integer library for JS, based on Leemon, with focus on prime numbers and cryptography

223 lines (169 loc) 4.29 kB
/* * Joseph's Super Fast Big Int Library * Each array element is 50bits long * If the number is over 1125899906842624 make a new element * * */ //This is the number of bits in a chunk var CHUNK_SIZE = 15; //We want the and mask to look like 11110000 var AND_MASK = (Math.pow(2,CHUNK_SIZE) - 1) << CHUNK_SIZE; var INV_AND_MASK = ~AND_MASK; function BI(number,base){ base = base || 10; this.n = []; this.size = 0; // The bit size in the last chunk this.lB = 0; switch(typeof number){ case 'string': break; case 'number': while(number){ this.n.push((number & INV_AND_MASK)); number >>= CHUNK_SIZE; this.size++; } break; case 'undefined': return this; break; } return this; } BI.prototype.lt = function(num){ var tS = this.size; var nS = num.size; if(tS == nS){ return this.n[tS - 1] < num.n[nS - 1]; }else{ return tS < nS; } } BI.prototype.gt = function(num){ var tS = this.size; var nS = num.size; if(tS == nS){ return this.n[tS - 1] > num.n[nS - 1]; }else{ return tS > nS; } } BI.prototype.eq = function(num){ var tS = this.size; var nS = num.size; if(tS == nS){ return this.n.join('') == num.n.join(''); }else{ return false; } } BI.prototype.add = function(num){ } BI.prototype.ls = function(k){ var c = new BI(); // The number of new chunks needed to be added var chunks = ~~(k / CHUNK_SIZE); // The remaining shift length needed to be done var rem = (k - (chunks * CHUNK_SIZE)); // Shift in the chunks for(var i = 0;i < chunks;i++){ this.n.unshift(0); } this.size += chunks; var carry = 0, nCarry = 0; //Shift in everything else for(var i = chunks,ii = this.size - 1;i <= ii;i++){ // Shift in the remainder this.n[i] <<= rem; // Add the carry this.n[i] |= carry; if(i == ii){ if((this.lB + rem) > CHUNK_SIZE){ this.lB = (this.lB + rem) - CHUNK_SIZE; this.n.push(0); this.n[i + 1] = (this.n[i] & AND_MASK) >> CHUNK_SIZE; }else{ this.lB += rem; } break; } //And out the overflow bits, and shift them into the normal place carry = (this.n[i] & AND_MASK) >> CHUNK_SIZE; } return this; } BI.prototype.rs = function(k){ // Calculate the number of chunks to disappear var chunks = ~~(k / CHUNK_SIZE); // Remaining shift size var rem = (k - (chunks * CHUNK_SIZE)); //Shift out the chunks for(var i = 0;i < chunks;i++){ this.n.shift(); } this.size -= chunks; //We start from 0 because everything below has been shifted out for(var i = 0,ii = this.size - 1;i < ii;i++){ if(i == ii){ } this.n[i]; } return this; } //Performs a bitwise OR on 2 big integers BI.prototype.OR = function(num){ // We only need to OR the smallest number of chunks var ii = (BI.lt(num)? this.size : num.size); for(var i = 0;i < ii;i++){ this.n[i] |= num.n[i]; } return this; } //Performs a bitwise AND on 2 big integers BI.prototype.AND = function(num){ // We only need to OR the smallest number of chunks var ii = (BI.lt(num)? this.size : num.size); for(var i = 0;i < ii;i++){ this.n[i] &= num.n[i]; } return this; } //Performs a bitwise XOR on 2 big integers BI.prototype.XOR = function(num){ // We only need to OR the smallest number of chunks var ii = (this.lt(num)? this.size : num.size); for(var i = 0;i < ii;i++){ this.n[i] ^= num.n[i]; } return this; } BI.prototype.NOT = function() { //Flip all the bits for(var i = 0,ii = this.size-1;i <= ii;i++){ //If we flip all the bits in the last column we get a new number if(i == ii){ this.n[i] = (~this.n[i] << (CHUNK_SIZE - this.lB)) & AND_MASK; break; } //We only need the last bits this.n[i] = ~this.n[i] & INV_AND_MASK; } return this; } BI.prototype.digest = function(){ //The digest string var dString = ""; //Append all the chunks for(var i = 0;i < this.size;i++){ var num = this.n[i].toString(2); dString = ("0".repeat(CHUNK_SIZE).substr(num.length) + num) + dString; } return dString; } //Performs a bitwise AND on 2 big integers BI.prototype.valueOf = function(){ } BI.prototype.toString = function(base){ }