【问题标题】:BigInteger exponentiation with BigInteger number: ArithmeticException, would overflow supported rangeBigInteger 指数与 BigInteger 数:ArithmeticException,会溢出支持的范围
【发布时间】:2021-07-13 13:01:30
【问题描述】:

我正在构建 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,而不是先使用pow,然后再使用mod
  • 原来有 mathematical tricks 可以用来计算 a^b mod c 形式的东西,当通过蛮力计算时会产生非常大的数字,而 modPow 正好使用那些技巧。
  • @luk2302 当文档与我实现的文档不同时,我很难使用 modPow
  • 我建议您edit 您的问题来准确解释您是如何“遇到困难”以及“文档与我实施的文档有何不同”。

标签: java exponentiation dsa


【解决方案1】:

要扩展我的评论并且因为我找不到重复:使用modPow

这里的问题是g^u1(和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)。

【讨论】:

  • u1.intValue() -> u1u2.intValue() -> u2。见modPow
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
相关资源
最近更新 更多