题目背景:已知一个素数p,我们需要求它的原根,因此需要对它的欧拉函数p-1进行分解质因数。
代码:
def fjzys(p,listg):
"""
质因数分解分两种情况:
1、因数都小于等于根号n,只需要从2到根号n之间找质因数
2、有比根号n大的质因数且必定只有一个,那么我们仍然只需要从2到根号n之间找质因数,最后剩下的就是那么大于根号n的质因数
综上我们只需要从2到根号n之间找质因数即可。
"""
listy=[]
n = p-1 #n的欧拉函数
m=int(math.sqrt(n)) #从2到根号n之间找质因数
listy.append(2)
while n % 2 == 0: #p-1必是一个偶数,因此现将质因数2加入列表
n //= 2
for i in range(3,m,2): #3到p的奇数来找p-1的质因数
#if gmpy2.is_prime(i):
if n % i == 0: #找到了质因数
listy.append(i)
while n % i == 0: #将这个质因数都从n中除掉
n //= i
if n != 1: #n不等于1说明剩下的n是一个大于根号n的质因数
listy.append(n)
flag=1
for i in range(2,p): #从2到p求解所有的原根
for j in range(len(listy)): #依次取原根j,计算i的p除以j的次方是否都不等于1,满足说明是原根
if pow(i,p//listy[j],p)==1:
flag=0
break
if flag==1:
listg.append(i)
flag=1
return listg
n=97
listg=fjzys(n)
分解大数:
import math
import random
import time
start = time.perf_counter()
#判断输入是否为素数
def prime(n):
if n in {2, 3, 5, 7, 11}:
return True
if n % 2 == 0 or n % 3 == 0 or n % 5 == 0 or n % 7 == 0 or n % 11 == 0:
return False
t = 0
u = n - 1
while u % 2 == 0:
t += 1
u //= 2
a = random.randint(2, n - 1)
r = pow(a, u, n)
if r != 1:
while t > 1 and r != n - 1:
r = (r * r) % n
t -= 1
if r != n - 1:
return False
return True
#寻找输入的一个因数
```python
def find(n, a):
def f(x):
return (x * x + a) % n
# 补上因子为2的判定
if n % 2 == 0:
return 2
x1 = random.randint(0, n)
x2 = x1
while True:
x1 = f(x1)
x2 = f(f(x2))
p = math.gcd(abs(x2-x1), n)
if p > 1:
return p
if x1 == x2:
return n
num = int(input('请输入1个大整数:\n'))
print(f'{num}=')
prime_list = []
while num != 1:
if prime(num):
prime_list.append(num)
break
else:
c = find(num, random.randint(0, num-1))
if prime(c):
prime_list.append(c)
num //= c
prime_list.sort()
print('*'.join(map(str, prime_list)))
end = time.process_time()
print('用时: %f秒'%(end - start))