bchaddrjs-slp
Version:
Bitcoin Cash and SLP general purpose address translation.
1,422 lines (1,294 loc) • 406 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.bchaddr = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict'
// base-x encoding / decoding
// Copyright (c) 2018 base-x contributors
// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
// @ts-ignore
var _Buffer = require('safe-buffer').Buffer
function base (ALPHABET) {
if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }
var BASE_MAP = new Uint8Array(256)
for (var j = 0; j < BASE_MAP.length; j++) {
BASE_MAP[j] = 255
}
for (var i = 0; i < ALPHABET.length; i++) {
var x = ALPHABET.charAt(i)
var xc = x.charCodeAt(0)
if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }
BASE_MAP[xc] = i
}
var BASE = ALPHABET.length
var LEADER = ALPHABET.charAt(0)
var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up
var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up
function encode (source) {
if (Array.isArray(source) || source instanceof Uint8Array) { source = _Buffer.from(source) }
if (!_Buffer.isBuffer(source)) { throw new TypeError('Expected Buffer') }
if (source.length === 0) { return '' }
// Skip & count leading zeroes.
var zeroes = 0
var length = 0
var pbegin = 0
var pend = source.length
while (pbegin !== pend && source[pbegin] === 0) {
pbegin++
zeroes++
}
// Allocate enough space in big-endian base58 representation.
var size = ((pend - pbegin) * iFACTOR + 1) >>> 0
var b58 = new Uint8Array(size)
// Process the bytes.
while (pbegin !== pend) {
var carry = source[pbegin]
// Apply "b58 = b58 * 256 + ch".
var i = 0
for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {
carry += (256 * b58[it1]) >>> 0
b58[it1] = (carry % BASE) >>> 0
carry = (carry / BASE) >>> 0
}
if (carry !== 0) { throw new Error('Non-zero carry') }
length = i
pbegin++
}
// Skip leading zeroes in base58 result.
var it2 = size - length
while (it2 !== size && b58[it2] === 0) {
it2++
}
// Translate the result into a string.
var str = LEADER.repeat(zeroes)
for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }
return str
}
function decodeUnsafe (source) {
if (typeof source !== 'string') { throw new TypeError('Expected String') }
if (source.length === 0) { return _Buffer.alloc(0) }
var psz = 0
// Skip leading spaces.
if (source[psz] === ' ') { return }
// Skip and count leading '1's.
var zeroes = 0
var length = 0
while (source[psz] === LEADER) {
zeroes++
psz++
}
// Allocate enough space in big-endian base256 representation.
var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.
var b256 = new Uint8Array(size)
// Process the characters.
while (source[psz]) {
// Decode character
var carry = BASE_MAP[source.charCodeAt(psz)]
// Invalid character
if (carry === 255) { return }
var i = 0
for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {
carry += (BASE * b256[it3]) >>> 0
b256[it3] = (carry % 256) >>> 0
carry = (carry / 256) >>> 0
}
if (carry !== 0) { throw new Error('Non-zero carry') }
length = i
psz++
}
// Skip trailing spaces.
if (source[psz] === ' ') { return }
// Skip leading zeroes in b256.
var it4 = size - length
while (it4 !== size && b256[it4] === 0) {
it4++
}
var vch = _Buffer.allocUnsafe(zeroes + (size - it4))
vch.fill(0x00, 0, zeroes)
var j = zeroes
while (it4 !== size) {
vch[j++] = b256[it4++]
}
return vch
}
function decode (string) {
var buffer = decodeUnsafe(string)
if (buffer) { return buffer }
throw new Error('Non-base' + BASE + ' character')
}
return {
encode: encode,
decodeUnsafe: decodeUnsafe,
decode: decode
}
}
module.exports = base
},{"safe-buffer":57}],2:[function(require,module,exports){
'use strict'
exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
function getLens (b64) {
var len = b64.length
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=')
if (validLen === -1) validLen = len
var placeHoldersLen = validLen === len
? 0
: 4 - (validLen % 4)
return [validLen, placeHoldersLen]
}
// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function _byteLength (b64, validLen, placeHoldersLen) {
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function toByteArray (b64) {
var tmp
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
var curByte = 0
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0
? validLen - 4
: validLen
var i
for (i = 0; i < len; i += 4) {
tmp =
(revLookup[b64.charCodeAt(i)] << 18) |
(revLookup[b64.charCodeAt(i + 1)] << 12) |
(revLookup[b64.charCodeAt(i + 2)] << 6) |
revLookup[b64.charCodeAt(i + 3)]
arr[curByte++] = (tmp >> 16) & 0xFF
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 2) {
tmp =
(revLookup[b64.charCodeAt(i)] << 2) |
(revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 1) {
tmp =
(revLookup[b64.charCodeAt(i)] << 10) |
(revLookup[b64.charCodeAt(i + 1)] << 4) |
(revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] +
lookup[num >> 12 & 0x3F] +
lookup[num >> 6 & 0x3F] +
lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp =
((uint8[i] << 16) & 0xFF0000) +
((uint8[i + 1] << 8) & 0xFF00) +
(uint8[i + 2] & 0xFF)
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
parts.push(
lookup[tmp >> 2] +
lookup[(tmp << 4) & 0x3F] +
'=='
)
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
parts.push(
lookup[tmp >> 10] +
lookup[(tmp >> 4) & 0x3F] +
lookup[(tmp << 2) & 0x3F] +
'='
)
}
return parts.join('')
}
},{}],3:[function(require,module,exports){
var bigInt = (function (undefined) {
"use strict";
var BASE = 1e7,
LOG_BASE = 7,
MAX_INT = 9007199254740992,
MAX_INT_ARR = smallToArray(MAX_INT),
DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
var supportsNativeBigInt = typeof BigInt === "function";
function Integer(v, radix, alphabet, caseSensitive) {
if (typeof v === "undefined") return Integer[0];
if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
return parseValue(v);
}
function BigInteger(value, sign) {
this.value = value;
this.sign = sign;
this.isSmall = false;
}
BigInteger.prototype = Object.create(Integer.prototype);
function SmallInteger(value) {
this.value = value;
this.sign = value < 0;
this.isSmall = true;
}
SmallInteger.prototype = Object.create(Integer.prototype);
function NativeBigInt(value) {
this.value = value;
}
NativeBigInt.prototype = Object.create(Integer.prototype);
function isPrecise(n) {
return -MAX_INT < n && n < MAX_INT;
}
function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
if (n < 1e7)
return [n];
if (n < 1e14)
return [n % 1e7, Math.floor(n / 1e7)];
return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
}
function arrayToSmall(arr) { // If BASE changes this function may need to change
trim(arr);
var length = arr.length;
if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
switch (length) {
case 0: return 0;
case 1: return arr[0];
case 2: return arr[0] + arr[1] * BASE;
default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
}
}
return arr;
}
function trim(v) {
var i = v.length;
while (v[--i] === 0);
v.length = i + 1;
}
function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
var x = new Array(length);
var i = -1;
while (++i < length) {
x[i] = 0;
}
return x;
}
function truncate(n) {
if (n > 0) return Math.floor(n);
return Math.ceil(n);
}
function add(a, b) { // assumes a and b are arrays with a.length >= b.length
var l_a = a.length,
l_b = b.length,
r = new Array(l_a),
carry = 0,
base = BASE,
sum, i;
for (i = 0; i < l_b; i++) {
sum = a[i] + b[i] + carry;
carry = sum >= base ? 1 : 0;
r[i] = sum - carry * base;
}
while (i < l_a) {
sum = a[i] + carry;
carry = sum === base ? 1 : 0;
r[i++] = sum - carry * base;
}
if (carry > 0) r.push(carry);
return r;
}
function addAny(a, b) {
if (a.length >= b.length) return add(a, b);
return add(b, a);
}
function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
var l = a.length,
r = new Array(l),
base = BASE,
sum, i;
for (i = 0; i < l; i++) {
sum = a[i] - base + carry;
carry = Math.floor(sum / base);
r[i] = sum - carry * base;
carry += 1;
}
while (carry > 0) {
r[i++] = carry % base;
carry = Math.floor(carry / base);
}
return r;
}
BigInteger.prototype.add = function (v) {
var n = parseValue(v);
if (this.sign !== n.sign) {
return this.subtract(n.negate());
}
var a = this.value, b = n.value;
if (n.isSmall) {
return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
}
return new BigInteger(addAny(a, b), this.sign);
};
BigInteger.prototype.plus = BigInteger.prototype.add;
SmallInteger.prototype.add = function (v) {
var n = parseValue(v);
var a = this.value;
if (a < 0 !== n.sign) {
return this.subtract(n.negate());
}
var b = n.value;
if (n.isSmall) {
if (isPrecise(a + b)) return new SmallInteger(a + b);
b = smallToArray(Math.abs(b));
}
return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
};
SmallInteger.prototype.plus = SmallInteger.prototype.add;
NativeBigInt.prototype.add = function (v) {
return new NativeBigInt(this.value + parseValue(v).value);
}
NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
function subtract(a, b) { // assumes a and b are arrays with a >= b
var a_l = a.length,
b_l = b.length,
r = new Array(a_l),
borrow = 0,
base = BASE,
i, difference;
for (i = 0; i < b_l; i++) {
difference = a[i] - borrow - b[i];
if (difference < 0) {
difference += base;
borrow = 1;
} else borrow = 0;
r[i] = difference;
}
for (i = b_l; i < a_l; i++) {
difference = a[i] - borrow;
if (difference < 0) difference += base;
else {
r[i++] = difference;
break;
}
r[i] = difference;
}
for (; i < a_l; i++) {
r[i] = a[i];
}
trim(r);
return r;
}
function subtractAny(a, b, sign) {
var value;
if (compareAbs(a, b) >= 0) {
value = subtract(a, b);
} else {
value = subtract(b, a);
sign = !sign;
}
value = arrayToSmall(value);
if (typeof value === "number") {
if (sign) value = -value;
return new SmallInteger(value);
}
return new BigInteger(value, sign);
}
function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
var l = a.length,
r = new Array(l),
carry = -b,
base = BASE,
i, difference;
for (i = 0; i < l; i++) {
difference = a[i] + carry;
carry = Math.floor(difference / base);
difference %= base;
r[i] = difference < 0 ? difference + base : difference;
}
r = arrayToSmall(r);
if (typeof r === "number") {
if (sign) r = -r;
return new SmallInteger(r);
} return new BigInteger(r, sign);
}
BigInteger.prototype.subtract = function (v) {
var n = parseValue(v);
if (this.sign !== n.sign) {
return this.add(n.negate());
}
var a = this.value, b = n.value;
if (n.isSmall)
return subtractSmall(a, Math.abs(b), this.sign);
return subtractAny(a, b, this.sign);
};
BigInteger.prototype.minus = BigInteger.prototype.subtract;
SmallInteger.prototype.subtract = function (v) {
var n = parseValue(v);
var a = this.value;
if (a < 0 !== n.sign) {
return this.add(n.negate());
}
var b = n.value;
if (n.isSmall) {
return new SmallInteger(a - b);
}
return subtractSmall(b, Math.abs(a), a >= 0);
};
SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
NativeBigInt.prototype.subtract = function (v) {
return new NativeBigInt(this.value - parseValue(v).value);
}
NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
BigInteger.prototype.negate = function () {
return new BigInteger(this.value, !this.sign);
};
SmallInteger.prototype.negate = function () {
var sign = this.sign;
var small = new SmallInteger(-this.value);
small.sign = !sign;
return small;
};
NativeBigInt.prototype.negate = function () {
return new NativeBigInt(-this.value);
}
BigInteger.prototype.abs = function () {
return new BigInteger(this.value, false);
};
SmallInteger.prototype.abs = function () {
return new SmallInteger(Math.abs(this.value));
};
NativeBigInt.prototype.abs = function () {
return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
}
function multiplyLong(a, b) {
var a_l = a.length,
b_l = b.length,
l = a_l + b_l,
r = createArray(l),
base = BASE,
product, carry, i, a_i, b_j;
for (i = 0; i < a_l; ++i) {
a_i = a[i];
for (var j = 0; j < b_l; ++j) {
b_j = b[j];
product = a_i * b_j + r[i + j];
carry = Math.floor(product / base);
r[i + j] = product - carry * base;
r[i + j + 1] += carry;
}
}
trim(r);
return r;
}
function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
var l = a.length,
r = new Array(l),
base = BASE,
carry = 0,
product, i;
for (i = 0; i < l; i++) {
product = a[i] * b + carry;
carry = Math.floor(product / base);
r[i] = product - carry * base;
}
while (carry > 0) {
r[i++] = carry % base;
carry = Math.floor(carry / base);
}
return r;
}
function shiftLeft(x, n) {
var r = [];
while (n-- > 0) r.push(0);
return r.concat(x);
}
function multiplyKaratsuba(x, y) {
var n = Math.max(x.length, y.length);
if (n <= 30) return multiplyLong(x, y);
n = Math.ceil(n / 2);
var b = x.slice(n),
a = x.slice(0, n),
d = y.slice(n),
c = y.slice(0, n);
var ac = multiplyKaratsuba(a, c),
bd = multiplyKaratsuba(b, d),
abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
trim(product);
return product;
}
// The following function is derived from a surface fit of a graph plotting the performance difference
// between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
function useKaratsuba(l1, l2) {
return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
}
BigInteger.prototype.multiply = function (v) {
var n = parseValue(v),
a = this.value, b = n.value,
sign = this.sign !== n.sign,
abs;
if (n.isSmall) {
if (b === 0) return Integer[0];
if (b === 1) return this;
if (b === -1) return this.negate();
abs = Math.abs(b);
if (abs < BASE) {
return new BigInteger(multiplySmall(a, abs), sign);
}
b = smallToArray(abs);
}
if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
return new BigInteger(multiplyKaratsuba(a, b), sign);
return new BigInteger(multiplyLong(a, b), sign);
};
BigInteger.prototype.times = BigInteger.prototype.multiply;
function multiplySmallAndArray(a, b, sign) { // a >= 0
if (a < BASE) {
return new BigInteger(multiplySmall(b, a), sign);
}
return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
}
SmallInteger.prototype._multiplyBySmall = function (a) {
if (isPrecise(a.value * this.value)) {
return new SmallInteger(a.value * this.value);
}
return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
};
BigInteger.prototype._multiplyBySmall = function (a) {
if (a.value === 0) return Integer[0];
if (a.value === 1) return this;
if (a.value === -1) return this.negate();
return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
};
SmallInteger.prototype.multiply = function (v) {
return parseValue(v)._multiplyBySmall(this);
};
SmallInteger.prototype.times = SmallInteger.prototype.multiply;
NativeBigInt.prototype.multiply = function (v) {
return new NativeBigInt(this.value * parseValue(v).value);
}
NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
function square(a) {
//console.assert(2 * BASE * BASE < MAX_INT);
var l = a.length,
r = createArray(l + l),
base = BASE,
product, carry, i, a_i, a_j;
for (i = 0; i < l; i++) {
a_i = a[i];
carry = 0 - a_i * a_i;
for (var j = i; j < l; j++) {
a_j = a[j];
product = 2 * (a_i * a_j) + r[i + j] + carry;
carry = Math.floor(product / base);
r[i + j] = product - carry * base;
}
r[i + l] = carry;
}
trim(r);
return r;
}
BigInteger.prototype.square = function () {
return new BigInteger(square(this.value), false);
};
SmallInteger.prototype.square = function () {
var value = this.value * this.value;
if (isPrecise(value)) return new SmallInteger(value);
return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
};
NativeBigInt.prototype.square = function (v) {
return new NativeBigInt(this.value * this.value);
}
function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
var a_l = a.length,
b_l = b.length,
base = BASE,
result = createArray(b.length),
divisorMostSignificantDigit = b[b_l - 1],
// normalization
lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
remainder = multiplySmall(a, lambda),
divisor = multiplySmall(b, lambda),
quotientDigit, shift, carry, borrow, i, l, q;
if (remainder.length <= a_l) remainder.push(0);
divisor.push(0);
divisorMostSignificantDigit = divisor[b_l - 1];
for (shift = a_l - b_l; shift >= 0; shift--) {
quotientDigit = base - 1;
if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
}
// quotientDigit <= base - 1
carry = 0;
borrow = 0;
l = divisor.length;
for (i = 0; i < l; i++) {
carry += quotientDigit * divisor[i];
q = Math.floor(carry / base);
borrow += remainder[shift + i] - (carry - q * base);
carry = q;
if (borrow < 0) {
remainder[shift + i] = borrow + base;
borrow = -1;
} else {
remainder[shift + i] = borrow;
borrow = 0;
}
}
while (borrow !== 0) {
quotientDigit -= 1;
carry = 0;
for (i = 0; i < l; i++) {
carry += remainder[shift + i] - base + divisor[i];
if (carry < 0) {
remainder[shift + i] = carry + base;
carry = 0;
} else {
remainder[shift + i] = carry;
carry = 1;
}
}
borrow += carry;
}
result[shift] = quotientDigit;
}
// denormalization
remainder = divModSmall(remainder, lambda)[0];
return [arrayToSmall(result), arrayToSmall(remainder)];
}
function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
// Performs faster than divMod1 on larger input sizes.
var a_l = a.length,
b_l = b.length,
result = [],
part = [],
base = BASE,
guess, xlen, highx, highy, check;
while (a_l) {
part.unshift(a[--a_l]);
trim(part);
if (compareAbs(part, b) < 0) {
result.push(0);
continue;
}
xlen = part.length;
highx = part[xlen - 1] * base + part[xlen - 2];
highy = b[b_l - 1] * base + b[b_l - 2];
if (xlen > b_l) {
highx = (highx + 1) * base;
}
guess = Math.ceil(highx / highy);
do {
check = multiplySmall(b, guess);
if (compareAbs(check, part) <= 0) break;
guess--;
} while (guess);
result.push(guess);
part = subtract(part, check);
}
result.reverse();
return [arrayToSmall(result), arrayToSmall(part)];
}
function divModSmall(value, lambda) {
var length = value.length,
quotient = createArray(length),
base = BASE,
i, q, remainder, divisor;
remainder = 0;
for (i = length - 1; i >= 0; --i) {
divisor = remainder * base + value[i];
q = truncate(divisor / lambda);
remainder = divisor - q * lambda;
quotient[i] = q | 0;
}
return [quotient, remainder | 0];
}
function divModAny(self, v) {
var value, n = parseValue(v);
if (supportsNativeBigInt) {
return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
}
var a = self.value, b = n.value;
var quotient;
if (b === 0) throw new Error("Cannot divide by zero");
if (self.isSmall) {
if (n.isSmall) {
return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
}
return [Integer[0], self];
}
if (n.isSmall) {
if (b === 1) return [self, Integer[0]];
if (b == -1) return [self.negate(), Integer[0]];
var abs = Math.abs(b);
if (abs < BASE) {
value = divModSmall(a, abs);
quotient = arrayToSmall(value[0]);
var remainder = value[1];
if (self.sign) remainder = -remainder;
if (typeof quotient === "number") {
if (self.sign !== n.sign) quotient = -quotient;
return [new SmallInteger(quotient), new SmallInteger(remainder)];
}
return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
}
b = smallToArray(abs);
}
var comparison = compareAbs(a, b);
if (comparison === -1) return [Integer[0], self];
if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
// divMod1 is faster on smaller input sizes
if (a.length + b.length <= 200)
value = divMod1(a, b);
else value = divMod2(a, b);
quotient = value[0];
var qSign = self.sign !== n.sign,
mod = value[1],
mSign = self.sign;
if (typeof quotient === "number") {
if (qSign) quotient = -quotient;
quotient = new SmallInteger(quotient);
} else quotient = new BigInteger(quotient, qSign);
if (typeof mod === "number") {
if (mSign) mod = -mod;
mod = new SmallInteger(mod);
} else mod = new BigInteger(mod, mSign);
return [quotient, mod];
}
BigInteger.prototype.divmod = function (v) {
var result = divModAny(this, v);
return {
quotient: result[0],
remainder: result[1]
};
};
NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
BigInteger.prototype.divide = function (v) {
return divModAny(this, v)[0];
};
NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
return new NativeBigInt(this.value / parseValue(v).value);
};
SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
BigInteger.prototype.mod = function (v) {
return divModAny(this, v)[1];
};
NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
return new NativeBigInt(this.value % parseValue(v).value);
};
SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
BigInteger.prototype.pow = function (v) {
var n = parseValue(v),
a = this.value,
b = n.value,
value, x, y;
if (b === 0) return Integer[1];
if (a === 0) return Integer[0];
if (a === 1) return Integer[1];
if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
if (n.sign) {
return Integer[0];
}
if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
if (this.isSmall) {
if (isPrecise(value = Math.pow(a, b)))
return new SmallInteger(truncate(value));
}
x = this;
y = Integer[1];
while (true) {
if (b & 1 === 1) {
y = y.times(x);
--b;
}
if (b === 0) break;
b /= 2;
x = x.square();
}
return y;
};
SmallInteger.prototype.pow = BigInteger.prototype.pow;
NativeBigInt.prototype.pow = function (v) {
var n = parseValue(v);
var a = this.value, b = n.value;
var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
if (b === _0) return Integer[1];
if (a === _0) return Integer[0];
if (a === _1) return Integer[1];
if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
if (n.isNegative()) return new NativeBigInt(_0);
var x = this;
var y = Integer[1];
while (true) {
if ((b & _1) === _1) {
y = y.times(x);
--b;
}
if (b === _0) break;
b /= _2;
x = x.square();
}
return y;
}
BigInteger.prototype.modPow = function (exp, mod) {
exp = parseValue(exp);
mod = parseValue(mod);
if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
var r = Integer[1],
base = this.mod(mod);
if (exp.isNegative()) {
exp = exp.multiply(Integer[-1]);
base = base.modInv(mod);
}
while (exp.isPositive()) {
if (base.isZero()) return Integer[0];
if (exp.isOdd()) r = r.multiply(base).mod(mod);
exp = exp.divide(2);
base = base.square().mod(mod);
}
return r;
};
NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
function compareAbs(a, b) {
if (a.length !== b.length) {
return a.length > b.length ? 1 : -1;
}
for (var i = a.length - 1; i >= 0; i--) {
if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
}
return 0;
}
BigInteger.prototype.compareAbs = function (v) {
var n = parseValue(v),
a = this.value,
b = n.value;
if (n.isSmall) return 1;
return compareAbs(a, b);
};
SmallInteger.prototype.compareAbs = function (v) {
var n = parseValue(v),
a = Math.abs(this.value),
b = n.value;
if (n.isSmall) {
b = Math.abs(b);
return a === b ? 0 : a > b ? 1 : -1;
}
return -1;
};
NativeBigInt.prototype.compareAbs = function (v) {
var a = this.value;
var b = parseValue(v).value;
a = a >= 0 ? a : -a;
b = b >= 0 ? b : -b;
return a === b ? 0 : a > b ? 1 : -1;
}
BigInteger.prototype.compare = function (v) {
// See discussion about comparison with Infinity:
// https://github.com/peterolson/BigInteger.js/issues/61
if (v === Infinity) {
return -1;
}
if (v === -Infinity) {
return 1;
}
var n = parseValue(v),
a = this.value,
b = n.value;
if (this.sign !== n.sign) {
return n.sign ? 1 : -1;
}
if (n.isSmall) {
return this.sign ? -1 : 1;
}
return compareAbs(a, b) * (this.sign ? -1 : 1);
};
BigInteger.prototype.compareTo = BigInteger.prototype.compare;
SmallInteger.prototype.compare = function (v) {
if (v === Infinity) {
return -1;
}
if (v === -Infinity) {
return 1;
}
var n = parseValue(v),
a = this.value,
b = n.value;
if (n.isSmall) {
return a == b ? 0 : a > b ? 1 : -1;
}
if (a < 0 !== n.sign) {
return a < 0 ? -1 : 1;
}
return a < 0 ? 1 : -1;
};
SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
NativeBigInt.prototype.compare = function (v) {
if (v === Infinity) {
return -1;
}
if (v === -Infinity) {
return 1;
}
var a = this.value;
var b = parseValue(v).value;
return a === b ? 0 : a > b ? 1 : -1;
}
NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
BigInteger.prototype.equals = function (v) {
return this.compare(v) === 0;
};
NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
BigInteger.prototype.notEquals = function (v) {
return this.compare(v) !== 0;
};
NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
BigInteger.prototype.greater = function (v) {
return this.compare(v) > 0;
};
NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
BigInteger.prototype.lesser = function (v) {
return this.compare(v) < 0;
};
NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
BigInteger.prototype.greaterOrEquals = function (v) {
return this.compare(v) >= 0;
};
NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
BigInteger.prototype.lesserOrEquals = function (v) {
return this.compare(v) <= 0;
};
NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
BigInteger.prototype.isEven = function () {
return (this.value[0] & 1) === 0;
};
SmallInteger.prototype.isEven = function () {
return (this.value & 1) === 0;
};
NativeBigInt.prototype.isEven = function () {
return (this.value & BigInt(1)) === BigInt(0);
}
BigInteger.prototype.isOdd = function () {
return (this.value[0] & 1) === 1;
};
SmallInteger.prototype.isOdd = function () {
return (this.value & 1) === 1;
};
NativeBigInt.prototype.isOdd = function () {
return (this.value & BigInt(1)) === BigInt(1);
}
BigInteger.prototype.isPositive = function () {
return !this.sign;
};
SmallInteger.prototype.isPositive = function () {
return this.value > 0;
};
NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
BigInteger.prototype.isNegative = function () {
return this.sign;
};
SmallInteger.prototype.isNegative = function () {
return this.value < 0;
};
NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
BigInteger.prototype.isUnit = function () {
return false;
};
SmallInteger.prototype.isUnit = function () {
return Math.abs(this.value) === 1;
};
NativeBigInt.prototype.isUnit = function () {
return this.abs().value === BigInt(1);
}
BigInteger.prototype.isZero = function () {
return false;
};
SmallInteger.prototype.isZero = function () {
return this.value === 0;
};
NativeBigInt.prototype.isZero = function () {
return this.value === BigInt(0);
}
BigInteger.prototype.isDivisibleBy = function (v) {
var n = parseValue(v);
if (n.isZero()) return false;
if (n.isUnit()) return true;
if (n.compareAbs(2) === 0) return this.isEven();
return this.mod(n).isZero();
};
NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
function isBasicPrime(v) {
var n = v.abs();
if (n.isUnit()) return false;
if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
if (n.lesser(49)) return true;
// we don't know if it's prime: let the other functions figure it out
}
function millerRabinTest(n, a) {
var nPrev = n.prev(),
b = nPrev,
r = 0,
d, t, i, x;
while (b.isEven()) b = b.divide(2), r++;
next: for (i = 0; i < a.length; i++) {
if (n.lesser(a[i])) continue;
x = bigInt(a[i]).modPow(b, n);
if (x.isUnit() || x.equals(nPrev)) continue;
for (d = r - 1; d != 0; d--) {
x = x.square().mod(n);
if (x.isUnit()) return false;
if (x.equals(nPrev)) continue next;
}
return false;
}
return true;
}
// Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
BigInteger.prototype.isPrime = function (strict) {
var isPrime = isBasicPrime(this);
if (isPrime !== undefined) return isPrime;
var n = this.abs();
var bits = n.bitLength();
if (bits <= 64)
return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
var logN = Math.log(2) * bits.toJSNumber();
var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
for (var a = [], i = 0; i < t; i++) {
a.push(bigInt(i + 2));
}
return millerRabinTest(n, a);
};
NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
BigInteger.prototype.isProbablePrime = function (iterations, rng) {
var isPrime = isBasicPrime(this);
if (isPrime !== undefined) return isPrime;
var n = this.abs();
var t = iterations === undefined ? 5 : iterations;
for (var a = [], i = 0; i < t; i++) {
a.push(bigInt.randBetween(2, n.minus(2), rng));
}
return millerRabinTest(n, a);
};
NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
BigInteger.prototype.modInv = function (n) {
var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
while (!newR.isZero()) {
q = r.divide(newR);
lastT = t;
lastR = r;
t = newT;
r = newR;
newT = lastT.subtract(q.multiply(newT));
newR = lastR.subtract(q.multiply(newR));
}
if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
if (t.compare(0) === -1) {
t = t.add(n);
}
if (this.isNegative()) {
return t.negate();
}
return t;
};
NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
BigInteger.prototype.next = function () {
var value = this.value;
if (this.sign) {
return subtractSmall(value, 1, this.sign);
}
return new BigInteger(addSmall(value, 1), this.sign);
};
SmallInteger.prototype.next = function () {
var value = this.value;
if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
return new BigInteger(MAX_INT_ARR, false);
};
NativeBigInt.prototype.next = function () {
return new NativeBigInt(this.value + BigInt(1));
}
BigInteger.prototype.prev = function () {
var value = this.value;
if (this.sign) {
return new BigInteger(addSmall(value, 1), true);
}
return subtractSmall(value, 1, this.sign);
};
SmallInteger.prototype.prev = function () {
var value = this.value;
if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
return new BigInteger(MAX_INT_ARR, true);
};
NativeBigInt.prototype.prev = function () {
return new NativeBigInt(this.value - BigInt(1));
}
var powersOfTwo = [1];
while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
function shift_isSmall(n) {
return Math.abs(n) <= BASE;
}
BigInteger.prototype.shiftLeft = function (v) {
var n = parseValue(v).toJSNumber();
if (!shift_isSmall(n)) {
throw new Error(String(n) + " is too large for shifting.");
}
if (n < 0) return this.shiftRight(-n);
var result = this;
if (result.isZero()) return result;
while (n >= powers2Length) {
result = result.multiply(highestPower2);
n -= powers2Length - 1;
}
return result.multiply(powersOfTwo[n]);
};
NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
BigInteger.prototype.shiftRight = function (v) {
var remQuo;
var n = parseValue(v).toJSNumber();
if (!shift_isSmall(n)) {
throw new Error(String(n) + " is too large for shifting.");
}
if (n < 0) return this.shiftLeft(-n);
var result = this;
while (n >= powers2Length) {
if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
remQuo = divModAny(result, highestPower2);
result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
n -= powers2Length - 1;
}
remQuo = divModAny(result, powersOfTwo[n]);
return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
};
NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
function bitwise(x, y, fn) {
y = parseValue(y);
var xSign = x.isNegative(), ySign = y.isNegative();
var xRem = xSign ? x.not() : x,
yRem = ySign ? y.not() : y;
var xDigit = 0, yDigit = 0;
var xDivMod = null, yDivMod = null;
var result = [];
while (!xRem.isZero() || !yRem.isZero()) {
xDivMod = divModAny(xRem, highestPower2);
xDigit = xDivMod[1].toJSNumber();
if (xSign) {
xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
}
yDivMod = divModAny(yRem, highestPower2);
yDigit = yDivMod[1].toJSNumber();
if (ySign) {
yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
}
xRem = xDivMod[0];
yRem = yDivMod[0];
result.push(fn(xDigit, yDigit));
}
var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
for (var i = result.length - 1; i >= 0; i -= 1) {
sum = sum.multiply(highestPower2).add(bigInt(result[i]));
}
return sum;
}
BigInteger.prototype.not = function () {
return this.negate().prev();
};
NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
BigInteger.prototype.and = function (n) {
return bitwise(this, n, function (a, b) { return a & b; });
};
NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
BigInteger.prototype.or = function (n) {
return bitwise(this, n, function (a, b) { return a | b; });
};
NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
BigInteger.prototype.xor = function (n) {
return bitwise(this, n, function (a, b) { return a ^ b; });
};
NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
function roughLOB(n) { // get lowestOneBit (rough)
// SmallInteger: return Min(lowestOneBit(n), 1 << 30)
// BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
var v = n.value,
x = typeof v === "number" ? v | LOBMASK_I :
typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
v[0] + v[1] * BASE | LOBMASK_BI;
return x & -x;
}
function integerLogarithm(value, base) {
if (base.compareTo(value) <= 0) {
var tmp = integerLogarithm(value, base.square(base));
var p = tmp.p;
var e = tmp.e;
var t = p.multiply(base);
return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
}
return { p: bigInt(1), e: 0 };
}
BigInteger.prototype.bitLength = function () {
var n = this;
if (n.compareTo(bigInt(0)) < 0) {
n = n.negate().subtract(bigInt(1));
}
if (n.compareTo(bigInt(0)) === 0) {
return bigInt(0);
}
return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
}
NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
function max(a, b) {
a = parseValue(a);
b = parseValue(b);
return a.greater(b) ? a : b;
}
function min(a, b) {
a = parseValue(a);
b = parseValue(b);
return a.lesser(b) ? a : b;
}
function gcd(a, b) {
a = parseValue(a).abs();
b = parseValue(b).abs();
if (a.equals(b)) return a;
if (a.isZero()) return b;