实现模幂算法
代码实现
# 定义PowerMod函数
def PowerMod(a, n, m):
result = 1
a = a % m
while n > 0:
if n % 2 == 1:
result = (result * a) % m
n = n // 2
a = (a * a) % m
return result
a = 6
n = 123456
m = 31
result = PowerMod(a, n, m)
# 打印结果
print(f"{a}^{n} mod {m} = {result}")
代码说明
初始化结果为1,因为任何数的0次方都是1
确保 a 是正数,取模是为了防止溢出
之后进入循环,如果n是奇数,就先取出来一个a计算模13结果为a1,剩下的a就是偶数了,那就让n减半,a等于a的平方模13结果为a2,下次循环的时候,如果n是偶数,就继续令a2的平方模13,如果下次循环为奇数就令a1乘以a2模13,如果奇数为1,那结果就是a1乘以a2.
2023的二进制有11位,大约在11次左右,对于n二进制有k位,则进行k次模乘运算
实现扩展欧几里得算法
代码实现
def ExtGcd(a, b):
if b == 0:
return a, 1, 0
# 递归调用,获取递归返回值
d, x1, y1 = ExtGcd(b, a % b)
# 更新 x 和 y 的值
x = y1
y = x1 - (a // b) * y1
return d, x, y
def InvModExists(a, m):
"""
判断 a 在模 m 下是否存在乘法逆。
如果存在,返回 True 和乘法逆;否则,返回 False。
"""
d, x, y = ExtGcd(a, m)
# 如果 a 和 m 不互质,则不存在乘法逆
if d != 1:
return False, None
return True, x % m
a = 3441
b = 2718
result = ExtGcd(a, b)
print(f"GCD({a}, {b}) = {result[0]}")
print(f"{result[0]} = {a}*{result[1]} + {b}*{result[2]}")
# 待检查的数
numbers = [123, 1234, 12345, 123456, 1234567]
modulus = 20230911
for number in numbers:
exists, inverse = InvModExists(number, modulus)
if exists:
print(f"{number}模{modulus}的乘法逆是: {inverse}")
else:
print(f"{number}模{modulus}没有乘法逆.")
代码说明
递归扩展欧几里得算法,当b等于0时,a就是最大公因子,同时x等于1,y等于0,否则就递归调用ExtGcd(b, a % b),然后令x=返回的y1,y等于返回的x1-(a//b)*y1,确保在当前的Ex