nodejs write 64bit unsigned integer to buffer

后端 未结 6 759
遥遥无期
遥遥无期 2021-02-14 03:08

I want to store a 64bit (8 byte) big integer to a nodejs buffer object in big endian format.

The problem about this task is that nodejs buffer only supports writing 32bi

6条回答
  •  醉酒成梦
    2021-02-14 04:01

    I'm confused because your example value of 0xFFFF is only 16-bit, not 64-bit.

    Keep in mind that the JS number type is specified as an IEEE754 floating-point value, so it is not guaranteed to be able to hold a 64-bit unsigned value. If you want real 64-bit integer support, you need to use a module to provide it, like bignum. The readme for that has examples of reading and writing values to buffers.

    Floating-point values can only represent values up to 2^53 - 1 without losing precision. You can see that in this example using standard JS numbers:

    var b = new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
    var firstHalf = b.readUInt32BE(0); // 4294967295
    var secondHalf = b.readUInt32BE(4); // 4294967295
    
    var val = firstHalf * 0x100000000 + secondHalf; // 18446744073709552000
    

    The result of this is 18446744073709552000 when the proper value is 18446744073709551615.

    var bignum = require('bignum');
    
    var b = new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
    var val = bignum.fromBuffer(b);
    

    This results in a BigNum object with the value 18446744073709551615.

    Also, to elaborate on your example code, the value you are using is only 16-bit, and you are trying to work with it using 32-bit functions. You can just do this:

    var buf = new Buffer(2);
    
    buf.fill(0) // clear all bytes of the buffer
    console.log(buf); // outputs 
    
    var int = 0xffff; // as decimal: 65535
    
    // Write it with a standard 16-bit function calls.
    buf.writeUInt16BE(int);
    
    // OR write it with 2 8-bit function calls.
    buf.writeUInt8(int & 0xff, 0); // right the first part of the int
    buf.writeUInt8((int >> 8) & 0xFF, 1); // right the second part of the int
    console.log(buf); // outputs 
    
    // Read it as a 16-bit value.
    var bufInt = buf.readUInt16BE(0);
    console.log(bufInt);
    
    // OR read it as two 8-bit values.
    var bufInt = (buf.readUInt8(1) << 8) + buf.readUInt8(0);
    

提交回复
热议问题