有人可以向我解释 Dixon 分解算法的这一部分吗?
Can someone explain to me this part of Dixon's factorization algorithm?
我一直在尝试在 python 中实现 Dixon 的因式分解方法,但我有点困惑。我知道你需要给出一些边界 B
和一些数字 N
并搜索 sqrtN
和 N
之间的数字,其平方是 B-smooth
,这意味着他们所有的因子在小于或等于 B
的素数集中。我的问题是,给定一定大小的 N
,是什么决定了 B
以便算法产生 N
的非平凡因子? Here 是一篇关于该算法的维基百科文章,如果有帮助,这是我的实现代码:
def factor(N, B):
def isBsmooth(n, b):
factors = []
for i in b:
while n % i == 0:
n = int(n / i)
if not i in factors:
factors.append(i)
if n == 1 and factors == b:
return True
return False
factor1 = 1
while factor1 == 1 or factor1 == N:
Bsmooth = []
BsmoothMod = []
for i in range(int(N ** 0.5), N):
if len(Bsmooth) < 2 and isBsmooth(i ** 2 % N, B):
Bsmooth.append(i)
BsmoothMod.append(i ** 2 % N)
gcd1 = (Bsmooth[0] * Bsmooth[1]) % N
gcd2 = int((BsmoothMod[0] * BsmoothMod[1]) ** 0.5)
factor1 = gcd(gcd1 - gcd2, N)
factor2 = int(N / factor1)
return (factor1, factor2)
也许有人也可以帮我清理一下代码?看起来效率很低
本文讨论了 B 的最佳大小:https://web.archive.org/web/20160205002504/https://vmonaco.com/dixons-algorithm-and-the-quadratic-sieve/。简而言之,最优值被认为是 exp((logN loglogN)^(1/2)).
[我写这篇文章的目的不同,但您可能会发现它很有趣。 ]
给定x2 ≡ y2 (mod n) with x ≠ ± y, gcd的时间大约是一半(x−y,n)是n[=69的因数=]. Maurice Kraitchik 在 1920 年代观察到的这种 正方形同余 是多种因式分解方法的基础。 John Dixon 提出的其中一种方法在理论上很重要,因为它的次指数 运行 时间可以得到证明,尽管它在实践中太慢而无用。
Dixon 的方法从选择边界 b 开始。 e√(log n log log n) 和识别小于 b 的所有素数的 factor base,它们是 n 的二次留数(它们的 jacobi 符号是 1).
function factorBase(n, b)
fb := [2]
for p in tail(primes(b))
if jacobi(n, p) == 1
append p to fb
return fb
然后在 1 < r < n 范围内重复选择一个整数 r,计算其平方 modulo n,如果平方在因子基上平滑,则将其添加到 relations 列表中,停止当因子库中的关系多于因子时,为那些失败的情况加上少量储备。这个想法是使用线性代数来识别一组关系,其中因子基素数组合形成一个正方形。然后对关系中所有因子基素数的乘积取平方根,取相关r的乘积,计算gcd来识别因子
struct rel(x, ys)
function dixon(n, fb, count)
r, rels := floor(sqrt(n)), []
while count > 0
fs := smooth((r * r) % n, fb)
if fs is not null
append rel(r, fs) to rels
count := count - 1
r := r + 1
return rels
一个数n是光滑的,如果它的所有因子都在因子基中,这是通过试分确定的; smooth
函数 returns 一个因子列表,如果 n 没有完全分解因子基数,则该列表为空。
function smooth(n, fb)
fs := []
for f in fb
while n % f == 0
append f to fs
n := n / f
if n == 1 return fs
return []
通过将累积关系提交给平方求解器同余的线性代数来确定一个因子。
例如考虑143的因式分解,选择r = 17,所以r2 ≡ 3 (mod 143)。然后选择r = 19,所以r2 ≡ 75 ≡ 3 · 5 2。这两个关系可以合并为 (17 · 19)2 ≡ 32 · 52 ≡ 152 (mod 143), 两个因子为 gcd(17·19 − 15, 143) = 11 和 gcd(17·19 + 15, 143) = 13. 这有时会失败;例如,关系 212 ≡ 22 (mod 143) 可以与 19 上的关系组合,但是两者产生的因子 1 和 143 是微不足道的。
我一直在尝试在 python 中实现 Dixon 的因式分解方法,但我有点困惑。我知道你需要给出一些边界 B
和一些数字 N
并搜索 sqrtN
和 N
之间的数字,其平方是 B-smooth
,这意味着他们所有的因子在小于或等于 B
的素数集中。我的问题是,给定一定大小的 N
,是什么决定了 B
以便算法产生 N
的非平凡因子? Here 是一篇关于该算法的维基百科文章,如果有帮助,这是我的实现代码:
def factor(N, B):
def isBsmooth(n, b):
factors = []
for i in b:
while n % i == 0:
n = int(n / i)
if not i in factors:
factors.append(i)
if n == 1 and factors == b:
return True
return False
factor1 = 1
while factor1 == 1 or factor1 == N:
Bsmooth = []
BsmoothMod = []
for i in range(int(N ** 0.5), N):
if len(Bsmooth) < 2 and isBsmooth(i ** 2 % N, B):
Bsmooth.append(i)
BsmoothMod.append(i ** 2 % N)
gcd1 = (Bsmooth[0] * Bsmooth[1]) % N
gcd2 = int((BsmoothMod[0] * BsmoothMod[1]) ** 0.5)
factor1 = gcd(gcd1 - gcd2, N)
factor2 = int(N / factor1)
return (factor1, factor2)
也许有人也可以帮我清理一下代码?看起来效率很低
本文讨论了 B 的最佳大小:https://web.archive.org/web/20160205002504/https://vmonaco.com/dixons-algorithm-and-the-quadratic-sieve/。简而言之,最优值被认为是 exp((logN loglogN)^(1/2)).
[我写这篇文章的目的不同,但您可能会发现它很有趣。 ]
给定x2 ≡ y2 (mod n) with x ≠ ± y, gcd的时间大约是一半(x−y,n)是n[=69的因数=]. Maurice Kraitchik 在 1920 年代观察到的这种 正方形同余 是多种因式分解方法的基础。 John Dixon 提出的其中一种方法在理论上很重要,因为它的次指数 运行 时间可以得到证明,尽管它在实践中太慢而无用。
Dixon 的方法从选择边界 b 开始。 e√(log n log log n) 和识别小于 b 的所有素数的 factor base,它们是 n 的二次留数(它们的 jacobi 符号是 1).
function factorBase(n, b)
fb := [2]
for p in tail(primes(b))
if jacobi(n, p) == 1
append p to fb
return fb
然后在 1 < r < n 范围内重复选择一个整数 r,计算其平方 modulo n,如果平方在因子基上平滑,则将其添加到 relations 列表中,停止当因子库中的关系多于因子时,为那些失败的情况加上少量储备。这个想法是使用线性代数来识别一组关系,其中因子基素数组合形成一个正方形。然后对关系中所有因子基素数的乘积取平方根,取相关r的乘积,计算gcd来识别因子
struct rel(x, ys)
function dixon(n, fb, count)
r, rels := floor(sqrt(n)), []
while count > 0
fs := smooth((r * r) % n, fb)
if fs is not null
append rel(r, fs) to rels
count := count - 1
r := r + 1
return rels
一个数n是光滑的,如果它的所有因子都在因子基中,这是通过试分确定的; smooth
函数 returns 一个因子列表,如果 n 没有完全分解因子基数,则该列表为空。
function smooth(n, fb)
fs := []
for f in fb
while n % f == 0
append f to fs
n := n / f
if n == 1 return fs
return []
通过将累积关系提交给平方求解器同余的线性代数来确定一个因子。
例如考虑143的因式分解,选择r = 17,所以r2 ≡ 3 (mod 143)。然后选择r = 19,所以r2 ≡ 75 ≡ 3 · 5 2。这两个关系可以合并为 (17 · 19)2 ≡ 32 · 52 ≡ 152 (mod 143), 两个因子为 gcd(17·19 − 15, 143) = 11 和 gcd(17·19 + 15, 143) = 13. 这有时会失败;例如,关系 212 ≡ 22 (mod 143) 可以与 19 上的关系组合,但是两者产生的因子 1 和 143 是微不足道的。