您可以使用 SymPy 和 this awesome answer 处理有限域。
您与n = 2 在环上Z/nZ,因此您想使用链接答案中的GF 类:
>>> %time field = GF(2, 409)
CPU times: user 1min 47s, sys: 6.64 ms, total: 1min 47s
Wall time: 1min 47s
如您所见,GF(2, 409) 的初始化相当长(~= 1-2 分钟)...
...但是乘法求逆的计算几乎是即时的:
%%time
import numpy as np
# list of 410 coefficients regarding x^409 (left-most) up to x^0 (right-most)
coeffs = [0] * 410
for idx in [0, 1, 6, 15, 409]: # exponents present in your polynome
coeffs[409 - idx] = 1 # set to 1 to indicate existence
li = []
for i in range(4):
'''
To help SymPy make the polynome `x^409 + x^15 + x^6 + x + 1`,
provide the `GF.inv()` method with its coefficients using `ZZ.map()`
Actually, `inv()` will call `sympy.polys.galoistools.gf_gcdex()`
'''
coeffs = field.inv(ZZ.map(coeffs))
li.append(np.array(coeffs))
CPU times: user 37.3 ms, sys: 2 µs, total: 37.3 ms
Wall time: 36 ms
GF.inv() 返回的结果是反相系数的数组。
请注意,再次应用反演将恢复为原始多项式:
>>> print(np.equal(li[0], li[2]).all() and np.equal(li[1], li[3]).all())
True
您还可以验证p(x) * p(x)^(-1) = 1:
>>> field.mul(li[0], li[1])
[1] # Ok !
以下是来自cited answer 的剥离代码,仅包含您需要的反转代码:
import itertools
from sympy.polys.domains import ZZ
from sympy.polys.galoistools import (gf_irreducible_p, gf_gcdex)
from sympy.ntheory.primetest import isprime
class GF():
def __init__(self, p, n=1):
p, n = int(p), int(n)
if not isprime(p):
raise ValueError("p must be a prime number, not %s" % p)
if n <= 0:
raise ValueError("n must be a positive integer, not %s" % n)
self.p = p
self.n = n
if n == 1:
self.reducing = [1, 0]
else:
for c in itertools.product(range(p), repeat=n):
poly = (1, *c)
if gf_irreducible_p(poly, p, ZZ):
self.reducing = poly
break
def inv(self, x):
s, t, h = gf_gcdex(x, self.reducing, self.p, ZZ)
return s
GF(2, 409).inv(ZZ.map(coeffs))