Nodejs write unsigned 64-bit integer to buffer

I want to store a 64-bit (8 bytes) large integer with a nodejs node object in large end format.

The problem with this task is that the nodejs buffer only supports the maximum write of 32-bit integers (with buf.write32UInt32BE (value, offset)). So why can't I just smash a 64-bit 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 can see, this almost works. The problem is simply to split the 64-bit integer and find the missing 510 when reading it. Anyone think about showing solutions to these two issues?

+5
source share
5 answers

I think you are looking for:

var bufInt = (buf.readUInt32BE(0) << 8) + buf.readUInt32BE(4);

Shift the first number by 8 bits and add (instead of multiplying) which returns 65535


:

var buf = new Buffer(8);
buf.fill(0);

var i = 0xCDEF; // 52719 in decimal

buf.writeUInt32BE(i >> 8, 0); //write the high order bits (shifted over)
buf.writeUInt32BE(i & 0x00ff, 4); //write the low order bits

console.log(buf); //displays: <Buffer 00 00 00 cd 00 00 00 ef>

var bufInt = (buf.readUInt32BE(0) << 8) + buf.readUInt32BE(4);
console.log(bufInt); //displays: 52719
+6

, 0xFFFF - 16-, 64-.

, JS number IEEE754, 64- . 64- , , bignum. readme .

2^53 - 1 . , JS:

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

18446744073709552000, 18446744073709551615.

var bignum = require('bignum');

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

BigNum 18446744073709551615.

, , , , 16-, 32- . :

var buf = new Buffer(2);

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

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 <Buffer ff ff>

// 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);
+1

/ 64- :

const int64 = Date.now()   // 1456909977176 (00 00 01 53 36 9a 06 58)
const b = new Buffer(8)
const MAX_UINT32 = 0xFFFFFFFF

// write
const big = ~~(int64 / MAX_UINT32)
const low = (int64 % MAX_UINT32) - big

b.writeUInt32BE(big, 0)  // 00 00 01 53 00 00 00 00
b.writeUInt32BE(low, 4)  // 00 00 01 53 36 9a 06 58

// read
var time = parseInt(b.toString('hex'), 16)
time == int64 // true

- .

UPDATE

<= Number.MAX_SAFE_INTEGER

+1
// sending time
var sending_time = new Date().getTime();
buffer.writeInt32LE(parseInt(sending_time & 0xffffffff, 10), 16);
buffer.writeInt32LE(parseInt(sending_time / 0xffffffff, 10), 20);
0

JavaScript/EcmaScript ( ) 32- .

bignum , 32- .

var bignum = require('bignum');

//max safe integer to big number
var num = bignum(Number.MAX_SAFE_INTEGER.toString());
var buf = num.toBuffer({endian:'big',size:8 /*8-byte / 64-bit*/});

console.log(buf); // 

In the above example Number.MAX_SAFE_INTEGER, which is equal to is used Math.pow(2,53)-1. If you need to use large numbers, you should refer to them as bignum strings ... if you can stay within integers in JS, you can save them and convert as above.

0
source

All Articles