peterolson / BigInteger.js

An arbitrary length integer library for Javascript
The Unlicense
1.12k stars 187 forks source link

Possible Bug: unexpected result when using mod() #180

Closed peshrawahmed closed 5 years ago

peshrawahmed commented 5 years ago

Hi, In one of my projects I created an IBAN validator. as IBAN is a big integer I had to use BigInteger.js to get modulo of two numbers. It was working well until today one of our computers got an error while validating IBAN.

the issue is; when performing bigInteger(6200048300006285407292719).mod(97) it should return 1. But it returns 1n. What does that n means?

Here is the example code we are working on.

const bigInt = require('big-integer');
function isIBAN(value) {
  const ibanMutated = convertLettersToNumber(value.substring(4) + value.substring(0, 4));
  const mod = bigInt(ibanMutated).mod(97).value;
  if (mod === 1) return true;
  return false;
}

function convertLettersToNumber(replaceString) {
  const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  for (var i = 0; i < letters.length; i++) {
    replaceString = replaceString.replace(letters.split('')[i], i + 10);
  }
  return replaceString;
}

This issue is happening on one of our computers. Luckily it works well on our production server.

Environment: macOs Mojave 10.14 Node.js 11.3.0

Hope I have explained the issue well...

Edit: I reproduced the issue on repl.it: https://repl.it/repls/DangerousTrivialNet

peterolson commented 5 years ago

In newer JavaScript environments, there are native BigInts. When this library detects an environment that supports native BigInts, it will work as a wrapper over the native implementation, which will be faster than manupulating an array of numbers.

This is where the 1n you see is coming from. Native BigInts can be created with the BigInt function or by appending n to a number literal.

For your particular issue, the problem is that you are using the .value property that is used for library-internal purposes but is not a documented property meant to be used by end users. You can resolve your issue by using the .toJSNumber() or .valueOf() methods instead.

peshrawahmed commented 5 years ago

Thanks for your detailed response. I am closing the issue.