加快我的费马分解功能(Python)
作者:互联网
我的任务是使用Fermat’s factorization method计算非常大的复合数.这些数字是1024位大,大约是309个十进制数字.
我已经提出了下面的Python代码,它使用gmpy2
模块来提高准确性.它只是Wikipedia page上显示的伪代码的Python实现.我在该页面上阅读了“Sieve Improvement”部分,但不确定如何实现它.
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()).
对于那些一直说这是一个难题的人,请记住使用这种方法是一个暗示:fermat分解算法基于当要考虑的复合数具有两个接近于的因素时存在的弱点彼此.如果这是作为提示给出的,则构成问题的实体很可能知道这种情况.
编辑:显然,gmpy2.isqrt()与gmpy.sqrt()(sqrt的整数版本)相同,而gmpy2.sqrt()是浮点版本.
标签:factorization,python 来源: https://codeday.me/bug/20190823/1696201.html