You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import random
import sympy as sp
import numpy as np
def find_irreducible_polynomial(p, n):
"""在F_p上寻找一个n次不可约多项式"""
# 生成所有可能的n次多项式首项系数为1
max_coeff = p ** n
for i in range(p ** n):
coeffs = []
num = i
for j in range(n):
coeffs.append(num % p)
num //= p
# 首项系数设为1
coeffs.append(1)
coeffs = coeffs[::-1] # 反转,使高次在前
# 创建多项式
poly = sp.Poly(coeffs, sp.Symbol('x'), modulus=p)
# 检查是否不可约
if sp.ntheory.isprime(p) and poly.is_irreducible:
# 使用sympy的不可约检查
try:
# 转换为有限域上的多项式进行检查
if poly.is_irreducible:
return poly
except:
continue
# 如果没找到,使用一些已知的不可约多项式
x = sp.Symbol('x')
if p == 2:
if n == 3:
return sp.Poly(x**3 + x + 1, x, modulus=p)
elif n == 4:
return sp.Poly(x**4 + x + 1, x, modulus=p)
elif n == 5:
return sp.Poly(x**5 + x**2 + 1, x, modulus=p)
elif p == 3:
if n == 3:
return sp.Poly(x**3 + 2*x + 1, x, modulus=p)
elif p == 5:
if n == 3:
return sp.Poly(x**3 + x + 2, x, modulus=p)
# 默认返回一个
return sp.Poly(x**n + x + 1, x, modulus=p)
def find_generator(poly, p, n):
"""在有限域F_{p^n}中寻找一个生成元"""
x = sp.Symbol('x')
field_size = p ** n
# 测试所有可能的非零多项式次数小于n
for i in range(1, field_size):
# 将i转换为多项式
coeffs = []
num = i
for _ in range(n):
coeffs.append(num % p)
num //= p
# 创建多项式
a_poly = sp.Poly(coeffs, x, modulus=p)
# 检查阶是否为p^n - 1
if is_generator(a_poly, poly, p, n, field_size - 1):
return a_poly
# 如果没找到返回x
return sp.Poly(x, x, modulus=p)
def is_generator(element, poly, p, n, order):
"""检查元素是否是生成元"""
x = sp.Symbol('x')
current = sp.Poly(1, x, modulus=p) # 单位元
# 计算元素的阶
for i in range(1, order + 1):
# 多项式乘法并取模
current = sp.rem(current * element, poly, modulus=p)
# 如果i < order但已经得到1则不是生成元
if i < order and current == sp.Poly(1, x, modulus=p):
return False
# 如果i == order且得到1则是生成元
if i == order and current == sp.Poly(1, x, modulus=p):
return True
return False
def construct_field(p, n):
"""构造有限域F_{p^n}"""
print(f"构造有限域 F_{{{p}^{n}}} = F_{{{p**n}}}")
print("=" * 50)
# 1. 寻找极小多项式
poly = find_irreducible_polynomial(p, n)
print(f"极小多项式 p(x) = {poly}")
print()
# 2. 寻找生成元
alpha = find_generator(poly, p, n)
print(f"生成元 α = {alpha}")
print()
# 3. 生成所有非零元素
field_size = p ** n
elements = []
x = sp.Symbol('x')
# 生成α的幂
current = sp.Poly(1, x, modulus=p) # α^0
elements.append((0, current.copy()))
for i in range(1, field_size - 1):
current = sp.rem(current * alpha, poly, modulus=p)
elements.append((i, current.copy()))
# 4. 显示对应表
print(f"有限域 F_{{{p**n}}} 的非零元素表:")
print("=" * 60)
print(f"{'α的幂':<10} | {'多项式表示':<30} | {'向量表示'}")
print("-" * 60)
for power, poly_repr in elements:
# 获取多项式系数
coeff_dict = poly_repr.as_dict()
coeffs = [0] * n
for deg, coeff in coeff_dict.items():
if len(deg) > 0:
coeffs[deg[0]] = coeff % p
# 构建向量表示
vector = "(" + ", ".join(str(c) for c in coeffs[::-1]) + ")" # 高次在前
print(f"α^{power:<7} | {str(poly_repr):<30} | {vector}")
print("=" * 60)
print(f"注意: α^{field_size-1} = α^0 = 1")
return poly, alpha, elements
def main():
"""主函数"""
print("有限域构造实验")
print("=" * 50)
# 随机选择参数
random.seed() # 使用当前时间作为种子
# 10以内的素数
primes = [2, 3, 5, 7]
p = random.choice(primes)
# 3到10之间的正整数
n = random.randint(3, 10)
print(f"随机选择的参数: p = {p}, n = {n}")
print()
# 构造有限域
poly, alpha, elements = construct_field(p, n)
# 验证域的性质
print("\n验证:")
print(f"1. 域的大小: {p**n}")
print(f"2. 非零元素个数: {p**n - 1}")
print(f"3. 生成元的阶: {p**n - 1}")
print(f"4. p(x)的次数: {sp.degree(poly)}")
print(f"5. p(x)在F_{p}上不可约")
if __name__ == "__main__":
main()