Simple problem. I'm building a Cordova app that among other things verifies the user with an NFC tag. I have to get the data in dec.
I have everything setup but the response I get is off by 8.
I know I can fix it with just adding a +8
but that is just solving the symptom.
Here is my current calculating function:
function intFromBytes( x ){
var result = 0;
var factor = 1;
for (var i = 0; i < x.length; ++i) {
var value = x[i] & 255;
result += value * factor;
factor *= 256;
}
return result;
}
For example the following Array:
0: 4, 1: 117, 2: 64, 3: 114, 4: -23, 5: 51, 6: -126
is converted to 36648824709608700
while I'm expecting (and getting from different NFC applications) 36648824709608708
The problem you're having is related to the way JavaScript numbers are represented. If you look at the value of Number.MAX_SAFE_INTEGER
you'll see that the number you're trying to represent is beyond the limits of JavaScript's Integer precision
From Number.MAX_SAFE_INTEGER on the Mozilla Developer Network site.
The MAX_SAFE_INTEGER constant has a value of 9007199254740991. The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between -(2^53 - 1) and 2^53 - 1.
If you tried this with different NFC tags you'll get responses that out by differing amounts.
You're going to have to use a JS library that can handle big integer values such as big-integer
function bigIntFromBytes(bytes){
var result = bigInt();
var factor = bigInt(1);
for (var i = 0; i < bytes.length; ++i) {
var value = bytes[i] & 255;
result = result.add(bigInt(value).times(factor));
factor = factor.times(256);
}
return result;
}
var bytes = [4, 117, 64, 114, -23, 51, -126];
bigIntFromBytes(bytes).toString(); // gives 36648824709608708