如何用python计算大数?

时间:2014-02-21 21:52:00

标签: python numpy

我目前正在尝试找到x的值,

x = (math.log(X) - math.log(math.fabs(p))/math.log(g))

with:

X = 53710695204323513509337733909021562547350740845028323195225592059762435955297110591848019878050853425581981564064692996024279718640577281681757923541806197728862534268310235863990001242041406600195234734872865710114622767319497082014412908147635982838670976889326329911714511434374891326542317244606912177994106645736126820796903212224

p = 79293686916250308867562846577205340336400039290615139607865873515636529820700152685808430350565795397930362488139681935988728405965018046160143856932183271822052154707966219579166490625165957544852172686883789422725879425460374250873493847078682057057098206096021890926255094441718327491846721928463078710174998090939469826268390010887

g = 73114111352295288774462814798129374078459933691513097211327217058892903294045760490674069858786617415857709128629468431860886481058309114786300536376329001946020422132220459480052973446624920516819751293995944131953830388015948998083956038870701901293308432733590605162069671909743966331031815478333541613484527212362582446507824584241

不幸的是,python无法处理如此大的数字。

有人知道解决这个问题的方法吗?

感谢您的帮助。


修改

因为很多你不知道我想要做什么:

为了能够以安全的方式进行通信,Alice和Bob继续进行Diffie-Hellman密钥交换。为此,他们使用素数p:

p = 79293686916250308867562846577205340336400039290615139607865873515636529820700152685808430350565795397930362488139681935988728405965018046160143856932183271822052154707966219579166490625165957544852172686883789422725879425460374250873493847078682057057098206096021890926255094441718327491846721928463078710174998090939469826268390010887

整数g:

g = 73114111352295288774462814798129374078459933691513097211327217058892903294045760490674069858786617415857709128629468431860886481058309114786300536376329001946020422132220459480052973446624920516819751293995944131953830388015948998083956038870701901293308432733590605162069671909743966331031815478333541613484527212362582446507824584241

Alice选择密码x,她计算X = g ^ x mod p并通过不安全的通道将X发送给Bob。 Bob选择密码y,他计算Y = g ^ y mod p并通过相同的不安全信道将Y发送给Alice。 两者都可以计算值Z = X ^ y = Y ^ x = g ^ xy mod p

通过监视频道,查理检索X和Y的值:

X = 53710695204323513509337733909021562547350740845028323195225592059762435955297110591848019878050853425581981564064692996024279718640577281681757923541806197728862534268310235863990001242041406600195234734872865710114622767319497082014412908147635982838670976889326329911714511434374891326542317244606912177994106645736126820796903212224

Y = 17548462742338155551984429588008385864428920973169847389730563268852776421819130212521059041463390276608317951678117988955994615505741640680466539914477079796678963391138192241654905635203691784507184457129586853997459084075350611422541722123509121359133932497700621300814065254996649070135358792927275914472632707420292830992294921992

这个练习的关键是Z

值的md5sum

3 个答案:

答案 0 :(得分:7)

您可以使用Decimal库执行此操作:

from decimal import Decimal

X = 53710695204323513509337733909021562547350740845028323195225592059762435955297110591848019878050853425581981564064692996024279718640577281681757923541806197728862534268310235863990001242041406600195234734872865710114622767319497082014412908147635982838670976889326329911714511434374891326542317244606912177994106645736126820796903212224
p = 79293686916250308867562846577205340336400039290615139607865873515636529820700152685808430350565795397930362488139681935988728405965018046160143856932183271822052154707966219579166490625165957544852172686883789422725879425460374250873493847078682057057098206096021890926255094441718327491846721928463078710174998090939469826268390010887
g = 73114111352295288774462814798129374078459933691513097211327217058892903294045760490674069858786617415857709128629468431860886481058309114786300536376329001946020422132220459480052973446624920516819751293995944131953830388015948998083956038870701901293308432733590605162069671909743966331031815478333541613484527212362582446507824584241
X=Decimal(X)
p=Decimal(p)
g=Decimal(g)

print X.ln() - abs(p).ln()/g.ln()

给出

769.7443428855116199351294830

答案 1 :(得分:2)

Sympy可能对您有意义。您可以进行符号简化并调整要使用的精度(使用mpmath):

import sympy as sy
sy.init_printing() # enable pretty printing in IPython

# Build the expression:
X,p,g = sy.symbols('X,p,g')
expr = (sy.log(X) - sy.log(sy.Abs(p))/sy.log(g))
# expr = expr.simplify()  # doesn't have any benefit in this case

# The values:
vX = 53710695204323513509337733909021562547350740845028323195225592059762435955297110591848019878050853425581981564064692996024279718640577281681757923541806197728862534268310235863990001242041406600195234734872865710114622767319497082014412908147635982838670976889326329911714511434374891326542317244606912177994106645736126820796903212224
vp = 79293686916250308867562846577205340336400039290615139607865873515636529820700152685808430350565795397930362488139681935988728405965018046160143856932183271822052154707966219579166490625165957544852172686883789422725879425460374250873493847078682057057098206096021890926255094441718327491846721928463078710174998090939469826268390010887
vg = 73114111352295288774462814798129374078459933691513097211327217058892903294045760490674069858786617415857709128629468431860886481058309114786300536376329001946020422132220459480052973446624920516819751293995944131953830388015948998083956038870701901293308432733590605162069671909743966331031815478333541613484527212362582446507824584241

# substitute values into variables:
expr2 = expr.subs({X:vX, p:vp,g:vg})

# evaluate to 150 digits with internal precision up to 1000 digits:
print(expr2.evalf(n=150, maxn=1000))
结果

    769.744342885511619935129482917192487900343653888850271462255718268257261969359878869753342583593581927254506121925469662801405523964742213571689617098

更新正如casevh和David所说,在使用sympy时,应注意使用普通浮点数作为输入而不会失去准确性。为了澄清,让我们计算10**log10(10+1e-30),这显然会产生10 + 1e-30:

import sympy as sy
import numpy as np

xf = 1e-30

# numpy with floats:
np_x1 = np.log10(10+ xf)
np_yf = 10**np_x1

# sympy with no extra benefit
sy1_x1 = sy.log(10 + xf) / sy.log(10)
sy1_ye = 10**sy1_x1
sy1_yf = sy1_ye.evalf(n=33)

# sympy, done right:
x = sy.symbols('x')
sy2_x1 = sy.log(10 + x) / sy.log(10)
sy2_ye = 10**sy2_x1
sy2_yf = sy2_ye.evalf(n=33, subs={x:xf})

print("correct answer: 10.0000000000000000000000000000010")
print("        numpy:  {:.31f}".format(np_yf))
print("  naive sympy:  " + repr(sy1_yf))
print("correct sympy:  " + repr(sy2_yf))

结果如下:

correct answer: 10.0000000000000000000000000000010
        numpy:  10.0000000000000000000000000000000
  naive sympy:  10.0000000000000017763568394002504
correct sympy:  10.0000000000000000000000000000010

答案 2 :(得分:0)

"机器epsilon"对于numpy float64 dtype约为2.2e-16。这意味着您应该只期望结果中的前16位有效数字是准确的,除非您正在做一些非常棘手的事情(比如滚动您自己的自定义数据类型)。

Dietrich建议使用sympy并设置高内部精度,但sympy documentation证实这不会逃脱机器epsilon问题。

  

某些Python浮点数仅精确到15位数作为输入,而其他(具有2的幂的分母,如.125 = 1/4)是准确的。

换句话说,要非常小心你使用与你的数字一样大的数据,因为只要你使用64位浮点数进行数学运算,只有前16位有效数字才有意义。