惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
L
LangChain Blog
Jina AI
Jina AI
博客园 - 叶小钗
B
Blog RSS Feed
Recent Announcements
Recent Announcements
H
Help Net Security
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
B
Blog
云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客

博客园 - 520_1351

使用Notepad++的快捷键运行Python时-报错-The security information for shortcuts.xml is missing in config.xml Powerautomate-控制Edge-浏览器-报错-Failed to assume control of Microsoft Edge (communication with Power Automate web extension failed) 关于AWS-EC2-串口登录的-IAM权限-Policy-策略 关于 AWS Lambda 中的默认的时区-日期-时间-注意点 关于使用 javascript 脚本语言中的 location.reload() 刷新当前页面 关于Bash - Shell脚本中的索引数组(Indexed Array) 关于Linux系统中-使用passwd对用户密码的锁定与解锁 关于 Redhat - 9 - 补丁升级后-旧版本内核相关的软件包卸载 关于 Redhat - 9 下 postfix 的安装配置 与 mail 命令发送邮件 关于 Amazon Linux 2023 (AL2023) 默认情况下确实没有 /var/log/secure 文件的解决方法 关于-HTML-内容-元素定位- CSS Selector 与 XPath 的说明及区别 关于Microsoft Power Automate-操作-Microsoft Access 数据库-【运行Access查询】 关于 Javascript 中 console.log("xxxx")-及console-对象其他常用的方法 关于Provider=Microsoft.ACE.OLEDB.12.0 与 Provider=Microsoft.ACE.OLEDB.16.0 的区别 通过Powershell-脚本-将指定的日期-转换成年周-格式-周数宽度为2 关于Windows-操作系统中-对带日期-或-数字-的文件目录-按名称排序的规则 关于Microsoft Power Automate-元素的定位-自定义写法去定位时-:nth-child 与 :eq 的区别 关于标准CSS伪类-以及在-Power Automate-等自动化工具中的使用 关于使用-Python-Selenium-模块-加载浏览器的扩展-的方法及注意事项-及只能加载一个扩展的解决方法 关于-根据-ISO8601-国际标准-计算一年中的周数-每年最少52周-每多53周 Redhat-9-中编译-EFS-客户端工具-即过程中-报错提示-warning: aws-lc-fips-sys@0.13.9: Building with: CMake-解决方法 关于Microsoft Power Automate-调用-Outlook-发送邮件-报错- A program is trying to access emal address information stored in Outlook 关于powershell中的-哈希表-Hashtable-类型-说明-类似于python中的字典 关于HTML中<font><b><i><s>等字体标签对-物理字体-逻辑字体的介绍及说明
关于-密码学算法中-类似-编程函数pow(3, 13, 7)的计算-快速幂...
520_1351 · 2026-06-05 · via 博客园 - 520_1351

而 pow(g, a, p) 之所以能“秒算”,是因为它在底层使用了高度优化的快速幂算法结合模运算(Exponentiation by Squaring with Modular Reduction)。

它的精妙之处在于“边算边约减”——在每一次平方或乘法运算后,立刻对中间结果进行取模操作。这样,整个计算过程中的所有中间变量都被死死地控制在

p 的范围之内,彻底避免了产生巨大中间值的问题。

这里举例说明 pow(3, 13, 7) ,即表示 计算 3^13 % 7 的结果 , 其核心是要将 3^13 分解成多个数的乘积 , 计算机中,最快最简单的就是3不变, 将指数13进行分解

如果按照你直觉中的“先算出完整结果再取模”,我们需要先算 3^13 ,这等于 1594323,然后再用 1594323 除以 7 求余数。如果指数更大,这个数字会大到计算机直接爆内存。

而快速幂算法的“边算边约减”和“二进制分解”是这样操作的: 

首先,我们将指数 13 写成二进制:1101  ,  在二进制中,每一位代表一个权重:

0 位是 1 - 代表 2^0 = 11 位是 0 - 代表 2^1 = 22 位是 1 - 代表 2^2 = 43 位是 1 - 代表 2^3 = 8

所以,13=8+4+1,而且可以观察出来,二进制中,低位的1如果为x ,它旁边高位的1就代表是x的2倍,即2x了

这样,我们带入底数3 , 也即如果 3^x 的下一个高位如果是1 , 就是 3^(2x) ,  也即是 (3^x)^2 ,  也即低高位都是1 , 位数的3^x 的 平方 就是下一个高位的结果

那么数学上,3^13 就可以拆解为:3^8 * 3^4 * 3^1 = 3^(8+4+1)

第二步:开始迭代计算(核心过程)

我们准备两个变量:结果(res) = 1,底数(base) = 3。我们从二进制的最低位(最右边)开始往左看:

【第 1 轮】处理二进制的最后一位(1)

  • 判断:当前位是 1,说明这个  3^1  需要被乘进最终结果里。
  • 更新结果:res = res × base % 7 → 1 × 3 % 7 = 3。
  • 底数自乘取模:不管这一位是不是1,底数都要平方,为下一位做准备。base = 3 × 3 % 7 = 9 % 7 = 2。(注意!这里立刻取了模,把 9 变成了 2,数值非常小)。【这也代表下一个高位3^高位1位置的结果 % 7  = 2】
  • 移动:向右移一位,处理下一个二进制位。

【第 2 轮】处理二进制的倒数第二位(0)

  • 判断:当前位是 0,说明不需要乘入结果,跳过。
  • 底数自乘:base = 2 × 2 % 7 = 4。(同样立刻取模,保持数值很小)。
  • 移动:继续右移。

【第 3 轮】处理二进制的倒数第三位(1)

  • 判断:当前位是 1,需要乘入结果。此时的 base 已经通过连续平方代表了 3^4 。
  • 更新结果res = res × base % 73 × 4 % 7 = 12 % 7 = 5
  • 底数自乘base = 4 × 4 % 7 = 16 % 7 = 2。(再次取模)。
  • 移动:继续右移。

【第 4 轮】处理二进制的最高位(1)

  • 判断:当前位是 1,需要乘入结果。此时的 base 代表了 3^8 。
  • 更新结果res = res × base % 75 × 2 % 7 = 10 % 7 = 3
  • 底数自乘base = 2 × 2 % 7 = 4
  • 移动:右移后没有更多位数了,结束。

所以最后的结果就是3 ,  这里我们总结一下:

我们可以看到,整个过程中,我们从来没有计算过像 1594323 这样的大数。每一次乘法之后,我们都立刻 % 7 

这就是为什么 Python 的 pow(g, a, p) 能够“秒算”:它利用二进制把巨大的指数拆解成了少量的平方和乘法操作

时间复杂度从 O(a)降到了 O(log a) 并且死死地把所有中间数字控制在模数 p 的范围内,彻底避免了内存爆炸。

尊重别人的劳动成果 转载请务必注明出处:https://www.cnblogs.com/5201351/p/20331011