求一个数的原根并求其欧拉函数的所有质因数

题目背景:已知一个素数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))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值