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
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);