为什么在计算时bigInt会给出不同的结果。 pow()(使用npm big-integer)?如何解密给定号码?

时间:2018-12-04 17:37:53

标签: javascript encryption biginteger

我正在尝试解密我的加密号码。

具有功能

function decrypt(arg){
  let encrypNum =  bigInt(arg).pow(dNum(eNum,eValue)) 
  let result = encrypNum%b
  return result
}

在值中,它看起来像这样:

加密后的值为七个。

结果= 7.pow(103)%143 并且应该返回123,但仍返回38。我以为该数字太大,所以我使用bigInt方法,但仍返回38。

解决该问题的方法应该是(下面不是代码,它的伪代码像伪代码一样,因为我不知道如何用数学写东西。对不起,可以解决这个问题): 7.pow(103)mod 143 = 7.pow(64)+ 7.pow(32)+ 7.pow(4)+ 7.pow(2)+ 7.pow(1)mod 143

等于

113×16×113×49×7 mod 143 = 123

但是为什么我的bigInt方法不起作用,为什么它们显示不同的结果?如果第二种方法是正确的方法,如何在代码中实现呢?

第一个代码:

function decrypt(arg){
  let encrypNum = Math.pow(arg,dNum(eNum,eValue))
  let result = encrypNum%b
  return result
}

1 个答案:

答案 0 :(得分:0)

JavaScript %运算符仅适用于普通JS数字(即IEEE 754 double-precision floating-point numbers),不适用于bigInt对象。因此,当您尝试将%应用于bigInt时,它将首先转换为浮点数。如果bigInt太大而无法用双精度浮点数精确表示,则其最低位将被四舍五入,从而丢弃依赖于它们的所有计算(如%)。

一般的解决方案是使用BigInteger.js .mod()方法而不是原生JavaScript %运算符。但是,对于modular exponentiation的特定情况,您应该使用的是.modPow()方法,因为它的效率要高得多(至少对于通常用于大数的类型而言)用于RSA加密;可能不用于此玩具示例),而不是执行完整的.pow()计算,然后对结果应用.mod()

下面是一个堆栈片段,演示了这些不同的操作:

console.log('bigInt(7).pow(103) =', bigInt(7).pow(103));
console.log('bigInt(7).pow(103).mod(143) =', bigInt(7).pow(103).mod(143));
console.log('bigInt(7).modPow(103, 143) =', bigInt(7).modPow(103, 143));

console.log('Number(bigInt(7).pow(103)) =', Number(bigInt(7).pow(103)));
console.log('Number(bigInt(7).pow(103)) % 143 =', Number(bigInt(7).pow(103)) % 143);
console.log('bigInt(7).pow(103) % 143 =', bigInt(7).pow(103) % 143);
<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>

运行上面的代码片段应该会产生类似以下输出的信息(可能会因使用哪种后端实现BigInteger.js而导致格式上的细微差别):

bigInt(7).pow(103) = "1109425442801291991031214184801374366124020697224286512520326098667350170655466324580343"
bigInt(7).pow(103).mod(143) = "123"
bigInt(7).modPow(103, 143) = "123"
Number(bigInt(7).pow(103)) = 1.109425442801292e+87
Number(bigInt(7).pow(103)) % 143 = 38
bigInt(7).pow(103) % 143 = 38

Ps。最近建议的native JavaScript BigInt objects do 可与%之类的普通JS算术运算符一起使用(尽管两个操作数都必须为BigInt s否则会出错) 。如果您的浏览器支持此功能,则以下内容也应该起作用:

console.log('BigInt(7)**BigInt(103) % BigInt(143) = ' + BigInt(7)**BigInt(103) % BigInt(143) + 'n');
console.log('7n**103n % 143n = ' + 7n**103n % 143n + 'n');

在可以运行上述代码的浏览器上,两个表达式都应求值为BigInt值123n。 (显然,Stack Snippets控制台尚不知道如何正确显示BigInt对象,因此我不得不手动对其进行字符串化处理才能显示结果。)

不幸的是,原生BigInt提议似乎(尚未)包括适当的模块化乘幂例程。因此,为了使用大量的模块化幂,仍建议使用诸如BigInteger.js之类的包装器(如果可用,则应在内部自动使用本机BigInts)。