质因数分解

目录

  1. 什么是质因数分解
  2. 逐步算法:试除法
  3. 大数分解的著名算法
  4. 关键公式与性质
  5. 实际应用
  6. 著名数字与故事
  7. 素性测试
  8. 相关工具
  9. 常见问题

1. 什么是质因数分解

质因数分解(Prime Factorization)是将一个大于 1 的正整数表示为若干质数(素数)乘积的过程。例如 360 = 23 × 32 × 5。这不是一种可选的数学技巧——它是整数的本质结构,就像化学分子式揭示了物质的原子组成一样。

算术基本定理(Fundamental Theorem of Arithmetic)

定理

每个大于 1 的正整数都可以唯一地(不考虑因数顺序)表示为质数的乘积。

这个定理有两个关键部分:

历史

欧几里得(Euclid,约公元前 300 年)在《几何原本》第九卷中首次阐述了存在性:每个合数都能被某个质数整除。但他没有证明唯一性。

唯一性的严格证明要等到将近两千年后——卡尔·弗里德里希·高斯(Carl Friedrich Gauss)在 1801 年出版的里程碑著作《Disquisitiones Arithmeticae》(算术研究)中给出了完整证明。这部著作奠定了现代数论的基础。

为什么唯一性如此重要?

如果质因数分解不是唯一的,整个数论体系将会崩塌。例如:

事实上,在某些代数结构(如 ℤ[√-5])中,唯一分解性确实不成立——这正是 Ernst Kummer 和 Richard Dedekind 在 19 世纪发展理想理论(ideal theory)的直接动因。

2. 逐步算法:试除法

试除法(Trial Division)是最古老、最直观的质因数分解算法。它的核心思想极为简单:从最小的质数开始,逐个尝试整除。

算法步骤

  1. 从最小的质数 p = 2 开始。
  2. 如果 n 能被 p 整除(n mod p = 0),则 p 是 n 的一个质因数。记录 p,并令 n = n / p。
  3. 重复步骤 2,直到 n 不再能被 p 整除。
  4. 将 p 增加到下一个质数(3, 5, 7, 11, ...),回到步骤 2。
  5. 当 p × p > n 时停止。如果此时 n > 1,则 n 本身是一个质因数。

为什么只需检查到 √n?

这是一个关键优化,其数学证明如下:

证明

假设 n 是合数,即 n = a × b,其中 1 < a ≤ b < n。
如果 a > √n,那么 b ≥ a > √n,所以 a × b > √n × √n = n,矛盾。
因此 a ≤ √n,即 n 的最小非平凡因子不超过 √n。

这意味着如果在 2 到 √n 的范围内都找不到因子,那么 n 一定是质数。这将搜索空间从 n 缩小到了 √n。

时间复杂度

试除法的时间复杂度为 O(√n)。对于 n = 1012,最多需要检查约 106 个除数——现代计算机可以在毫秒内完成。但对于 n = 10100(如 RSA 密钥),√n = 1050,即使是最快的超级计算机也无法在宇宙寿命内完成。

代码实现(JavaScript)

function trialDivision(n) { const factors = []; for (let p = 2; p * p <= n; p++) { while (n % p === 0) { factors.push(p); n = Math.floor(n / p); } } if (n > 1) factors.push(n); return factors; } // trialDivision(360) → [2, 2, 2, 3, 3, 5]

以 360 为例的完整分解过程

步骤当前值 n除数 p操作结果
13602360 ÷ 2 = 180记录因子 2
21802180 ÷ 2 = 90记录因子 2
390290 ÷ 2 = 45记录因子 2
445245 mod 2 ≠ 0跳过,p → 3
545345 ÷ 3 = 15记录因子 3
615315 ÷ 3 = 5记录因子 3
7533 × 3 = 9 > 5停止,n=5 是质数

结果:360 = 23 × 32 × 5

3. 大数分解的著名算法

试除法对于小数字已经足够,但当数字增长到几十位甚至上百位时,我们需要更高效的算法。下面按历史顺序和复杂度介绍关键算法。

算法发明者年份时间复杂度适用场景
试除法(古代已知)O(√n)小数字(< 1012
埃拉托斯特尼筛法埃拉托斯特尼~前 240 年O(n log log n)生成质数表
费马因式分解皮埃尔·德·费马1643视因子差而定因子接近 √n 时高效
Pollard's RhoJohn Pollard1975O(n1/4)中等大小数字
二次筛法Carl Pomerance1981亚指数级大数(< 100 位)
一般数域筛法 (GNFS)Pollard / Lenstra 等1993亚指数级(最快)最大的数(> 100 位)

埃拉托斯特尼筛法(Sieve of Eratosthenes)

发明者:昔兰尼的埃拉托斯特尼(Eratosthenes of Cyrene),约公元前 240 年。他还以精确测量地球周长而闻名。

思想:不是检验单个数字的素性,而是系统地筛除所有合数。从 2 开始,标记 2 的所有倍数为合数;然后找到下一个未标记的数(3),标记它的所有倍数;以此类推。剩下的未标记数全部是质数。

用途:在质因数分解中,我们可以先用筛法生成质数表,然后只用质数做试除,跳过所有合数除数。

费马因式分解(Fermat's Factorization)

发明者皮埃尔·德·费马(Pierre de Fermat),1643 年。

核心思想:将 n 表示为两个平方数之差:n = a2 - b2 = (a + b)(a - b)。从 a = ⌈√n⌉ 开始,检查 a2 - n 是否为完全平方数。

优势:当 n 的两个因子接近 √n 时(例如 RSA 半素数的两个因子长度接近),费马方法可以极快地找到分解。这也是为什么 RSA 要求两个质因子的大小不能太接近。

Pollard's Rho 算法

发明者John Pollard,1975 年发表。

核心思想:利用伪随机序列和生日悖论。定义迭代函数 f(x) = (x2 + c) mod n,同时维护两个速度不同的迭代器(Floyd 环检测),计算它们差值与 n 的 GCD。当 GCD 不等于 1 也不等于 n 时,就找到了一个非平凡因子。

复杂度:期望 O(n1/4)——远优于试除法的 O(n1/2)。对于 20-25 位的数字效果极佳。

代码:Pollard's Rho(JavaScript)

function pollardRho(n) { if (n % 2 === 0) return 2; let x = 2, y = 2, c = 1, d = 1; while (d === 1) { x = (x * x + c) % n; // tortoise: one step y = (y * y + c) % n; y = (y * y + c) % n; // hare: two steps d = gcd(Math.abs(x - y), n); } return d === n ? null : d; // null → retry with different c } function gcd(a, b) { while (b) { [a, b] = [b, a % b]; } return a; }

二次筛法(Quadratic Sieve)与一般数域筛法(GNFS)

二次筛法Carl Pomerance 于 1981 年提出,是第一个实用的亚指数分解算法。它通过在筛选区间内寻找"光滑数"(只有小质因子的数),构建线性方程组来找到 n 的因子。

一般数域筛法(General Number Field Sieve,GNFS)是目前已知最快的大整数分解算法。它在代数数域中工作,利用格约化(lattice reduction)和复杂的筛选策略。2020 年,GNFS 成功分解了 RSA-250(829 位二进制,250 位十进制),这是目前的世界纪录。

4. 关键公式与性质

一旦得到质因数分解 n = p1a1 × p2a2 × ... × pkak,我们可以直接计算许多重要的数论函数。

约数个数函数 τ(n)

τ(n) = (a1 + 1)(a2 + 1) ··· (ak + 1)

为什么这个公式成立?(组合论证)

n 的任何约数 d 都具有形式 d = p1b1 × p2b2 × ... × pkbk,其中 0 ≤ bi ≤ ai。对于每个质因子 pi,指数 bi 有 (ai + 1) 种选择(从 0 到 ai)。由乘法原理,约数总数 = 各质因子选择数之积。

例子:360 = 23 × 32 × 51,所以 τ(360) = (3+1)(2+1)(1+1) = 4 × 3 × 2 = 24。

约数和函数 σ(n)

σ(n) = ∏i=1..k (piai+1 - 1) / (pi - 1)

推导:对每个质因子 pi,其贡献的约数为 pi0 + pi1 + ... + piai。这是一个等比级数,求和公式为 (piai+1 - 1) / (pi - 1)。由于约数和函数是积性函数,总和等于各质因子贡献之积。

例子:σ(360) = (24-1)/(2-1) × (33-1)/(3-1) × (52-1)/(5-1) = 15 × 13 × 6 = 1170。

欧拉函数 φ(n)

φ(n) = n × ∏i=1..k (1 - 1/pi)

莱昂哈德·欧拉(Leonhard Euler),1763 年引入。欧拉函数 φ(n) 计算 1 到 n 中与 n 互质的正整数个数。

为什么重要

例子:φ(360) = 360 × (1 - 1/2) × (1 - 1/3) × (1 - 1/5) = 360 × 1/2 × 2/3 × 4/5 = 96。

公式汇总表

函数公式τ(360) 示例
约数个数 τ(n)∏(ai + 1)24
约数之和 σ(n)∏(piai+1 - 1)/(pi - 1)1170
欧拉函数 φ(n)n × ∏(1 - 1/pi)96
Liouville λ(n)(-1)∑ai(-1)6 = 1
Mangoldt Λ(n)log p 若 n = pk,否则 00(非质数幂)

5. 实际应用

RSA 加密

RSA(Rivest, Shamir, Adleman,1977)是现代互联网安全的基石。其安全性完全依赖于大整数分解的困难性

原理:选择两个大质数 p 和 q(各约 150-300 位),计算 n = p × q。公钥包含 n,但要从 n 恢复 p 和 q(即分解 n)在计算上极其困难。解密需要 φ(n) = (p-1)(q-1),而计算 φ(n) 等价于分解 n。

当前纪录:RSA-250(250 位十进制,829 位二进制),于 2020 年被分解,耗费约 2700 CPU 年的计算量。现实中使用的 RSA-2048(617 位十进制)在现有技术下被认为是安全的。

量子威胁:Peter Shor 于 1994 年提出的量子算法可以在多项式时间内分解大整数。如果大规模量子计算机实现,RSA 将不再安全——这推动了后量子密码学(post-quantum cryptography)的研究。

GCD 和 LCM 计算

给定两个数的质因数分解:

例如:360 = 23 × 32 × 5,150 = 2 × 3 × 52

分数化简

将分数 a/b 化简为最简形式,本质上就是计算 GCD(a, b) 然后同除。质因数分解让我们可以直观地看到哪些因子可以约去。例如 120/360 = (23×3×5) / (23×32×5) = 1/3。

数论中的应用

6. 著名数字与故事

梅森质数(Mersenne Primes)

形如 Mp = 2p - 1 的质数以法国修道士马林·梅森(Marin Mersenne,1588-1648)命名。梅森于 1644 年声称对 p ≤ 257 列出了所有使 Mp 为质数的 p 值——虽然他的列表有几处错误,但这激发了数百年的研究。

为什么特别:梅森质数是已知最大质数的来源。当前纪录保持者是 282,589,933 - 1(约 2490 万位),由 GIMPS(互联网梅森质数大搜索)项目于 2018 年发现。GIMPS 是一个分布式计算项目,任何人都可以贡献计算资源。

与完美数的联系:欧几里得-欧拉定理告诉我们,每发现一个梅森质数 Mp,就对应一个偶完美数 2p-1 × Mp

费马数(Fermat Numbers)

形如 Fn = 22n + 1 的数。费马观察到 F0=3, F1=5, F2=17, F3=257, F4=65537 都是质数,于是猜想所有费马数都是质数

反例莱昂哈德·欧拉于 1732 年证明 F5 = 4,294,967,297 = 641 × 6,700,417,彻底否定了费马的猜想。此后发现的所有费马数(F5 到 F32)要么被证明是合数,要么素性未知。至今没有发现 F4 之后的费马质数。

有趣的联系:高斯证明正 n 边形可以用尺规作图,当且仅当 n 是 2 的幂与若干不同费马质数的乘积。这就是为什么正 17 边形(F2=17)可以尺规作图,而正 7 边形不行。

孪生质数猜想(Twin Prime Conjecture)

猜想存在无穷多组"孪生质数"——相差 2 的质数对,如 (3,5), (11,13), (29,31), (41,43)。

这个猜想至今未被证明。2013 年,张益唐证明存在无穷多对相差不超过 7000 万的质数,这是重大突破。随后 James Maynard 和 Terence Tao 的 Polymath 项目将这个界缩小到 246。但从 246 到 2 的最后一步仍然遥不可及。

哥德巴赫猜想(Goldbach's Conjecture)

1742 年,普鲁士数学家克里斯蒂安·哥德巴赫在写给欧拉的信中提出:每个大于 2 的偶数都可以表示为两个质数之和。例如:4=2+2, 6=3+3, 8=3+5, 10=3+7=5+5, 100=3+97=11+89=17+83=29+71=41+59=47+53。

这可能是数学中最古老的未解决猜想之一。经计算机验证,所有不超过 4 × 1018 的偶数都满足猜想,但严格证明仍然缺失。

7. 素性测试

素性测试(判断一个数是否为质数)与质因数分解密切相关但有本质区别:判断一个数是否为质数比找到它的因子要容易得多

Miller-Rabin 测试

发明者:Gary L. Miller(1976,确定性版本基于广义黎曼假设)和 Michael O. Rabin(1980,概率版本)。

原理:基于费马小定理的逆否命题。将 n-1 写成 2s × d 的形式,对随机选取的基 a,检查 ad mod n 是否等于 1 或 -1,以及序列 a2d, a4d, ... 中是否出现 -1。

优势:每轮测试的错误概率不超过 1/4。执行 k 轮后,错误概率 ≤ 4-k。20 轮测试的错误概率约 10-12,在实际应用中已足够可靠。时间复杂度 O(k × log2 n × log log n)。

应用:RSA 密钥生成中寻找大质数的标准方法。OpenSSL、GnuPG 等密码库都使用 Miller-Rabin。

AKS 素性测试

发明者Manindra Agrawal、Neeraj Kayal、Nitin Saxena,2002 年(印度理工学院坎普尔分校)。

历史意义

AKS 是第一个被证明的确定性多项式时间素性测试算法。它终结了数学家两千多年来的追问:素性测试是否属于 P 类问题?答案是

原理:基于一个推广的费马小定理:n 是质数当且仅当多项式恒等式 (x + a)n ≡ xn + a (mod n) 成立。AKS 算法巧妙地将这个需要检查指数级多项系数的条件简化为可在多项式时间内验证的形式。

复杂度:O(log6 n)(原始版本),后续改进至 O(log3 n)(在某些猜想下)。

实际应用:虽然理论上是突破性的,但在实际中 AKS 比 Miller-Rabin 慢得多,因此密码学实现仍然首选 Miller-Rabin。AKS 的价值在于其理论意义——它证明了素性测试在计算复杂性理论中的确切地位。

素性测试对比

算法类型复杂度确定性?实际速度
试除法确定性O(√n)小数字快
Miller-Rabin概率性O(k log2 n)否*非常快
AKS确定性O(log6 n)较慢

*Miller-Rabin 在确定性变体中需要广义黎曼假设。

9. 常见问题

1 是质数吗?

不是。按照现代定义,质数必须大于 1 且仅有 1 和自身两个因子。1 被排除在质数之外是为了保证算术基本定理中质因数分解的唯一性。如果 1 被视为质数,那么 6 = 2 × 3 = 1 × 2 × 3 = 12 × 2 × 3 = ...,分解将不再唯一。

质因数分解可以用于负数或 0 吗?

算术基本定理仅适用于大于 1 的正整数。对于负数,可以先取绝对值再分解,然后附加一个 -1 的符号。0 不能被质因数分解,因为它可以被任何数整除。

质因数分解是 NP 难问题吗?

令人惊讶的是,不是——至少没有被证明是。整数分解被认为处于 NP 和 co-NP 的交集中,但不太可能是 NP 完全的(如果它是 NP 完全的,则 NP = co-NP,这与主流猜想矛盾)。Shor 的量子算法表明它在 BQP 中,说明它可能比传统 NP 难问题"更容易"。

这个计算器能处理多大的数字?

本工具使用 JavaScript 的 BigInt,可以精确处理任意大小的整数。但由于使用试除法,对于超过 15 位的数字,分解速度可能会明显变慢。对于超大数字(如 RSA 级别),需要使用专门的数论软件如 PARI/GP、Mathematica 或 SageMath。

量子计算机会让质因数分解变得简单吗?

理论上是的。Peter Shor 于 1994 年提出的量子分解算法可以在 O((log n)3) 时间内分解 n,远快于任何已知经典算法。但截至 2026 年,实际的量子计算机还无法分解超过几十位的数字。IBM、Google 等公司正在积极研发,但大规模容错量子计算机仍需多年发展。与此同时,NIST 已于 2024 年发布了后量子密码标准,以应对未来的量子威胁。