gpt4 book ai didi

javascript - BigInteger 到字节的 Uint8Array

转载 作者:行者123 更新时间:2023-11-29 15:16:29 25 4
gpt4 key购买 nike

我需要在 JavaScript 中获取一个大整数的字节。

我尝试了几个大型整数库,但实际提供此功能的那个库不起作用。

我不太确定如何自己实现这个,给定一个包含大量数字的字符串,这通常是库允许访问的内容。

是否有可以运行并允许执行此操作的库?或者它实际上并不难,我只是错过了一些东西?

最佳答案

我在谷歌上搜索用 JavaScript 快速优雅地解决这个问题,但我唯一找到的是基于中间十六进制字符串的转换方法。不幸的是,肯定是次优的,而且该代码对我也不起作用。因此,我实现了自己的代码并想将其发布为我自己问题的答案,但找到了这个。

说明

首先,我将回答相反的问题,因为它更具说明性。

从字节数组中读取 BigInteger

字节数组对我们来说是什么?这是 256 进制数字系统中的数字,我们希望将其转换为更方便的 10 进制(十进制)系统。例如,让我们取一个字节数组
[AA][BB][CC][DD](1 个字节为 8 位或 2 个十六进制数字)。

根据我们从哪一边开始(参见 https://en.wikipedia.org/wiki/Endianness ),我们可以将其解读为:

  • (AA*1 + BB*256 + CC*256^2 + DD*256^3) little-endian
  • big-endian 中的 (DD*1 + CC*256 + BB*256^2 + AA*256^3)。

让我们在这里使用little-endian。所以,我们用数组[AA][BB][CC][DD]编码的数字是:

AA + BB*256 + CC*256^2 + DD*256^3  
= 170 + 187*256 + 204*65536 + 221*16777216
= 170 + 47872 + 13369344 + 3707764736
= 3721182122

将 BigInteger 写入字节数组

为了将一个数字写入字节数组,我们必须执行相反的操作,即在十进制系统中找到一个数字,以在 256 基数字系统中找到它的所有数字。让我们取相同的数字:3721182122

要找到它的最低有效字节 (https://en.wikipedia.org/wiki/Bit_numbering#Least_significant_byte),我们只需将它除以 256。余数代表较高的数字。因此,我们再次将余数除以 256,依此类推,直到余数为 0:

3721182122 = 14535867*256 + 170  
14535867 = 56780*256 + 187
56780 = 221*256 + 204
221 = 0*256 + 221

所以,结果是十进制的 [170][187][204][221],十六进制的 [AA][BB][CC][DD]

JavaScript 中的解决方案

现在,这是使用 big-integer 库在 NodeJS 中编码的算法。

const BigInteger = require('big-integer');

const zero = BigInteger(0);
const one = BigInteger(1);
const n256 = BigInteger(256);

function fromLittleEndian(bytes) {
let result = zero;
let base = one;
bytes.forEach(function (byte) {
result = result.add(base.multiply(BigInteger(byte)));
base = base.multiply(n256);
});
return result;
}

function fromBigEndian(bytes) {
return fromLittleEndian(bytes.reverse());
}

function toLittleEndian(bigNumber) {
let result = new Uint8Array(32);
let i = 0;
while (bigNumber.greater(zero)) {
result[i] = bigNumber.mod(n256);
bigNumber = bigNumber.divide(n256);
i += 1;
}
return result;
}

function toBigEndian(bytes) {
return toLittleEndian(bytes).reverse();
}

console.log('Reading BigInteger from an array of bytes');
let bigInt = fromLittleEndian(new Uint8Array([170, 187, 204, 221]));
console.log(bigInt.toString());

console.log('Writing BigInteger to an array of bytes');
let bytes = toLittleEndian(bigInt);
console.log(bytes);

基准

我已经为这种方法编写了小型基准。欢迎大家修改为自己的转换方式,并与我的进行比较。

https://repl.it/repls/EvenSturdyEquipment

关于javascript - BigInteger 到字节的 Uint8Array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48521840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com