BigInteger 到 Uint8Array 字节

use*_*048 5 javascript arrays biginteger

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

我尝试过几个大整数库,但实际提供此功能的库无法工作。

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

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

Kir*_*ran 3

我在谷歌上搜索 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)小尾数
  • 或 (DD*1 + CC*256 + BB*256^2 + AA*256^3) 中的big-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
Run Code Online (Sandbox Code Playgroud)

将 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  
Run Code Online (Sandbox Code Playgroud)

因此,结果为十进制的 [170][187][204][221],十六进制的结果为[AA][BB][CC][DD] 。

JavaScript 中的解决方案

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

AA + BB*256 + CC*256^2 + DD*256^3  
= 170 + 187*256 + 204*65536 + 221*16777216  
= 170 + 47872 + 13369344 + 3707764736  
= 3721182122
Run Code Online (Sandbox Code Playgroud)

基准

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

https://repl.it/repls/EvenSturdyEquipment