linux中factor命令背后的算法是什么?

时间:2012-06-22 11:29:30

标签: linux algorithm command

factor命令打印指定整数NUMBER的素因子。

当我尝试时

factor 12345678912345678912
即使对于这么大的数字,它也会在工厂内产生。

使用哪种算法?

3 个答案:

答案 0 :(得分:16)

答案 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

<块引用>

算法:

  1. 使用小的素数表进行试除,但不使用硬件 除法,因为素数表存储以词基为模取反。 (此代码的 GMP 变体不使用预先计算的 相反,而是依靠 GMP 进行快速可分性测试。)
  2. 使用 Miller-Rabin 检查任何非因式分解零件的性质 检测复合,Lucas 检测素数。
  3. 使用 Pollard-Brent rho 分解任何剩余的复合材料零件 算法或者如果 USE_SQUFOF 定义为 1,请先尝试。 使用 Miller-Rabin 和 Lucas 再次检查找到的因素的状态。

我们更喜欢在分区中使用 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
$ 

因此,随着互质因子位数的增加,分解时间增加得更快。