You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用gmpy2的Python程序崩溃(Scala可运行):mpz溢出/核心转储

gmpy2模幂运算程序崩溃问题排查

我在使用gmpy2库运行模幂运算时遇到程序崩溃问题,但相同逻辑在Scala中用BigInteger.modPow()能正常运行并输出'good'。想确认这是gmpy2的已知bug,还是我的Python代码存在错误?

Scala 可正常运行代码

import java.math.BigInteger

import java.nio.charset.StandardCharsets
import java.util.Base64


object Example extends App {
  val pstr: String ="134078079299425970995740249982058461274793658205923933" +
    "77723561443721764030073546976801874298166903427690031" +
    "858186486050853753882811946569946433649006084171"
  val gstr = "11717829880366207009516117596335367088558084999998952205"  +
    "59997945906392949973658374667057217647146031292859482967"  +
    "5428279466566527115212748467589894601965568"
  val hstr = "323947510405045044356526437872806578864909752095244"  +
    "952783479245297198197614329255807385693795855318053"  +
    "2878928001494706097394108577585732452307673444020333"


  val decodedBytes = Base64.getDecoder.decode("Mzc1Mzc0MjE3ODMw")
  val decodedString = new String(decodedBytes, StandardCharsets.UTF_8)     // obfuscated ... can't fall into wrong hands

  val p: BigInteger = new BigInteger(pstr)
  val g: BigInteger = new BigInteger(gstr)
  val h: BigInteger = new BigInteger(hstr)
  val exponent: BigInteger = new BigInteger(decodedString)

  val recover = g.modPow(exponent, p)

  if (recover == h)
    print("good")
  else
    print("bad")
}

Python 崩溃代码

import gmpy2
import base64

pstr = "134078079299425970995740249982058461274793658205923933" + \
       "77723561443721764030073546976801874298166903427690031" + \
       "858186486050853753882811946569946433649006084171"

gstr = "11717829880366207009516117596335367088558084999998952205" + \
       "59997945906392949973658374667057217647146031292859482967" + \
       "5428279466566527115212748467589894601965568"

hstr = "323947510405045044356526437872806578864909752095244" + \
       "952783479245297198197614329255807385693795855318053" + \
       "2878928001494706097394108577585732452307673444020333"

p = gmpy2.mpz(pstr)
g = gmpy2.mpz(gstr)
h = gmpy2.mpz(hstr)

secret_exponent_encoded = base64.b64decode(b'Mzc1Mzc0MjE3ODMw').decode('utf-8')
exponent = gmpy2.mpz(secret_exponent_encoded)
recover = (g ** exponent) % p

if (recover == h):
    print("true")
else:
    print("false")

问题原因与修正

崩溃的核心原因是Python代码中使用了(g ** exponent) % p的写法:这种方式会先计算g的exponent次幂,生成一个极其庞大的中间值,直接耗尽内存导致程序崩溃。而Scala的BigInteger.modPow()是高效模幂运算,会在计算过程中持续取模,不会生成超大中间值。

gmpy2同样提供了高效的模幂实现,只需将崩溃代码中的模幂计算替换为gmpy2.pow(g, exponent, p)即可。

修正后的Python代码:

import gmpy2
import base64

pstr = "134078079299425970995740249982058461274793658205923933" + \
       "77723561443721764030073546976801874298166903427690031" + \
       "858186486050853753882811946569946433649006084171"

gstr = "11717829880366207009516117596335367088558084999998952205" + \
       "59997945906392949973658374667057217647146031292859482967" + \
       "5428279466566527115212748467589894601965568"

hstr = "323947510405045044356526437872806578864909752095244" + \
       "952783479245297198197614329255807385693795855318053" + \
       "2878928001494706097394108577585732452307673444020333"

p = gmpy2.mpz(pstr)
g = gmpy2.mpz(gstr)
h = gmpy2.mpz(hstr)

secret_exponent_encoded = base64.b64decode(b'Mzc1Mzc0MjE3ODMw').decode('utf-8')
exponent = gmpy2.mpz(secret_exponent_encoded)
# 使用gmpy2内置的高效模幂函数
recover = gmpy2.pow(g, exponent, p)

if recover == h:
    print("true")
else:
    print("false")

内容的提问来源于stack exchange,提问作者Chris Bedford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:27:33