factor命令打印指定整数NUMBER的素因子。
当我尝试时
factor 12345678912345678912
即使对于这么大的数字,它也会在工厂内产生。
使用哪种算法?
答案 0 :(得分:16)
Gnu coreutils手册通知正在使用Pollard's rho algorithm。
http://www.gnu.org/software/coreutils/manual/html_node/factor-invocation.html
答案 1 :(得分:6)
以下是GNU因子源的一个版本的示例:
http://www.futuretg.com/FTHumanEvolutionCourse/Source/factor.c
它包括试验师和Pollard's rho的惯例。在快速扫描中向我看,好像它使用试验分区找到一些小因素(最多约lg(n)^2
,在这种情况下约为4000),然后Pollard如果剩下的不是可能是素数。在这种情况下,205432623008947
如果我对4000是正确的,即35129 * 5847949643
。
您示例中的第二大素数因子是35129
,最大的平方根在76471
附近。因此,单独的试验分工会很快,因为它只需要尝试大约2.5万名候选人。
答案 2 :(得分:1)
来自source code:
<块引用>算法:
我们更喜欢在分区中使用 Hensel 范数,而不是更熟悉的 欧几里得范数,因为前者会导致更快的代码。在里面 Pollard-Brent rho 代码和素数测试代码,我们使用 Montgomery's 将所有 n 残基乘以词基的技巧,允许廉价的 Hensel 减少 mod n。
GMP 代码使用的算法可能会慢很多; 例如,在大约 2017 年的 Intel Xeon Silver 4116 上,分解 2^{127}-3 使用两字算法需要大约 50 毫秒,但会 使用 GMP 代码大约需要 750 毫秒。
总的来说,factor
的速度非常快。然而,这不是魔法。如果你选择病理上难以分解的数字,它会显着减慢。
RSA encryption 的底层安全性基于分解 2 个大互质数的难度。所以让我们看看我们可以用大互质数推动 factor
有多难。 factor
能够分解的最大数是 2127-1(大概在内部用 int64_t 表示),它恰好是质数:
$ factor $(bc <<< 2^127)
factor: ‘170141183460469231731687303715884105728’ is too large
$ factor $(bc <<< 2^127-1)
170141183460469231731687303715884105727: 170141183460469231731687303715884105727
$ factor $(bc <<< 2^127-2)
170141183460469231731687303715884105726: 2 3 3 3 7 7 19 43 73 127 337 5419 92737 649657 77158673929
$
2127-1 和 2127-2 几乎立即分解; 2127-1很快被发现是素数,而2127-2的因数相对较小。
更难的东西呢? 260 量级的 2 个因子的乘积将接近可以作用的因子的更高阶。那么接下来的 2 个大于 260 的素数怎么样?
$ primes $(bc <<< 2^60) | head -2
1152921504606847009
1152921504606847067
$ bc <<< 1152921504606847009*1152921504606847067
1329227995784916015866073631529372603
$ time factor 1329227995784916015866073631529372603
1329227995784916015866073631529372603: 1152921504606847009 1152921504606847067
real 0m30.628s
user 0m30.578s
sys 0m0.004s
$
因此,随着互质因子位数的增加,分解时间增加得更快。