Как читать / записывать bigint из буфера в node.js 10?

Я вижу, что BigInt поддерживается на узле 10. Однако в классе Buffer нет функции ReadBigInt().

Можно ли как-то обойти это? Возможно, прочитайте 2 целых, приведите их к BigInt, сдвиньте верхний и добавьте их, чтобы восстановить bigint?

4 ответа

Решение

Недавно я столкнулся с необходимостью сделать это, и мне удалось найти эту библиотеку npm: https://github.com/no2chem/bigint-buffer ( https://www.npmjs.org/package/bigint-buffer) который может читать из буфера как BigInt.
Пример использования (чтение, есть больше примеров на связанных github/npm):

const BigIntBuffer = require('bigint-buffer');

let testBuffer = Buffer.alloc(16);
testBuffer[0] = 0xff; // 255

console.log(BigIntBuffer.toBigIntBE(testBuffer));
// -> 338953138925153547590470800371487866880n

Это будет читать 16-байтовое (128-битное) число из буфера. Если вы хотите прочитать только его часть как BigInt, то срез буфера должен работать.

Немного поздно для вечеринки здесь, но поскольку BigInt ctor принимает шестнадцатеричную строку , мы можем просто преобразовать буфер в шестнадцатеричную строку и передать ее в BigIntcтор. Это также работает для чисел > 2 ** 64

      function bufferToBigInt(buffer, start = 0, end = buffer.length) {
  const bufferAsHexString = buffer.slice(start, end).toString("hex");
  return BigInt(`0x${bufferAsHexString}`};
}

В Node v12 были добавлены функции для чтения bigint из буферов, поэтому, если возможно, вы должны попробовать использовать Node v12 или более позднюю версию.

Но эти функции - просто математика, основанная на чтении целых чисел из буфера, так что вы можете скопировать их в код Node 10-11.

https://github.com/nodejs/node/blob/v12.6.0/lib/internal/buffer.js#L78-L152

Таким образом, изменение этих методов, чтобы они не были методами класса, может выглядеть примерно так

function readBigUInt64LE(buffer, offset = 0) {
  const first = buffer[offset];
  const last = buffer[offset + 7];
  if (first === undefined || last === undefined) {
    throw new Error('Out of bounds');
  }

  const lo = first +
    buffer[++offset] * 2 ** 8 +
    buffer[++offset] * 2 ** 16 +
    buffer[++offset] * 2 ** 24;

  const hi = this[++offset] +
    buffer[++offset] * 2 ** 8 +
    buffer[++offset] * 2 ** 16 +
    last * 2 ** 24;

  return BigInt(lo) + (BigInt(hi) << 32n);
}

Один лайнер:BigInt('0x'+buffer.toString('hex'))

Другие вопросы по тегам