我正在尝试解密我的加密号码。
具有功能
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
}
答案 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)。