加速我的费马分解函数(Python)

加速我的费马分解函数(Python),python,factorization,Python,Factorization,我的任务是使用因子分解非常大的复合数。这些数字是1024位,大约是309位十进制数字 我已经提出了下面的Python代码,它使用模块来保证准确性。它只是上显示的伪代码的Python实现。我读了那页上的“”部分,但不确定如何实现它 def fermat_factor(n): assert n % 2 != 0 # Odd integers only a = gmpy2.ceil(gmpy2.sqrt(n)) b2 = gmpy2.square(a) - n wh

我的任务是使用因子分解非常大的复合数。这些数字是1024位,大约是309位十进制数字

我已经提出了下面的Python代码,它使用模块来保证准确性。它只是上显示的伪代码的Python实现。我读了那页上的“”部分,但不确定如何实现它

def fermat_factor(n):
    assert n % 2 != 0  # Odd integers only

    a = gmpy2.ceil(gmpy2.sqrt(n))
    b2 = gmpy2.square(a) - n
    while not is_square(b2):
        a += 1
        b2 = gmpy2.square(a) - n

    factor1 = a + gmpy2.sqrt(b2)
    factor2 = a - gmpy2.sqrt(b2)
    return int(factor1), int(factor2) 

def is_square(n):
    root = gmpy2.sqrt(n)
    return root % 1 == 0  # '4.0' will pass, '4.1212' won't

对于较小的数字,此代码运行得相当快,但对于问题中给定的较大数字,此代码运行的时间太长。如何提高此代码的速度?我不是在找人为我写代码的人,但如果能给我一些建议,我将不胜感激。感谢您的回复。

请考虑重写此脚本,以便仅使用整数而不是任意精度浮点

gmpy支持整数平方根(返回有效计算的平方根下限)。这可以通过测试平方根的平方是否等于原始值来用于is_square()函数

我不确定gmpy2,但在gmpy.sqrt()中需要一个整数参数,并返回一个整数输出。如果您使用的是浮点数,那么这可能就是您的问题(因为浮点数与整数相比非常慢,尤其是在使用扩展精度时)。如果您实际上使用的是整数,那么每次调用is_square()时,它都必须执行从整数到浮点的繁琐转换(并且gmpy2.sqrt()!=gmpy.sqrt())

对于那些一直说这是一个难题的人,请记住,使用这种方法是一个提示:费马分解算法基于一个弱点,当要分解的复合数有两个彼此接近的素因子时。如果这是一个提示,那么提出问题的实体很可能知道情况就是这样


编辑:显然,gmpy2.isqrt()与gmpy.sqrt()相同(sqrt的整数版本),而gmpy2.sqrt()是浮点版本。

您需要避免执行太多的平方和sqrt操作,尤其是对大数

避免它们的简单方法是注意,a^2-N=b^2必须为真,所有模才能成为解。比如说,

a^2模9-N模9=b^2模9

假设你的N是55,那么N模9=1

现在考虑一组(mod 9),并将它平方,模9。 生成的^2 mod 9是集合:{0,1,4,7}。对于b^2 mod 9也必须如此

如果^2模9=0,那么0-1=8(所有模9)不是一个解,因为8不是模9的数字的平方。这消除了(mod 9)={0、3和6}

如果a^2 mod 9=1,则1-1=0(所有mod 9),因此(a mod 9)={1,8}是可能的解决方案

如果^2模9=4,则4-1=3(所有模9)不是可能的解决方案。 对于^2模块9=7,同上

所以,一个模数消除了9个可能的'a mod 9'值中的7个

你可以有很多模,每一个都至少消除了一半的可能性。 对于一组,比如说,10个模,你只需要检查1000个a中的1个是否是完美的平方,或者是否有整数平方根。(我在工作中使用了大约10000个模)

注:模是素数的幂,通常比素数更有用。 此外,模数16是一个有用的特例,因为当N mod 4为1时,“a”必须是奇数,
当N mod 4为3时,a必须为偶数。“证明留作学生练习。”

神圣的烟雾,这使我的功能快了8倍左右!我所要做的就是用
gmpy2.isqrt
替换
gmpy2.sqrt
,并删除
gmpy2.ceil
。非常感谢。