Search code examples
javascriptcordovadecimalnfc

Cordova NFC getting NFC tag value in dec


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


Solution

  • 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