如何在node.js 10中从缓冲区读取/写入bigint?

问题描述 投票:0回答:5

我看到节点 10 支持 BigInt。但是,Buffer 类中没有 ReadBigInt() 功能。

是否有可能以某种方式绕过它?也许读取 2 个整数,将它们转换为 BigInt,移动上面的一个并将它们相加以重建 bigint?

node.js buffer bigint
5个回答
6
投票

有点晚了,但是由于 BigInt ctor 接受十六进制字符串,我们可以将 Buffer 转换为十六进制字符串并将其传递给

BigInt
ctor。这也适用于数字
> 2 ** 64
并且不需要任何依赖项。

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

4
投票

我最近也遇到了这样做的需要,并设法找到了这个npm库:https://github.com/no2chem/bigint-bufferhttps://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 读取,那么对缓冲区进行切片应该可以。


3
投票

在 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 = buffer[++offset] + buffer[++offset] * 2 ** 8 + buffer[++offset] * 2 ** 16 + last * 2 ** 24; return BigInt(lo) + (BigInt(hi) << 32n); }

编辑:对于有同样问题的其他人,我为此创建了一个包。

https://www.npmjs.com/package/read-bigint


1
投票
一个衬垫:

BigInt('0x'+buffer.toString('hex'))


    


0
投票
您还可以使用

@vekexasia/bigint-uint8array,它为 Node.JS 和浏览器提供实现,并且与其他包不同,支持有符号和无符号的大整数。

例如,使用无符号 bigendian bigint 时:

import { converter } from '@vekexasia/bigint-uint8array'; let arr = converter .unsigned // or .signed if working with signed integers .be // or .le for little endian .toNewArray(42n, 1 /* bytes */); // Uint8Array [ 42 ] let bigint = converter.unsigned.be.toBigInt(arr); // 42n
    
© www.soinside.com 2019 - 2024. All rights reserved.