Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs write 64bit unsigned integer to buffer

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 32bit integers as maximum (with buf.write32UInt32BE(value, offset)). So I thought, why can't we just split the 64bit integer?

var buf = new Buffer(8);

buf.fill(0) // clear all bytes of the buffer
console.log(buf); // outputs <Buffer 00 00 00 00 00 00 00 00>

var int = 0xffff; // as dezimal: 65535

buf.write32UInt32BE(0xff, 4); // right the first part of the int
console.log(buf); // outputs <Buffer 00 00 00 00 00 00 00 ff>

buf.write32UInt32BE(0xff, 0); // right the second part of the int
console.log(buf); // outputs <Buffer 00 00 00 ff 00 00 00 ff>

var bufInt = buf.read32UInt32BE(0) * buf.read32UInt32BE(4);
console.log(bufInt); // outputs 65025

As you see this nearly works. The problem is just splitting the 64bit integer and finding the missing 510 at reading it. Would somebody mind showing the solutions for these two issues?

like image 751
bodokaiser Avatar asked Feb 06 '13 14:02

bodokaiser


People also ask

What is the use of buffer in Node JS?

The nodejs Buffer is pretty swell. However, it seems to be geared towards storing strings. The constructors either take a string, an array of bytes, or a size of bytes to allocate.

What is int64be in Node JS?

Tested on node.js v10, v12, v14 and Web browsers. Int64BE is the class to host a 64 bit signed long integer int64_t. It uses Buffer on Node.js and Uint8Array on modern Web browsers.

Is it possible to write a 64-bit integer to a JS number?

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.

How to add 64-bit integers to a buffer?

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.


1 Answers

Reading and writings UINT numbers up to Number.MAX_SAFE_INTEGER.

This works in node.js only, is not portable on browser side.

function uintToBase62(n) {
  if (n < 0) throw 'unsupported negative integer';

  let uintBuffer;
  if (n < 0x7FFFFFFF) {
    uintBuffer = new Buffer(4);
    uintBuffer.writeUInt32BE(n, 0);
  } else {
    // `~~` double bitwise operator
    // The most practical way of utilizing the power of this operator is to use it as a replacement
    // for Math.floor() function as double bitwise NOT performs the same operation a lot quicker.
    // You can use it, to convert any floating point number to a integer without performance overkill
    // that comes with Math.floor(). Additionally, when you care about minification of your code,
    // you end up using 2 characters (2 tildes) instead of 12.
    // http://rocha.la/JavaScript-bitwise-operators-in-practice
    const big = ~~(n / 0x0100000000);
    const low = (n % 0x0100000000);
    uintBuffer = new Buffer(8);
    uintBuffer.writeUInt32BE(big, 0);
    uintBuffer.writeUInt32BE(low, 4);
  }

  return uintBuffer.toString('hex');
}

to convert it

function uintFromBase62(uintBuffer) {
  const n = parseInt(uintBuffer.toString('hex'), 16);
  return n;
}
like image 112
dash1e Avatar answered Oct 13 '22 06:10

dash1e