〖数学算法〗大数模幂运算快速算法

部署运行你感兴趣的模型镜像

有朋友问我的博文《素性测试》中的Miller-Rabin算法的大数模幂运算快速算法怎么理解,由于在《素性测试》中没有讲解算法原理,所以在此单独一个篇文章详细讲这个算法。这是一个在密码学中比较重要的算法,在我的《素性测试》一文则是用于实现费马小定理。

首先我们先把问题简化一下,看看如何快速求a^b.

先看看我们熟知的两个数学公式:

a^(2c) = (a^c)^2;

a^(2c+1) = a*((a^c)^2);

我们就利用这两个数学公式来解决这个问题,比如a=3,b=13时,我们把b写成二进制的形式13(10)=1101(2),我们从低位到高位运算,每运算一位可以将b右移一位,上面的例子可以转化成3^13 = 3^1 * 3^4 * 3^8,结合上面的两个数学公式我们可以写出如下的代码:

代码清单:

public class MyPow {
	
	public static void main(String[] args){
		 
		int a = 3;
		int b = 13;
		int m = pow(a,b);
		System.out.println(m);
	}

	private static int pow(int a, int b) {
		int result = 1;
		while(b > 0){
			
			if((b & 1) == 1)//b的某位上为1时才累乘
				result *= a;
			
			a *= a;//数学公式所得
			b >>= 1;//右移1位
		}
		return result;
	}
}
如上面的叙述叙述中可以看出快速pow算法的时间复杂度取决于b的二进制位数,而传统的一位一位累乘的pow算法的时间复杂度取决于b的大小,例如上述例子中,两种算法的运算次数分别为4次,和13次。随着b的增大,效率上的差距是显然的。


下面进入我们的主题---大数模幂运算快速算法(a^b % m)

要计算这个,我们首先还要知道一个数学公式:

a^b % m = (...((a % m) * a) % m) ......* a) % m其中a%m有b个

下面我还用上面b=13的例子,利用这个公式来证明下

a^13 % m = ((a^8) % m) *((a^4) % m) *((a^1) % m)

证明:

a^b % m = (...((a % m) * a) % m) ......* a) % m其中a%m有b个得

a^8 % m = (...((a % m) * a) % m) ......* a) % m其中a%m有8个

a^4 % m = (...((a % m) * a) % m) ......* a) % m其中a%m有4个

a^1 % m = (...((a % m) * a) % m) ......* a) % m 其中a%m有1个

所以((a^8) % m) *((a^4) % m) *((a^1) % m) =(...((a % m) * a) % m) ......* a) % m 其中a%m有13个=a^13 % m

证毕。


由上面我们证明的公式和第一个pow的例子,容易写出代码如下:

代码清单:

int runFermatPow(int a, int b, int m){
		
		int result = 1;
		while (b > 0) {
			if ((b & 1) == 1)
				result = (result * a);

			a = (a * a) % m;
			b >>= 1;
		}
		return result % m;
}

解释:当b=1101(2)时,从第1位开始result累乘,a = (a*a)%m加上循环可以看成表达式(a%m)^2 % m....因为(a%m)^2 % m = a^2 % m ,所以我们可以把a^13%m看成((a^1) % m) ,((a^4) % m) ,((a^8) % m)的累乘,最后对m取模


但累乘很容易造成溢出,所以我们可以把代码改成如下形式:

代码清单:

int runFermatPow(int a, int b, int m){
		
		int result = 1;
		while (b > 0) {
			if ((b & 1) == 1)
				result = (result * a) % m;

			a = (a * a) % m;
			b >>= 1;
		}
		return result;
}



==================================================================================================

作者:nash_ 欢迎转载,与人分享是进步的源泉!

转载请保留原文地址http://blog.youkuaiyun.com/nash_/article/details/8491301

===================================================================================================

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>嗯,用户这想深入了解快速运算结合的知识点。从引用内容看,用户提供的资料质量很高,特别是引用[1][3]详细解释了快速原理,引用[2][4]重点讨论了运算实践,引用[5]则展示了密码学场景的应用实例。用户应该是有算法基础的学习者或开发者,可能正在研究密码学或竞赛算法优化。 用户提问的核心在于"结合原理、实现及应用"三个层面。需要特别注意两点:一是要突出运算在每一步乘法中的介入时机,这是理解结合原理的关键;二是应用部分要区分密码学和其他场景的差异,比如引用[2]提到的蒙哥马利乘法就是专业优化。 快速运算结合的数学本质其实是同余定理的链式应用:每平方或乘时都取,相当于$(a \cdot b) \mod m = [(a \mod m) \cdot (b \mod m)] \mod m$的迭代。引用[4]提到的"平方和乘法"正是描述这个操作流程。 实现层面要强调递归和迭代的共性——它们都遵循指数二进制分解。递归版更直观但有栈溢出风险,迭代版更适合嵌入式系统(如引用[2]的双核实现场景)。代码示例需要展示数m如何嵌入每一步运算,这点在引用[1]的递归示例里体现得很好。 应用方面,除了引用[3][5]提到的RSA解密,还应补充矩阵快速这种非数值计算场景。用户如果研究算法竞赛,斐波那契数列的矩阵解法会是很好的切入点。不过要注意控制深度,毕竟用户主要问的是原理而非具体应用扩展。 安全边界问题值得单独说明。引用[5]提到原数值需小于min(p,q),这实际是RSA-CRT优化的前提条件,但普通幂运算无此限制,需要区分清楚。 </think>快速运算结合的原理、实现及应用是密码学算法优化的核心内容,其核心原理是通过**分治思想**和**运算性质**,将指数时间复杂度降至 $O(\log n)$。以下是详细解析: --- ### **一、结合原理** 1. **数学基础** - **运算分配律**:$(a \cdot b) \mod m = [(a \mod m) \cdot (b \mod m)] \mod m$ - **的分解**:$a^b = \begin{cases} (a^{b/2})^2 & \text{if } b \text{ is even} \\ a \cdot (a^{(b-1)/2})^2 & \text{if } b \text{ is odd} \end{cases}$ - 两者结合:计算 $a^b \mod m$ 时,每一步乘法和平方后立即取,防止数值溢出并加速运算[^1][^3][^4]。 2. **核心流程** 以 $3^{13} \mod 5$ 为例: $$ \begin{align*} 3^{13} \mod 5 &= 3 \cdot (3^6)^2 \mod 5 \\ 3^6 \mod 5 &= (3^3)^2 \mod 5 = (3 \cdot (3^1)^2)^2 \mod 5 \\ &\downarrow \\ 3^1 \mod 5 &= 3 \quad \Rightarrow \quad 3^3 \mod 5 = 3 \cdot 3^2 \mod 5 = 27 \mod 5 = 2 \\ &\Rightarrow \quad 3^6 \mod 5 = 2^2 \mod 5 = 4 \\ &\Rightarrow \quad 3^{13} \mod 5 = 3 \cdot 4^2 \mod 5 = 3 \cdot 16 \mod 5 = 3 \cdot 1 = 3 \end{align*} $$ --- ### **二、实现方法** #### 1. **递归实现(直观但栈开销大)** ```python def mod_exp(base, exp, mod): if exp == 0: return 1 half = mod_exp(base, exp // 2, mod) res = (half * half) % mod return (res * base) % mod if exp % 2 == 1 else res ``` #### 2. **迭代实现(高效,空间 $O(1)$)** ```python def mod_exp_iter(base, exp, mod): res = 1 base = base % mod # 初始取 while exp > 0: if exp & 1: # 指数为奇数 res = (res * base) % mod base = (base * base) % mod # 平方 exp >>= 1 # 指数右移(整除2) return res ``` **关键步骤**: - 指数按二进制分解(如 $13 = 1101_2$) - 逐位处理:遇 `1` 则乘当前底数,每轮底数平方[^1][^3]。 --- ### **三、应用场景** 1. **密码学** - **RSA 加密/解密**:计算 $c = m^e \mod n$(加密),$m = c^d \mod n$(解密),其中 $e, d$ 为大质数[^2][^5]。 - **Diffie-Hellman 密钥交换**:生成共享密钥 $K = g^{ab} \mod p$[^3]。 2. **算法优化** - **大数逆元**:通过费马小定理 $a^{-1} \equiv a^{m-2} \pmod{m}$($m$ 为质数)[^1]。 - **斐波那契数列**:矩阵 $\begin{pmatrix} 1 & 1 \\ 1 & 0 \end{pmatrix}^n$ 结合运算[^3]。 3. **硬件加速** - **蒙哥马利乘**:避免除法,将乘转为移位和加法(引用[2][4]所述)[^2][^4]。 - **双核并行**:分解指数为高低位,分别计算后合并结果(引用[2])[^2]。 --- ### **四、性能分析** | 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | |--------------|-------------|------------|------------------| | 直接计算 | $O(b)$ | $O(1)$ | 小指数 | | 递归快速 | $O(\log b)$ | $O(\log b)$| 代码简洁 | | 迭代快速 | $O(\log b)$ | $O(1)$ | 大指数/嵌入式系统 | > ⚠️ **注意**:幂运算需保证 $a$ 与 $m$ 互质(如 RSA 中 $m=pq$),否则需用欧拉定理扩展[^5]。 --- ### **典型问题示例(引用[5])** **问题描述**: 给定质数 $p, q, e$ 和加密序列 $\{a_i\}$,解密公式为 $m_i = a_i^d \mod n$($n=pq$, $d=e^{-1} \mod \phi(n)$)。 **解法**: 1. 计算 $n = p \times q$, $\phi(n) = (p-1)(q-1)$ 2. 求 $d \equiv e^{-1} \pmod{\phi(n)}$(扩展欧几里得) 3. 对每个 $a_i$ 计算 $a_i^d \mod n$(迭代快速)[^5]。 --- **
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值