java - BigInteger 指数与 BigInteger 数:ArithmeticException,会溢出支持的范围
问题描述
我正在构建 DSA 算法。但是在将 BigInteger 数字与其他 BigInteger 数字进行排名时遇到了问题。这是我要使用的公式:
v = ((g^u1 * y^u2) mod p) mod q
这是我制作的代码:
BigInteger v = g.pow(u1.intValue()).multiply(y.pow(u2.intValue())).mod(p).mod(q);
运行脚本时,错误是:
Exception in thread "main" java.lang.ArithmeticException: BigInteger would overflow supported range
at java.math.BigInteger.reportOverflow(Unknown Source)
at java.math.BigInteger.pow(Unknown Source)
at DSAVerifying.main(DSAVerifying.java:38)
解决方案
扩展我的评论并且因为我找不到重复:使用modPow
!
这里的问题是g^u1
(and y^u2
) 真的很大。但是在处理数学中的幂时,通常会在其后加上一个 mod 语句,这大大简化了事情:通常a ^ b mod c
可以表示为((((a * a) mod c) * a) mod c) * a) mod c .....
(b 次)。这基本上就是modPow
这样做的,它mod
在指数期间应用。这将返回相同的数字,但不会溢出。它们在数学上是相同的,但其中一个可以通过计算机通过合理的努力进行计算,而另一个则不能。作为开发人员,您需要聪明并以计算机可以正确处理的方式简化或改写您想要解决的表达式。
BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
基本上要计算(6 ^ 10 mod 7)
,您永远不想先计算6 ^ 10
然后应用,mod 7
而是这样做6 * 6 mod 7 = 36 mod 7 = 1 => 1 * 6 mod 7 = 6 => 6 * 6 mod 7 = 36 mod 7 = 1 => ...
,您可以看到您处理的唯一值是 1 和 6 而不是60466176
(即6^10
)。
推荐阅读
- ios - 使用模糊背景突出显示 UIButton 会导致透明度丢失
- react-native - 如何更新 Animated.Value 以在没有动画的情况下更改?
- python - 具有多个值的字典到元组
- java - 如何从 ArrayList 中按键获取值?
- php - Laravel 5.5.40 验证 - 检查输入以字符串结尾(正则表达式)
- android - 初始化“com.android.tools.idea.AndroidInitialConfigurator”的致命错误
- aws-lambda - 将项目放入 DynamoDB 时出错:“将循环结构转换为 JSON”
- angular - 使用 Angular,Typescript 数组在某些情况下会显示为空,而在其他情况下则不会
- javascript - PHP echo javascript - 不回显 $
- ionic3 - Ionic 3 组件插入图像