<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>信息安全 on 蛋蛋忧桑</title><link>https://dandansad.com/tags/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/</link><description>Recent content in 信息安全 on 蛋蛋忧桑</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Thu, 08 May 2025 14:32:12 +0800</lastBuildDate><atom:link href="https://dandansad.com/tags/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>访问控制策略</title><link>https://dandansad.com/2025/05/08/%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6%E7%AD%96%E7%95%A5/</link><pubDate>Thu, 08 May 2025 14:32:12 +0800</pubDate><guid>https://dandansad.com/2025/05/08/%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6%E7%AD%96%E7%95%A5/</guid><description>&lt;h2 id="1-dacdiscretionary-access-control"&gt;&lt;a href="#1-dacdiscretionary-access-control" class="header-anchor"&gt;&lt;/a&gt;1. DAC（Discretionary Access Control）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;自主访问控制&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="核心特点"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e7%89%b9%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;核心特点：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;资源拥有者决定权限&lt;/strong&gt;：用户对其拥有的资源（如文件）有控制权，可以授予或撤销他人的访问权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限可继承/传播&lt;/strong&gt;：被授权的用户可以继续把权限授予其他用户（这可能导致“权限扩散”）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="举例"&gt;&lt;a href="#%e4%b8%be%e4%be%8b" class="header-anchor"&gt;&lt;/a&gt;举例：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;用户 A 拥有一个文件 &lt;code&gt;file.txt&lt;/code&gt;，他设置权限让用户 B 也能读取它。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用户 B 如果有权，也可以把这个文件分享给用户 C。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="类似系统"&gt;&lt;a href="#%e7%b1%bb%e4%bc%bc%e7%b3%bb%e7%bb%9f" class="header-anchor"&gt;&lt;/a&gt;类似系统：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类 Unix 的系统默认使用 DAC&lt;/strong&gt;，通过 &lt;code&gt;chmod&lt;/code&gt;、&lt;code&gt;chown&lt;/code&gt; 控制文件权限。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-macmandatory-access-control"&gt;&lt;a href="#2-macmandatory-access-control" class="header-anchor"&gt;&lt;/a&gt;2. MAC（Mandatory Access Control）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;强制访问控制&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="核心特点-1"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e7%89%b9%e7%82%b9-1" class="header-anchor"&gt;&lt;/a&gt;核心特点：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;系统控制访问权限&lt;/strong&gt;：用户无权修改自己的资源权限，所有访问规则由系统策略统一定义。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;基于安全标签（level）&lt;/strong&gt;：对象（资源）和主体（用户）都有安全级别，比如“机密”、“受限”、“公开”，系统强制根据这些级别控制访问。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="举例-1"&gt;&lt;a href="#%e4%b8%be%e4%be%8b-1" class="header-anchor"&gt;&lt;/a&gt;举例：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一个“秘密”级别的文件只有“秘密”级别或更高级别的用户才能访问，不能随意共享。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用户即使拥有文件，也无法更改其访问权限。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="类似系统-1"&gt;&lt;a href="#%e7%b1%bb%e4%bc%bc%e7%b3%bb%e7%bb%9f-1" class="header-anchor"&gt;&lt;/a&gt;类似系统：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SELinux（Security-Enhanced Linux）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AppArmor（Ubuntu 上使用）
这些系统就使用了 MAC 模型。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-rbacrole-based-access-control"&gt;&lt;a href="#3-rbacrole-based-access-control" class="header-anchor"&gt;&lt;/a&gt;3. RBAC（Role-Based Access Control）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;基于角色的访问控制&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="核心特点-2"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e7%89%b9%e7%82%b9-2" class="header-anchor"&gt;&lt;/a&gt;核心特点：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;以“角色”为中心&lt;/strong&gt;：权限分配给“角色”，用户根据其角色获得权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;灵活、集中管理&lt;/strong&gt;：适合组织结构复杂、职责分明的环境。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="举例-2"&gt;&lt;a href="#%e4%b8%be%e4%be%8b-2" class="header-anchor"&gt;&lt;/a&gt;举例：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;角色“管理员”拥有系统配置权限；角色“用户”只能读写自己的数据。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用户 A 被分配为“管理员”，系统自动赋予所有“管理员”权限。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="类似系统-2"&gt;&lt;a href="#%e7%b1%bb%e4%bc%bc%e7%b3%bb%e7%bb%9f-2" class="header-anchor"&gt;&lt;/a&gt;类似系统：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;多数企业应用和身份管理系统（如 Active Directory、Kubernetes、数据库权限管理）使用 RBAC。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="4-tbactask-based-access-control"&gt;&lt;a href="#4-tbactask-based-access-control" class="header-anchor"&gt;&lt;/a&gt;4. TBAC（Task-Based Access Control）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;基于任务的访问控制&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="核心特点-3"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e7%89%b9%e7%82%b9-3" class="header-anchor"&gt;&lt;/a&gt;核心特点：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;权限与具体任务绑定，而不是与用户或角色绑定&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用户只有在执行某个“已授权任务”时，才能获得所需权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;强调“动态激活权限”，避免静态分配带来的过度权限问题。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="举例-3"&gt;&lt;a href="#%e4%b8%be%e4%be%8b-3" class="header-anchor"&gt;&lt;/a&gt;举例：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;某人是“医生”角色，但只有在处理某个病人的病历任务时，才能访问该病历。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;执行完任务后，权限自动撤销。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="应用场景"&gt;&lt;a href="#%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;应用场景：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;工作流系统、审批系统、临时授权操作（如 DevOps 自动化脚本）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="5-obacobject-based-access-control"&gt;&lt;a href="#5-obacobject-based-access-control" class="header-anchor"&gt;&lt;/a&gt;5. OBAC（Object-Based Access Control）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;基于对象的访问控制&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="核心特点-4"&gt;&lt;a href="#%e6%a0%b8%e5%bf%83%e7%89%b9%e7%82%b9-4" class="header-anchor"&gt;&lt;/a&gt;核心特点：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;访问控制依赖对象本身的属性和策略&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不看用户或角色，看“对象是否允许某类用户访问”。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="举例-4"&gt;&lt;a href="#%e4%b8%be%e4%be%8b-4" class="header-anchor"&gt;&lt;/a&gt;举例：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一个文件设置了“仅允许创建者和其直属上级访问”，访问控制规则写在对象的元数据或策略中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不依赖用户的角色或任务，只要对象规则允许，就能访问。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="应用场景-1"&gt;&lt;a href="#%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af-1" class="header-anchor"&gt;&lt;/a&gt;应用场景：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;微服务架构、面向对象系统、基于资源策略的授权系统（如某些云平台）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结对比表"&gt;&lt;a href="#%e6%80%bb%e7%bb%93%e5%af%b9%e6%af%94%e8%a1%a8" class="header-anchor"&gt;&lt;/a&gt;总结对比表：
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模型&lt;/th&gt;
					&lt;th&gt;控制基础&lt;/th&gt;
					&lt;th&gt;权限分配方式&lt;/th&gt;
					&lt;th&gt;粒度&lt;/th&gt;
					&lt;th&gt;动态性&lt;/th&gt;
					&lt;th&gt;上下文感知&lt;/th&gt;
					&lt;th&gt;安全性&lt;/th&gt;
					&lt;th&gt;灵活性&lt;/th&gt;
					&lt;th&gt;常见场景/系统&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;DAC&lt;/td&gt;
					&lt;td&gt;用户（资源拥有者）&lt;/td&gt;
					&lt;td&gt;手动分配&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;静态&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;Unix/Linux 文件系统、用户共享&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MAC&lt;/td&gt;
					&lt;td&gt;系统策略/安全标签&lt;/td&gt;
					&lt;td&gt;统一策略控制&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;静态&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;很高&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;SELinux、军事系统、政府保密系统&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;RBAC&lt;/td&gt;
					&lt;td&gt;用户角色&lt;/td&gt;
					&lt;td&gt;基于角色分配&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;静态&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;企业权限管理、数据库、Kubernetes&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TBAC&lt;/td&gt;
					&lt;td&gt;当前执行任务&lt;/td&gt;
					&lt;td&gt;任务自动授权&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;动态&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;中&lt;/td&gt;
					&lt;td&gt;工作流系统、临时任务授权、自动化系统&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;OBAC&lt;/td&gt;
					&lt;td&gt;对象自身策略&lt;/td&gt;
					&lt;td&gt;对象定义控制策略&lt;/td&gt;
					&lt;td&gt;非常高&lt;/td&gt;
					&lt;td&gt;动态或静态&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;云服务（如 AWS IAM）、微服务资源管理&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>E2_AES</title><link>https://dandansad.com/2025/03/18/e2_aes/</link><pubDate>Tue, 18 Mar 2025 13:09:22 +0800</pubDate><guid>https://dandansad.com/2025/03/18/e2_aes/</guid><description>&lt;h2 id="算法主要原理"&gt;&lt;a href="#%e7%ae%97%e6%b3%95%e4%b8%bb%e8%a6%81%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;算法主要原理
&lt;/h2&gt;&lt;p&gt;算法流程如下：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-10-1024x949.png"&gt;&lt;/p&gt;
&lt;h2 id="算法步骤"&gt;&lt;a href="#%e7%ae%97%e6%b3%95%e6%ad%a5%e9%aa%a4" class="header-anchor"&gt;&lt;/a&gt;算法步骤
&lt;/h2&gt;&lt;p&gt;AES算法是一种对称分组密码算法，采用代换-置换网络（SPN）结构，通过多轮迭代的加密过程对数据进行混淆和扩散，确保其安全性。该算法将明文分成固定长度的128位数据块（实际上分组长度也有128位、192位或256位三种选择），并支持128位、192位或256位的密钥，分别对应10轮、12轮或14轮的加密轮次。每一轮加密过程包括四个核心操作：&lt;strong&gt;字节代换&lt;/strong&gt;、&lt;strong&gt;行移位&lt;/strong&gt;、&lt;strong&gt;列混淆&lt;/strong&gt;和&lt;strong&gt;轮密钥加&lt;/strong&gt;，其中最后一轮省略列混淆步骤。通过&lt;strong&gt;密钥扩展算法&lt;/strong&gt;，初始密钥被扩展为多组轮密钥，供每一轮加密使用。AES算法的安全性依赖于其非线性的S盒变换、扩散层操作以及密钥的复杂性，使其能够有效抵抗线性攻击和差分攻击，成为当前最广泛使用的对称加密标准之一。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-18.png"&gt;&lt;/p&gt;
&lt;h3 id="1字节代换"&gt;&lt;a href="#1%e5%ad%97%e8%8a%82%e4%bb%a3%e6%8d%a2" class="header-anchor"&gt;&lt;/a&gt;1.字节代换
&lt;/h3&gt;&lt;p&gt;字节代换是AES加密的核心非线性变换，它通过一个被称为S盒的查找表对状态矩阵中的每个字节进行独立替换。其中，S盒是经过精心设计的，它基于有限域GF(2⁸)上的乘法逆运算，再加上一个仿射变换，使得输出与输入之间不存在明显的数学关系。具体来说，每个字节先被看作GF(2⁸)中的元素，计算其乘法逆元（0x00映射到自身），然后经过一个固定的仿射变换。这种设计让S盒具备极强的非线性特性，有效抵抗线性密码分析。而解密过程则使用逆S盒进行反向替换，但这两个S盒并不是简单的互逆关系，而是各自独立构造的。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-19-810x1024.png"&gt;&lt;/p&gt;
&lt;h3 id="2行移位"&gt;&lt;a href="#2%e8%a1%8c%e7%a7%bb%e4%bd%8d" class="header-anchor"&gt;&lt;/a&gt;2.行移位
&lt;/h3&gt;&lt;p&gt;行移位步骤是对状态矩阵的行进行循环移位操作。具体来说，状态矩阵是一个4行4列的字节数组。第一行保持不变，第二行循环左移1个字节，第三行循环左移2个字节，第四行循环左移3个字节。这个操作使得原本在同一列中的字节被分散到不同列中。在解密时，需要进行相反方向的循环右移操作。行移位的目的是实现字节在状态矩阵中的扩散，使得后续的列混淆操作能更有效地传播变化。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-20.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-22.png"&gt;&lt;/p&gt;
&lt;h3 id="3列混淆"&gt;&lt;a href="#3%e5%88%97%e6%b7%b7%e6%b7%86" class="header-anchor"&gt;&lt;/a&gt;3.列混淆
&lt;/h3&gt;&lt;p&gt;列混淆步骤对状态矩阵的每一列进行线性变换。该操作将每一列视为GF(2^8)上的多项式，与固定多项式进行有限域上的乘法。这个运算可以表示为矩阵乘法，其中每个字节的变换都是与固定系数的乘法和异或组合。&lt;/p&gt;
&lt;p&gt;在实际实现中，这个步骤可以使用xtime进行化简。xtime定义为这样的一个函数，其输入是一个 8 位字节（即 GF(2⁸) 的元素），输出是该字节与 {02}（即多项式 x）相乘的结果，并在必要时进行模 x⁸ + x⁴ + x³ + x + 1（AES 使用的不可约多项式）的约简，也即异或0x1B。&lt;/p&gt;
&lt;p&gt;在解密时，只需要变换固定系数矩阵即可。值得注意的是，最后一轮加密不包含列混淆操作。这个步骤增强了AES的扩散特性，使得单个字节的变化会影响整个列。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-23.png"&gt;&lt;/p&gt;
&lt;h3 id="4轮密钥加"&gt;&lt;a href="#4%e8%bd%ae%e5%af%86%e9%92%a5%e5%8a%a0" class="header-anchor"&gt;&lt;/a&gt;4.轮密钥加
&lt;/h3&gt;&lt;p&gt;轮密钥加步骤将当前轮的扩展密钥与状态矩阵进行简单的按位异或操作。每一轮都使用不同的轮密钥，这些密钥是通过密钥扩展算法从初始密钥派生出来的。这个操作是AES中唯一直接使用密钥的步骤。由于异或操作的可逆性，解密时只需使用相同的轮密钥再次异或即可恢复原始数据。这个步骤为算法提供了基于密钥的安全性。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-24.png"&gt;&lt;/p&gt;
&lt;h3 id="5密钥扩展算法"&gt;&lt;a href="#5%e5%af%86%e9%92%a5%e6%89%a9%e5%b1%95%e7%ae%97%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;5.密钥扩展算法
&lt;/h3&gt;&lt;p&gt;密钥扩展算法负责从初始密钥生成各轮所需的轮密钥。对于128位密钥，需要生成10个轮密钥（共44个32位字）。算法首先将初始密钥分成4个字（w[0]-w[3]），然后递归生成后续的字。我们这里只讨论128位密钥的扩展，其他位数的扩展步骤大致相同。&lt;/p&gt;
&lt;p&gt;对于非4k个字，计算方式为前一个字w[i-1]与w[i-4]的简单异或（XOR）。每第4k个字（如w[4],w[8]等）需要特殊处理，计算方式为先对前一个字w[i-1]进行字节代换、循环移位，再与w[i-4]、轮常数异或。轮常数是一个与轮次相关的固定值，用于打破对称性。对于192位和256位密钥，扩展过程类似但细节略有不同。这个算法确保每个轮密钥都与前一个不同，且整个密钥调度具有足够的随机性。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-25.png"&gt;&lt;/p&gt;
&lt;h3 id="6des与aes的对比"&gt;&lt;a href="#6des%e4%b8%8eaes%e7%9a%84%e5%af%b9%e6%af%94" class="header-anchor"&gt;&lt;/a&gt;6.DES与AES的对比
&lt;/h3&gt;&lt;p&gt;DES和AES在结构设计上采用了不同的密码学架构，体现了对称加密算法演进的思路。DES基于Feistel网络结构，这种结构将输入分组分为左右两部分，每轮只对其中一半进行加密变换，再通过交换左右部分实现数据混淆。Feistel结构的特点是加密解密过程对称，只需调整子密钥顺序即可实现逆向运算，这使得硬件实现相对简单。然而DES的56位密钥长度在计算能力提升后显得不足，且固定的S盒设计存在潜在的分析风险。&lt;/p&gt;
&lt;p&gt;AES则采用了更为现代的SPN（Substitution-Permutation Network）结构，这种结构通过多轮重复的代换和置换操作实现数据加密。与Feistel网络不同，SPN结构在每一轮都对整个数据块进行完整的非线性变换和线性扩散。具体来说，AES的每轮加密都包含字节代换、行移位、列混淆和轮密钥加四个步骤，其中前三步分别实现非线性代换和线性扩散，最后一步引入密钥相关变换。这种设计使得AES在相同轮数下能实现更强的混淆和扩散效果。&lt;/p&gt;
&lt;p&gt;从安全性角度来看，AES的SPN结构具有明显优势。其更大的分组长度（128位起）和可变的密钥长度（128/192/256位）能更好抵抗穷举攻击。每一轮对整个数据块的处理方式使得差分和线性分析更加困难，而DES的Feistel结构由于每轮只处理半块数据，需要更多轮数才能达到相似的混淆效果。此外，AES的S盒设计基于严密的数学理论，相比DES的固定S盒具有更强的抗分析能力。&lt;/p&gt;
&lt;p&gt;在性能表现上，AES的SPN结构更适合现代计算环境。其算法设计充分考虑了软硬件实现的效率，在各类平台上都能展现出优异的性能。而DES由于其初始设计年代较早，在软件实现效率上相对较低，特别是在处理大数据量时更为明显。AES的轮数可以根据密钥长度灵活调整（10/12/14轮），在安全性和效率之间取得了更好的平衡。&lt;/p&gt;
&lt;p&gt;NIST提出AES标准的主要原因在于DES已不能满足现代安全需求。随着计算能力的提升，DES的56位密钥面临被暴力破解的风险。1997年DES挑战赛被成功攻破，加速了新标准的制定进程。AES的选拔过程公开透明，最终Rijndael算法因其在安全性、性能和实现灵活性上的综合优势胜出。相比DES，AES提供了更高的安全强度、更优的执行效率以及更好的算法透明度，这些特点使其成为21世纪最重要的对称加密标准。&lt;/p&gt;
&lt;h2 id="程序运行截图"&gt;&lt;a href="#%e7%a8%8b%e5%ba%8f%e8%bf%90%e8%a1%8c%e6%88%aa%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;程序运行截图
&lt;/h2&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-26.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-27.png"&gt;&lt;/p&gt;
&lt;h2 id="参考代码"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;参考代码
&lt;/h2&gt;&lt;h3 id="aespy"&gt;&lt;a href="#aespy" class="header-anchor"&gt;&lt;/a&gt;aes.py
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# AES 128 bit encryption and decryption&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 128 bit 密钥 == 16 bytes == 32位十六进制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 192 bit 密钥 == 24 bytes == 48位十六进制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 256 bit 密钥 == 32 bytes == 64位十六进制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Sbox &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x63&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x77&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x30&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x01&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x67&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x76&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xCA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x82&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x59&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x47&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x72&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xB7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x93&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x26&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x36&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x34&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x71&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x31&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x15&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x04&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x23&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x18&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x96&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x05&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x07&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x12&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x80&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x27&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x75&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x09&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x83&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x52&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x29&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x84&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x53&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x00&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xED&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x20&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x39&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x58&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCF&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xD0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x43&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x33&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x85&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x45&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x02&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x50&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA8&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x51&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x40&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x92&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x38&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x21&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xCD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x13&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x97&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x44&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x17&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x64&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x19&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x73&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x60&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x81&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x22&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x90&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x88&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x46&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x14&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDB&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xE0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x32&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x49&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x06&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x24&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x62&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x91&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x95&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x79&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xE7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x37&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x56&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x65&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x08&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xBA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x78&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x25&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x74&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8A&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x70&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x66&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x48&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x03&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x61&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x35&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x57&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x86&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9E&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xE1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x98&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x11&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x69&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x94&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x87&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x55&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x28&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDF&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x8C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x89&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x42&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x68&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x41&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x99&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x54&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x16&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;InvSbox &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x52&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x09&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x30&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x36&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x38&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x40&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x81&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFB&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x7C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x39&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x82&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x87&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x34&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x43&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x44&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCB&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x54&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x94&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x32&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x23&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x95&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x42&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4E&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x08&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x66&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x28&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x24&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x76&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x49&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x25&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x72&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x64&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x86&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x68&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x98&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x16&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x65&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x92&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x6C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x70&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x48&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x50&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xED&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x15&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x46&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x57&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x84&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x90&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x00&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x58&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x05&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x45&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x06&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xD0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x02&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x03&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x01&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x13&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x8A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6B&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x3A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x91&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x11&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x41&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x67&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x97&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x73&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x96&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x74&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x22&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x35&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x85&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x37&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x75&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDF&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6E&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x47&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x71&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x29&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x89&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x6F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x62&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x18&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x1B&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xFC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x56&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x79&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x20&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xFE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x78&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xCD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF4&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x1F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xDD&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x33&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x88&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x07&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x31&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x12&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x59&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x27&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x80&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEC&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x5F&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x60&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x51&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xA9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x19&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9F&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x93&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC9&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x9C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEF&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0xA0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x4D&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xAE&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2A&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xF5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xB0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xC8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xEB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBB&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x3C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x83&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x53&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x99&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x61&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0x17&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x2B&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x04&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7E&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xBA&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x77&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xD6&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x26&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0xE1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x69&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x14&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x63&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x55&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x21&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x0C&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0x7D&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# xtime函数，用于有限域上的乘法运算&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 如果a的最高位为1，则左移1位后与0x1B异或，否则直接左移1位&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 0x1B 是 0001 1011 的十六进制表示，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 0xFF 是 1111 1111 的十六进制表示，&amp;amp; 0xFF 运算只保留最低8位，其余位为0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 0x80 是 1000 0000 的十六进制表示，&amp;amp; 0x80 运算只保留最高位，其余位为0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;xtime &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;lambda&lt;/span&gt; a: (((a &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; i))) &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0xFF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; i &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 每4个字节开始一个新行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; matrix&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([byte])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 将字节添加到当前行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; matrix[int(i &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;)]&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(byte)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; matrix
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;matrix2text&lt;/span&gt;(matrix):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 将矩阵转换为文本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 将每个字节移动到正确的位置并组合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; text &lt;span style="color:#f92672"&gt;|=&lt;/span&gt; (matrix[i][j] &lt;span style="color:#960050;background-color:#1e0010"&gt;!&lt;/span&gt;[](&lt;span style="color:#f92672"&gt;/&lt;/span&gt;images&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2025&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;03&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;image&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;11&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1024&lt;/span&gt;x429&lt;span style="color:#f92672"&gt;.&lt;/span&gt;png)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## 参考资料&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[bozhu&lt;span style="color:#f92672"&gt;/&lt;/span&gt;AES&lt;span style="color:#f92672"&gt;-&lt;/span&gt;Python: A pure Python implementation of AES](https:&lt;span style="color:#f92672"&gt;//&lt;/span&gt;github&lt;span style="color:#f92672"&gt;.&lt;/span&gt;com&lt;span style="color:#f92672"&gt;/&lt;/span&gt;bozhu&lt;span style="color:#f92672"&gt;/&lt;/span&gt;AES&lt;span style="color:#f92672"&gt;-&lt;/span&gt;Python)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[AES &lt;span style="color:#f92672"&gt;-&lt;/span&gt; CTF Wiki](https:&lt;span style="color:#f92672"&gt;//&lt;/span&gt;ctf&lt;span style="color:#f92672"&gt;-&lt;/span&gt;wiki&lt;span style="color:#f92672"&gt;.&lt;/span&gt;org&lt;span style="color:#f92672"&gt;/&lt;/span&gt;crypto&lt;span style="color:#f92672"&gt;/&lt;/span&gt;blockcipher&lt;span style="color:#f92672"&gt;/&lt;/span&gt;aes)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[密码学基础&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;AES加密算法 &lt;span style="color:#f92672"&gt;-&lt;/span&gt; 知乎](https:&lt;span style="color:#f92672"&gt;//&lt;/span&gt;zhuanlan&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zhihu&lt;span style="color:#f92672"&gt;.&lt;/span&gt;com&lt;span style="color:#f92672"&gt;/&lt;/span&gt;p&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;78913397&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>E1_Vigenere</title><link>https://dandansad.com/2025/03/18/e1_vigenere/</link><pubDate>Tue, 18 Mar 2025 12:32:52 +0800</pubDate><guid>https://dandansad.com/2025/03/18/e1_vigenere/</guid><description>&lt;h2 id="算法主要原理"&gt;&lt;a href="#%e7%ae%97%e6%b3%95%e4%b8%bb%e8%a6%81%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;算法主要原理
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;加密公式：C = (P + K)%26&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;C：密文&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P：原文&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;K：第几套加密方式&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;解密公式：P = (C - K)%26&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;C：密文&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P：原文&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;K：第几套加密方式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;如果P&amp;lt;0,P+26取得正序&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简单来说，Vigenere密码实际上就是分组的凯撒密码。而分组的方法就是重复密钥，密钥相同的明文为同一组。每一组都可以看作是由不同的密钥所加密的凯撒密码。&lt;/p&gt;
&lt;h2 id="算法步骤"&gt;&lt;a href="#%e7%ae%97%e6%b3%95%e6%ad%a5%e9%aa%a4" class="header-anchor"&gt;&lt;/a&gt;算法步骤
&lt;/h2&gt;&lt;h3 id="加解密"&gt;&lt;a href="#%e5%8a%a0%e8%a7%a3%e5%af%86" class="header-anchor"&gt;&lt;/a&gt;加/解密
&lt;/h3&gt;&lt;p&gt;维吉尼亚密码是一种经典的多表替换加密算法，其改进了凯撒密码单表替换的弱点，通过使用不同的字母移位规则，使得频率分析攻击更加困难。&lt;/p&gt;
&lt;p&gt;实际上可以将维吉尼亚密码理解为多个凯撒密码的加密，它的核心思想是用一个关键词来控制加密过程，使得同样的字母在明文的不同位置可能会被加密成不同的密文字母，这样就比简单的凯撒密码安全得多。&lt;/p&gt;
&lt;p&gt;加密的时候就是把明文的每个字母按照密钥字母对应的数值进行移位，比如密钥字母A代表移0位（相当于不变），B移1位，一直到Z移25位。例如，当加密&amp;quot;HELLO&amp;quot;这个单词，选择的密钥是&amp;quot;KEY&amp;quot;，首先要把密钥重复到和明文一样长变成&amp;quot;KEYKE&amp;quot;，然后每个明文字母都对应一个密钥字母。然后每个字母加密时，H（在字母表里排第7位）对应K（排第10位），就往后移10位变成R（第17位）；E（第4位）对应E（第4位），移4位变成I（第8位）；第一个L（第11位）对应Y（第24位），11加24等于35，因为字母表只有26个字母，所以35减26得到9，对应J；第二个L（第11位）对应K（第10位），11加10等于21，对应V；O（第14位）对应E（第4位），14加4等于18，对应S。这样最终&amp;quot;HELLO&amp;quot;就被加密成了&amp;quot;RIJVS&amp;quot;。但要注意的是字母表是循环的，超过Z就要回到A继续算，所以计算时要取模26。&lt;/p&gt;
&lt;p&gt;解密过程与加密过程相反，用密文字母和密钥字母相减，比如R（17位）减去K（10位）得到7对应H，I（8位）减E（4位）得到4对应E，以此类推。如果遇到字母相减得到负数的情况，把负数加上26就能得到正确的结果。&lt;/p&gt;
&lt;h3 id="破解"&gt;&lt;a href="#%e7%a0%b4%e8%a7%a3" class="header-anchor"&gt;&lt;/a&gt;破解
&lt;/h3&gt;&lt;p&gt;维吉尼亚密码的核心安全特性来自于它的多表代换机制，但这也恰恰成为它被破解的突破口。要理解破解原理，我们需要先认清一个关键事实：&lt;strong&gt;维吉尼亚密码本质上是多个凯撒密码的交替使用。&lt;/strong&gt;****&lt;/p&gt;
&lt;p&gt;具体说来则是密钥长度决定了位移序列的长度，也即维吉尼亚密码是在循环应用一组固定的凯撒密码。若是我们确定了其密钥长度，则分组后的密码实际上呈现出单表特性，每组内部都是纯粹的凯撒密码，完全保留自然语言的统计特征。&lt;/p&gt;
&lt;p&gt;因此破解维吉尼亚密码的重中之重是要破解出密钥长度，确定了密钥长度后就和破解凯撒密码无异了。所以说我们的破解步骤就分为&lt;strong&gt;确定密钥长度&lt;/strong&gt;和&lt;strong&gt;确定密钥内容&lt;/strong&gt;两步。&lt;/p&gt;
&lt;h4 id="一确定密钥长度重合指数法确定密钥长度"&gt;&lt;a href="#%e4%b8%80%e7%a1%ae%e5%ae%9a%e5%af%86%e9%92%a5%e9%95%bf%e5%ba%a6%e9%87%8d%e5%90%88%e6%8c%87%e6%95%b0%e6%b3%95%e7%a1%ae%e5%ae%9a%e5%af%86%e9%92%a5%e9%95%bf%e5%ba%a6" class="header-anchor"&gt;&lt;/a&gt;（一）&lt;strong&gt;确定密钥长度&lt;/strong&gt;——重合指数法确定密钥长度
&lt;/h4&gt;&lt;p&gt;确定密钥长度这一步，我们采用重合指数法来确定。&lt;/p&gt;
&lt;p&gt;因为对于正常的英语分布来说，从正常英语句子中随机取两个元素相同的概率是0.065，而如果是完全随机的字符串概率则是0.038。0.038~0.065之间的差距，让我们可以检验某一段文字是否符合正常的英语分布。&lt;/p&gt;
&lt;p&gt;所以说，我们先假定密钥长度，便可以分出多组密文。每组密文内都是用相同的密钥加密的，因此只要是正常的、有意义的英文句子便符合0.065的概率。我们遍历可能的密钥长度，计算出接近0.065的值后取最小值就可以得到密钥长度。（当遍历的密钥长度稍长时，可能会出现真正密钥长度的倍数的IC会更接近0.065的情况，因此最好选容许的误差范围中的最小值）&lt;/p&gt;
&lt;p&gt;以下是详细的数学证明过程：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-9-862x1024.png"&gt;&lt;/p&gt;
&lt;h4 id="二确定密钥内容使用卡方检验确定密钥的内容"&gt;&lt;a href="#%e4%ba%8c%e7%a1%ae%e5%ae%9a%e5%af%86%e9%92%a5%e5%86%85%e5%ae%b9%e4%bd%bf%e7%94%a8%e5%8d%a1%e6%96%b9%e6%a3%80%e9%aa%8c%e7%a1%ae%e5%ae%9a%e5%af%86%e9%92%a5%e7%9a%84%e5%86%85%e5%ae%b9" class="header-anchor"&gt;&lt;/a&gt;（二）&lt;strong&gt;确定密钥内容&lt;/strong&gt;——使用卡方检验确定密钥的内容
&lt;/h4&gt;&lt;p&gt;在确定密钥内容这一步，我们使用卡方检验来确定。&lt;/p&gt;
&lt;p&gt;之前的步骤中我们已经将维吉尼亚密码转换为了多组凯撒密码。而对于凯撒密码来说，因为所有自然语言都存在特定的字母出现频率规律，单表替换加密虽然改变了字母的表象，但完整保留了这种统计特征。以英语为例，字母E的出现频率高达12.7%，T约9.1%，A约8.2%，这种分布特征就像语言的&amp;quot;指纹&amp;quot;一样稳定。当我们将明文通过凯撒密码加密时，整个字母表只是被整体平移了一定位数，比如位移3的情况下，原本高频的E会被统一替换成H，T变成W，A变成D，此时密文中H、W、D就会成为新的高频字母，它们与原始高频字母的对应关系完全由位移量决定。&lt;/p&gt;
&lt;p&gt;那我们首先需要统计密文中各字母的出现频率，制作频率分布表，然后将这个统计结果与目标语言的标准字母频率进行对比匹配，这一步我们使用卡方检验。卡方检验可以通过量化比较两个字母频率分布的差异程度，来找出最可能使用的位移量。这个卡方值的计算公式是：将每个字母在解密文本中的观察频次与标准英语中的期望频次之差的平方除以期望频次后求和。卡方值越小，说明解密后的字母频率分布与标准英语越接近，也就意味着这个位移量越有可能是正确的密钥。求出密钥后，我们便可以轻松解密维吉尼亚密码了。&lt;/p&gt;
&lt;h2 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h2&gt;&lt;p&gt;破解Vigenere算法最主要就是两个步骤——&lt;strong&gt;确定密钥长度&lt;/strong&gt;和&lt;strong&gt;确定密钥内容&lt;/strong&gt;，而这两个步骤实际上都是利用了英语字母的分布规律来破解的，一个是通过&lt;strong&gt;重合指数&lt;/strong&gt;，一个是通过&lt;strong&gt;卡方检验&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="程序运行截图"&gt;&lt;a href="#%e7%a8%8b%e5%ba%8f%e8%bf%90%e8%a1%8c%e6%88%aa%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;程序运行截图
&lt;/h2&gt;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-13.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-14.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-15.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-16.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="../../images/2025/03/image-17.png"&gt;&lt;/p&gt;
&lt;h2 id="参考代码"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e4%bb%a3%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;参考代码
&lt;/h2&gt;&lt;h3 id="endecryptpy"&gt;&lt;a href="#endecryptpy" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;endecrypt.py&lt;/strong&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Vigenere Cipher Encrypt/Decrypt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 字母转数字&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;L2N&lt;/span&gt;(L):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ord(L&lt;span style="color:#f92672"&gt;.&lt;/span&gt;upper()) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 数字转字母&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;N2L&lt;/span&gt;(N):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; chr(N &lt;span style="color:#f92672"&gt;+&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 加密&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;encrypt&lt;/span&gt;(text, key):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; encrypted_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(len(text)):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(text[i]&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isalpha()):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; encrypted_text &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; N2L((L2N(text[i]) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; L2N(key[j&lt;span style="color:#f92672"&gt;%&lt;/span&gt;len(key)])) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;+=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; encrypted_text
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 解密&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;decrypt&lt;/span&gt;(text, key):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; decrypted_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(len(text)):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; decrypted_text &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; N2L((L2N(text[i]) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; L2N(key[j&lt;span style="color:#f92672"&gt;%&lt;/span&gt;len(key)])) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;+=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; decrypted_text
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;I am alive here, my beloved, for the reason to adore you. Oh!How anxious I have been for you and how sorry I am about all you must have suffered in having no news from us. May heaven grant that this letter reaches you. Do not write to me, this would compromise all of us and above all,do not return under any circumstances. It is known that it was you who helped us to get away from here and all would be lost if you should show yourself.We are guarded day and night. I do not care you are not here. Do not be troubled on my account. Nothing will happen to me. The national assemble will show leniency. Farewell the most loved of men. Be quiet if you can take care of yourself.For myself I cannot write any more, but nothing in the world could stop me to adore you up to the death.&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;crypt&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(encrypt(text, key)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;lower())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="crackpy"&gt;&lt;a href="#crackpy" class="header-anchor"&gt;&lt;/a&gt;&lt;strong&gt;crack.py&lt;/strong&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Vigenere Cipher Crack&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; math
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; typing &lt;span style="color:#f92672"&gt;import&lt;/span&gt; List, Tuple
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alpha&lt;/span&gt;(cipher: str) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 预处理函数：去掉密文中的非字母字符（如空格、回车、标点符号等）。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 只包含字母的密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; char &lt;span style="color:#f92672"&gt;in&lt;/span&gt; cipher:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; char&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isalpha():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; char
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_IC&lt;/span&gt;(cipher: str) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 计算字符串的重合指数（IC）。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 重合指数值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(cipher)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; char &lt;span style="color:#f92672"&gt;in&lt;/span&gt; cipher:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; char&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isupper():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count[ord(char) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;A&amp;#34;&lt;/span&gt;)] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; char&lt;span style="color:#f92672"&gt;.&lt;/span&gt;islower():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count[ord(char) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;)] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; (count[i] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (count[i] &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; (L &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (L &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; IC
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_key_len&lt;/span&gt;(cipher: str, key_len: int) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 对密文按密钥长度分组，并计算每组的平均重合指数。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key_len: 密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 平均重合指数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; groups &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; key_len
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; key_len
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(len(cipher)):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; m &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;%&lt;/span&gt; key_len
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; groups[m] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; cipher[i]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(key_len):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; count_IC(groups[i])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;长度为&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;key_len&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;时, 平均重合指数为&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean(IC)&lt;span style="color:#e6db74"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;.5f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean(IC)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;determine_key_length&lt;/span&gt;(cipher: str, tolerance: float &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.01&lt;/span&gt;) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; int:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 确定最可能的密钥长度。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param tolerance: 允许的重合指数误差范围
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 最可能的密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possible_lengths &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储可能的密钥长度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; key_len &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;): &lt;span style="color:#75715e"&gt;# 尝试密钥长度从1到100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; avg_IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; count_key_len(cipher, key_len)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; abs(avg_IC &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.065&lt;/span&gt;) int:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 确定最可能的密钥长度。(老旧版本)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 最可能的密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; key_len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; min_diff &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; avg_IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; current_IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; count_key_len(cipher, i)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; abs(current_IC &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.065&lt;/span&gt;) float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 计算卡方统计量，用于评估解密后的文本是否符合英文字母频率分布。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param vec: 密文的子串（按密钥长度分组后的某一组）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key: 尝试的密钥偏移量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 卡方统计量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; freq &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 统计字母频率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; c &lt;span style="color:#f92672"&gt;in&lt;/span&gt; vec:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; c&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isalpha():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c&lt;span style="color:#f92672"&gt;.&lt;/span&gt;lower()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; chr((ord(c) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; key)) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; freq[ord(c) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;)] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 英文字母的期望频率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; expected_freq &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.08167&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.01492&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02782&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.04253&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.12702&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02228&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02015&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.06094&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.06966&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00153&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00772&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.04025&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02406&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.06749&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.07507&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.01929&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00095&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.05987&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.06327&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.09056&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02758&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00978&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02360&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00150&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.01974&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00074&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 确保期望频率的总和为1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;assert&lt;/span&gt; abs(&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; sum(expected_freq)) List[int]:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 使用卡方检验确定每组最可能的相对偏移量。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key_len: 密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 相对偏移量列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possible_key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储可能的密钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(key_len):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 生成当前分组的子串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vec &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [cipher[j] &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(i, len(cipher), key_len)]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 尝试所有可能的偏移量（0-25）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possibility_array &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr_chi_square &lt;span style="color:#f92672"&gt;=&lt;/span&gt; chi_square(vec, j)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possibility_array&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append((chr(ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; j), curr_chi_square))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 按卡方值从小到大排序（卡方值越小，可能性越大）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possibility_array&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sort(key&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;lambda&lt;/span&gt; x: x[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 选择卡方值最小的偏移量作为当前分组的密钥字母&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possible_key&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(ord(possibility_array[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;][&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; possible_key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;decrypt&lt;/span&gt;(cipher: str, key_len: int, shifts: List[int]) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 使用密钥对密文进行解密。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key_len: 密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param shifts: 密钥字母的下标列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 解密后的明文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plain &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; i str:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 预处理函数：去掉密文中的非字母字符（如空格、回车、标点符号等）。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 只包含字母的密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; char &lt;span style="color:#f92672"&gt;in&lt;/span&gt; cipher:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; char&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isalpha():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; char
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_IC&lt;/span&gt;(cipher: str) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 计算字符串的重合指数（IC）。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 重合指数值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; L &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len(cipher)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; char &lt;span style="color:#f92672"&gt;in&lt;/span&gt; cipher:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; char&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isupper():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count[ord(char) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;A&amp;#34;&lt;/span&gt;)] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; char&lt;span style="color:#f92672"&gt;.&lt;/span&gt;islower():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count[ord(char) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;)] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; (count[i] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (count[i] &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; (L &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (L &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; IC
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;count_key_len&lt;/span&gt;(cipher: str, key_len: int) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 对密文按密钥长度分组，并计算每组的平均重合指数。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key_len: 密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 平均重合指数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; groups &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; key_len
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; key_len
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(len(cipher)):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; m &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;%&lt;/span&gt; key_len
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; groups[m] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; cipher[i]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(key_len):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; count_IC(groups[i])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean(IC)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;determine_key_length&lt;/span&gt;(cipher: str, tolerance: float &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.01&lt;/span&gt;) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; int:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 确定最可能的密钥长度。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param tolerance: 允许的重合指数误差范围
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 最可能的密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possible_lengths &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储可能的密钥长度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC_values &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储每个密钥长度对应的重合指数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; key_len &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;): &lt;span style="color:#75715e"&gt;# 尝试密钥长度从1到100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; avg_IC &lt;span style="color:#f92672"&gt;=&lt;/span&gt; count_key_len(cipher, key_len)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IC_values&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(avg_IC)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; abs(avg_IC &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.065&lt;/span&gt;) float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 计算卡方统计量，用于评估解密后的文本是否符合英文字母频率分布。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param vec: 密文的子串（按密钥长度分组后的某一组）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key: 尝试的密钥偏移量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 卡方统计量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; freq &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 统计字母频率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; c &lt;span style="color:#f92672"&gt;in&lt;/span&gt; vec:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; c&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isalpha():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c&lt;span style="color:#f92672"&gt;.&lt;/span&gt;lower()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; chr((ord(c) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; key)) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; freq[ord(c) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;)] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 英文字母的期望频率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; expected_freq &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.08167&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.01492&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.02782&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.04253&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.12702&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.02228&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.02015&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.06094&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.06966&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.00153&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.00772&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.04025&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.02406&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.06749&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.07507&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.01929&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.00095&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.05987&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.06327&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.09056&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0.02758&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.00978&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.02360&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.00150&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.01974&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.00074&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 确保期望频率的总和为1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;assert&lt;/span&gt; abs(&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; sum(expected_freq)) Tuple[List[int], List[List[float]]]:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 使用卡方检验确定每组与第一组之间的相对偏移量。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key_len: 密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 相对偏移量列表和每一组的卡方值列表（未排序）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possible_key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储可能的密钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; chi_square_values &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储每一组的卡方值（未排序）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(key_len):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 生成当前分组的子串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vec &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [cipher[j] &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(i, len(cipher), key_len)]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 尝试所有可能的偏移量（0-25）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; chi_values &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [] &lt;span style="color:#75715e"&gt;# 存储当前分组的卡方值（未排序）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curr_chi_square &lt;span style="color:#f92672"&gt;=&lt;/span&gt; chi_square(vec, j)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; chi_values&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(curr_chi_square)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 按卡方值从小到大排序（卡方值越小，可能性越大）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sorted_indices &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;argsort(chi_values) &lt;span style="color:#75715e"&gt;# 获取排序后的索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; best_shift &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sorted_indices[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#75715e"&gt;# 选择卡方值最小的偏移量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 存储结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; possible_key&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(best_shift)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; chi_square_values&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(chi_values) &lt;span style="color:#75715e"&gt;# 存储未排序的卡方值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; possible_key, chi_square_values
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;decrypt&lt;/span&gt;(cipher: str, key_len: int, shifts: List[int]) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 使用密钥对密文进行解密。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param cipher: 密文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param key_len: 密钥长度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param shifts: 密钥字母的下标列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :return: 解密后的明文字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plain &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; len(cipher):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; j &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(key_len):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; cipher[i]&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isupper():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plain &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; chr(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (ord(cipher[i]) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;A&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; shifts[j] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;A&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plain &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; chr(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (ord(cipher[i]) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; shifts[j] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; ord(&lt;span style="color:#e6db74"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; i &lt;span style="color:#f92672"&gt;==&lt;/span&gt; len(cipher):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; plain
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# GUI 界面&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;VigenereCrackerApp&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, root):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;root &lt;span style="color:#f92672"&gt;=&lt;/span&gt; root
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;root&lt;span style="color:#f92672"&gt;.&lt;/span&gt;title(&lt;span style="color:#e6db74"&gt;&amp;#34;维吉尼亚密码工具&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cipher &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shifts &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plain &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show_plots &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;BooleanVar(value&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 是否展示柱状图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 创建选项卡&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;notebook &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Notebook(root)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;notebook&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack(fill&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;both&amp;#34;&lt;/span&gt;, expand&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 添加“加/解密”选项卡&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_encrypt_decrypt_tab()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 添加“破解”选项卡&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_crack_tab()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add_encrypt_decrypt_tab&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;添加加/解密选项卡&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tab &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Frame(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;notebook)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;notebook&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;加/解密&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 输入框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; input_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Label(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;原文：&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; input_label&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, sticky&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text_encrypt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Text(tab, height&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;, width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 密钥输入框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; key_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Label(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;密钥：&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; key_label&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, sticky&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_entry &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Entry(tab, width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_entry&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, sticky&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 创建一个 Frame 来放置按钮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; button_frame &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Frame(tab)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; button_frame&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, columnspan&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 加密按钮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; encrypt_button &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Button(button_frame, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;👇加密👇&amp;#34;&lt;/span&gt;, command&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;encrypt_text)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; encrypt_button&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack(side&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;left&amp;#34;&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 解密按钮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; decrypt_button &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Button(button_frame, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;👆解密👆&amp;#34;&lt;/span&gt;, command&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;decrypt_text)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; decrypt_button&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack(side&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;left&amp;#34;&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 输出框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; output_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Label(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;密文：&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; output_label&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, sticky&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text_encrypt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Text(tab, height&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;, width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add_crack_tab&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;添加破解选项卡&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tab &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Frame(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;notebook)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;notebook&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;破解&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 输入框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; input_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Label(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;输入密文：&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; input_label&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, sticky&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Text(tab, height&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;, width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 输出框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; output_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Label(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;输出结果：&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; output_label&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, sticky&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Text(tab, height&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;, width&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 按钮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step1_button &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Button(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;1. 确定密钥长度&amp;#34;&lt;/span&gt;, command&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step1_button&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step2_button &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Button(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;2. 确定密钥&amp;#34;&lt;/span&gt;, command&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step2)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step2_button&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step3_button &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Button(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;3. 解密&amp;#34;&lt;/span&gt;, command&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step3)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;step3_button&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 是否展示柱状图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plot_check &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ttk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Checkbutton(tab, text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;展示柱状图&amp;#34;&lt;/span&gt;, variable&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show_plots)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plot_check&lt;span style="color:#f92672"&gt;.&lt;/span&gt;grid(row&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, column&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padx&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;encrypt_text&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;加密文本&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get(&lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;, tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strip() &lt;span style="color:#75715e"&gt;# 获取明文&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_entry&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strip() &lt;span style="color:#75715e"&gt;# 获取密钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; text &lt;span style="color:#f92672"&gt;or&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; key:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; messagebox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;showerror(&lt;span style="color:#e6db74"&gt;&amp;#34;错误&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;请输入明文和密钥！&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; encrypted_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; encrypt(text, key) &lt;span style="color:#75715e"&gt;# 调用加密函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;delete(&lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;, tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END) &lt;span style="color:#75715e"&gt;# 清空输出框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;insert(tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END, encrypted_text) &lt;span style="color:#75715e"&gt;# 显示密文&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;decrypt_text&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;解密文本&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get(&lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;, tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strip() &lt;span style="color:#75715e"&gt;# 获取密文&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_entry&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strip() &lt;span style="color:#75715e"&gt;# 获取密钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; text &lt;span style="color:#f92672"&gt;or&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; key:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; messagebox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;showerror(&lt;span style="color:#e6db74"&gt;&amp;#34;错误&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;请输入密文和密钥！&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; decrypted_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; decrypt_vigenere(text, key) &lt;span style="color:#75715e"&gt;# 调用解密函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;delete(&lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;, tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END) &lt;span style="color:#75715e"&gt;# 清空输入框&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text_encrypt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;insert(tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END, decrypted_text) &lt;span style="color:#75715e"&gt;# 显示明文&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;step1&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;第一步：确定密钥长度&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cipher &lt;span style="color:#f92672"&gt;=&lt;/span&gt; alpha(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;input_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get(&lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;, tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strip())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_len, IC_values &lt;span style="color:#f92672"&gt;=&lt;/span&gt; determine_key_length(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cipher)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;delete(&lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;, tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;insert(tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END, &lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;密钥长度为: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_len&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 展示重合指数与密钥长度的图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show_plots&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plot_IC_vs_keylen(IC_values)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ValueError&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; e:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; messagebox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;showerror(&lt;span style="color:#e6db74"&gt;&amp;#34;错误&amp;#34;&lt;/span&gt;, str(e))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;step2&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;第二步：确定密钥&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_len:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; messagebox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;showerror(&lt;span style="color:#e6db74"&gt;&amp;#34;错误&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;请先确定密钥长度！&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 调用 determine_relative_shifts 获取密钥和卡方值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shifts, chi_square_values &lt;span style="color:#f92672"&gt;=&lt;/span&gt; determine_relative_shifts(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cipher, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_len)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;insert(tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END, &lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;相对偏移量: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shifts&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 展示每一组的卡方与偏移量的图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show_plots&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plot_chi_square_vs_shift(chi_square_values)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;step3&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;第三步：解密&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shifts:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; messagebox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;showerror(&lt;span style="color:#e6db74"&gt;&amp;#34;错误&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;请先确定密钥！&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plain &lt;span style="color:#f92672"&gt;=&lt;/span&gt; decrypt(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;cipher, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key_len, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shifts)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;output_text&lt;span style="color:#f92672"&gt;.&lt;/span&gt;insert(tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;END, &lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;解密后的明文: &lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;plain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plot_IC_vs_keylen&lt;/span&gt;(self, IC_values):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;绘制重合指数与密钥长度的柱状图&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fig, ax &lt;span style="color:#f92672"&gt;=&lt;/span&gt; plt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;subplots()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, len(IC_values) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 横轴：密钥长度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bar(x, IC_values) &lt;span style="color:#75715e"&gt;# 绘制柱状图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_xlabel(&lt;span style="color:#e6db74"&gt;&amp;#34;密钥长度&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_ylabel(&lt;span style="color:#e6db74"&gt;&amp;#34;重合指数&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_title(&lt;span style="color:#e6db74"&gt;&amp;#34;重合指数与密钥长度的关系&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plot_chi_square_vs_shift&lt;/span&gt;(self, chi_square_values):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 绘制每一组的卡方与偏移量的图。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; :param chi_square_values: 每一组的卡方值列表（未排序）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i, chi_values &lt;span style="color:#f92672"&gt;in&lt;/span&gt; enumerate(chi_square_values):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fig, ax &lt;span style="color:#f92672"&gt;=&lt;/span&gt; plt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;subplots()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 横轴：偏移量（0-25）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;bar(x, chi_values) &lt;span style="color:#75715e"&gt;# 绘制柱状图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_xlabel(&lt;span style="color:#e6db74"&gt;&amp;#34;偏移量&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_ylabel(&lt;span style="color:#e6db74"&gt;&amp;#34;卡方值&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ax&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_title(&lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;分组 &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;i&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; 的偏移量与卡方值&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; plt&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 运行 GUI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Tk()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app &lt;span style="color:#f92672"&gt;=&lt;/span&gt; VigenereCrackerApp(root)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mainloop()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参考资料"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-anchor"&gt;&lt;/a&gt;参考资料
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://blog.csdn.net/qq_47912072/article/details/112684665" target="_blank" rel="noopener"
 &gt;维吉尼亚密码的破解算法及python代码实现_维吉尼亚密码解密代码-CSDN博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.zhihu.com/question/494708265/answer/3630012436" target="_blank" rel="noopener"
 &gt;维吉尼亚密码产生密文，和密钥，如何得到明文? - 知乎&lt;/a&gt;&lt;/p&gt;</description></item><item><title>U2F相关疑问</title><link>https://dandansad.com/2025/03/02/u2f%E7%9B%B8%E5%85%B3%E7%96%91%E9%97%AE/</link><pubDate>Sun, 02 Mar 2025 17:16:08 +0800</pubDate><guid>https://dandansad.com/2025/03/02/u2f%E7%9B%B8%E5%85%B3%E7%96%91%E9%97%AE/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;本文为人工智能问答记录，内容仅供参考，可能存在错误信息。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="这个服务器的名称若是攻击者伪造的那不是照样没用吗比如攻击者伪造成amazoncom"&gt;&lt;a href="#%e8%bf%99%e4%b8%aa%e6%9c%8d%e5%8a%a1%e5%99%a8%e7%9a%84%e5%90%8d%e7%a7%b0%e8%8b%a5%e6%98%af%e6%94%bb%e5%87%bb%e8%80%85%e4%bc%aa%e9%80%a0%e7%9a%84%e9%82%a3%e4%b8%8d%e6%98%af%e7%85%a7%e6%a0%b7%e6%b2%a1%e7%94%a8%e5%90%97%e6%af%94%e5%a6%82%e6%94%bb%e5%87%bb%e8%80%85%e4%bc%aa%e9%80%a0%e6%88%90amazoncom" class="header-anchor"&gt;&lt;/a&gt;这个服务器的名称若是攻击者伪造的，那不是照样没用吗，比如攻击者伪造成amazon.com
&lt;/h2&gt;&lt;p&gt;你提出了一个很好的问题！如果攻击者能够伪造服务器的名称（例如，将伪造的网站名称设置为 &lt;code&gt;amazon.com&lt;/code&gt;），那么这种机制确实可能会失效。让我们深入分析一下这种情况，并解释为什么在实际应用中，这种攻击仍然可以被有效防范。&lt;/p&gt;
&lt;h3 id="1-服务器名称的真实性依赖于-https-和证书"&gt;&lt;a href="#1-%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%90%8d%e7%a7%b0%e7%9a%84%e7%9c%9f%e5%ae%9e%e6%80%a7%e4%be%9d%e8%b5%96%e4%ba%8e-https-%e5%92%8c%e8%af%81%e4%b9%a6" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;服务器名称的真实性依赖于 HTTPS 和证书&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在现代互联网中，网站的真实性是通过 &lt;strong&gt;HTTPS&lt;/strong&gt; 和 &lt;strong&gt;SSL/TLS 证书&lt;/strong&gt; 来验证的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;当用户访问 &lt;code&gt;amazon.com&lt;/code&gt; 时，浏览器会检查该网站的 SSL/TLS 证书，确保证书是由受信任的证书颁发机构（CA）签发的，并且证书中的域名与用户访问的域名一致。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者试图伪造 &lt;code&gt;amazon.com&lt;/code&gt;，他们无法获取由受信任的 CA 签发的有效证书（除非他们攻破了 CA 或用户的系统），因此浏览器会显示警告，提示用户该网站不安全。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-u2f-设备如何验证服务器名称"&gt;&lt;a href="#2-u2f-%e8%ae%be%e5%a4%87%e5%a6%82%e4%bd%95%e9%aa%8c%e8%af%81%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%90%8d%e7%a7%b0" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;U2F 设备如何验证服务器名称&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;U2F 设备（如硬件密钥）在生成认证代码时，会检查用户正在访问的网站的真实性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设备会通过浏览器的安全上下文获取网站的域名，并确保该域名与 SSL/TLS 证书中的域名一致。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者伪造了 &lt;code&gt;amazon.com&lt;/code&gt;，但由于没有有效的证书，U2F 设备会拒绝生成认证代码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-攻击者伪造域名的难度"&gt;&lt;a href="#3-%e6%94%bb%e5%87%bb%e8%80%85%e4%bc%aa%e9%80%a0%e5%9f%9f%e5%90%8d%e7%9a%84%e9%9a%be%e5%ba%a6" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;攻击者伪造域名的难度&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;攻击者要成功伪造 &lt;code&gt;amazon.com&lt;/code&gt;，需要满足以下条件：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;获取有效的 SSL/TLS 证书&lt;/strong&gt;：这几乎是不可能的，因为受信任的 CA 不会为攻击者签发 &lt;code&gt;amazon.com&lt;/code&gt; 的证书。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;绕过浏览器的安全机制&lt;/strong&gt;：现代浏览器会严格检查证书的有效性，并阻止用户访问没有有效证书的网站。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;欺骗 U2F 设备&lt;/strong&gt;：U2F 设备会验证网站的真实性，攻击者无法欺骗设备生成针对伪造网站的代码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-如果攻击者成功伪造域名会怎样"&gt;&lt;a href="#4-%e5%a6%82%e6%9e%9c%e6%94%bb%e5%87%bb%e8%80%85%e6%88%90%e5%8a%9f%e4%bc%aa%e9%80%a0%e5%9f%9f%e5%90%8d%e4%bc%9a%e6%80%8e%e6%a0%b7" class="header-anchor"&gt;&lt;/a&gt;4. &lt;strong&gt;如果攻击者成功伪造域名会怎样？&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者通过某种方式成功伪造了 &lt;code&gt;amazon.com&lt;/code&gt;（例如，通过 DNS 劫持或中间人攻击），U2F 设备可能会生成针对伪造网站的代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然而，这种攻击需要极高的技术能力，并且通常需要用户忽略浏览器的安全警告（例如“此网站不安全”）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;即使攻击者成功获取了针对伪造网站的代码，他们也无法使用该代码登录真实的 &lt;code&gt;amazon.com&lt;/code&gt;，因为代码是与伪造网站绑定的。&lt;/em&gt;（有误）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h3&gt;&lt;p&gt;虽然理论上攻击者可以伪造服务器名称，但在实际应用中，这种攻击的难度非常高，且需要绕过多层安全机制（如 HTTPS、SSL/TLS 证书、浏览器安全检查和 U2F 设备的验证）。因此，这种基于服务器名称的认证机制仍然是一种有效的反钓鱼手段。&lt;/p&gt;
&lt;h2 id="即使攻击者成功获取了针对伪造网站的代码他们也无法使用该代码登录真实的-amazoncom因为代码是与伪造网站绑定的-这句话有问题吧如果攻击者把网站地址伪造成了amazoncom生成的mackramazoncom不就可以正常登录了吗"&gt;&lt;a href="#%e5%8d%b3%e4%bd%bf%e6%94%bb%e5%87%bb%e8%80%85%e6%88%90%e5%8a%9f%e8%8e%b7%e5%8f%96%e4%ba%86%e9%92%88%e5%af%b9%e4%bc%aa%e9%80%a0%e7%bd%91%e7%ab%99%e7%9a%84%e4%bb%a3%e7%a0%81%e4%bb%96%e4%bb%ac%e4%b9%9f%e6%97%a0%e6%b3%95%e4%bd%bf%e7%94%a8%e8%af%a5%e4%bb%a3%e7%a0%81%e7%99%bb%e5%bd%95%e7%9c%9f%e5%ae%9e%e7%9a%84-amazoncom%e5%9b%a0%e4%b8%ba%e4%bb%a3%e7%a0%81%e6%98%af%e4%b8%8e%e4%bc%aa%e9%80%a0%e7%bd%91%e7%ab%99%e7%bb%91%e5%ae%9a%e7%9a%84-%e8%bf%99%e5%8f%a5%e8%af%9d%e6%9c%89%e9%97%ae%e9%a2%98%e5%90%a7%e5%a6%82%e6%9e%9c%e6%94%bb%e5%87%bb%e8%80%85%e6%8a%8a%e7%bd%91%e7%ab%99%e5%9c%b0%e5%9d%80%e4%bc%aa%e9%80%a0%e6%88%90%e4%ba%86amazoncom%e7%94%9f%e6%88%90%e7%9a%84mackramazoncom%e4%b8%8d%e5%b0%b1%e5%8f%af%e4%bb%a5%e6%ad%a3%e5%b8%b8%e7%99%bb%e5%bd%95%e4%ba%86%e5%90%97" class="header-anchor"&gt;&lt;/a&gt;即使攻击者成功获取了针对伪造网站的代码，他们也无法使用该代码登录真实的 amazon.com，因为代码是与伪造网站绑定的。 这句话有问题吧，如果攻击者把网站地址伪造成了amazon.com，生成的MAC(k,r∥amazon.com)不就可以正常登录了吗
&lt;/h2&gt;&lt;p&gt;你说得对！如果攻击者成功将网站地址伪造成 &lt;code&gt;amazon.com&lt;/code&gt;，并且生成了 &lt;code&gt;MAC(k, r∥amazon.com)&lt;/code&gt;，那么理论上这个代码是可以用于登录真实的 &lt;code&gt;amazon.com&lt;/code&gt; 的。我的之前的解释确实不够准确，感谢你指出这一点！让我们重新分析这个问题，并更清晰地解释为什么这种攻击在实际中仍然难以成功。&lt;/p&gt;
&lt;h3 id="1-攻击者伪造"&gt;&lt;a href="#1-%e6%94%bb%e5%87%bb%e8%80%85%e4%bc%aa%e9%80%a0" class="header-anchor"&gt;&lt;/a&gt;1. &lt;strong&gt;攻击者伪造 &lt;code&gt;amazon.com&lt;/code&gt; 的难度&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;攻击者要成功伪造 &lt;code&gt;amazon.com&lt;/code&gt;，需要满足以下条件：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;域名伪造&lt;/strong&gt;：攻击者需要通过某种方式（如 DNS 劫持或中间人攻击）将用户重定向到伪造的网站。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSL/TLS 证书伪造&lt;/strong&gt;：攻击者需要为伪造的网站获取有效的 SSL/TLS 证书，否则浏览器会显示安全警告，用户可能会察觉异常。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;欺骗 U2F 设备&lt;/strong&gt;：U2F 设备会验证网站的真实性，攻击者需要绕过这一机制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者成功伪造了 &lt;code&gt;amazon.com&lt;/code&gt;，并且生成了 &lt;code&gt;MAC(k, r∥amazon.com)&lt;/code&gt;，那么这个代码确实可以用于登录真实的 &lt;code&gt;amazon.com&lt;/code&gt;，因为代码是与 &lt;code&gt;amazon.com&lt;/code&gt; 绑定的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-为什么这种攻击仍然难以成功"&gt;&lt;a href="#2-%e4%b8%ba%e4%bb%80%e4%b9%88%e8%bf%99%e7%a7%8d%e6%94%bb%e5%87%bb%e4%bb%8d%e7%84%b6%e9%9a%be%e4%bb%a5%e6%88%90%e5%8a%9f" class="header-anchor"&gt;&lt;/a&gt;2. &lt;strong&gt;为什么这种攻击仍然难以成功&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SSL/TLS 证书的保护&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现代网站使用 HTTPS，依赖于 SSL/TLS 证书来验证网站的真实性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;攻击者无法为 &lt;code&gt;amazon.com&lt;/code&gt; 获取有效的 SSL/TLS 证书，除非他们攻破了受信任的证书颁发机构（CA）或用户的系统。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者使用自签名证书或无效证书，浏览器会显示安全警告，提示用户该网站不安全。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;U2F 设备的验证机制&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;U2F 设备会通过浏览器的安全上下文获取网站的域名，并确保该域名与 SSL/TLS 证书中的域名一致。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者伪造了 &lt;code&gt;amazon.com&lt;/code&gt;，但由于没有有效的证书，U2F 设备会拒绝生成认证代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用户的安全意识&lt;/strong&gt;：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现代浏览器会明确提示用户网站的安全性（例如，地址栏中的锁图标和“安全”字样）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果用户忽略浏览器的安全警告，攻击者可能会成功，但这需要用户主动配合。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-如果攻击者成功伪造"&gt;&lt;a href="#3-%e5%a6%82%e6%9e%9c%e6%94%bb%e5%87%bb%e8%80%85%e6%88%90%e5%8a%9f%e4%bc%aa%e9%80%a0" class="header-anchor"&gt;&lt;/a&gt;3. &lt;strong&gt;如果攻击者成功伪造 &lt;code&gt;amazon.com&lt;/code&gt; 会怎样？&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果攻击者通过某种方式成功伪造了 &lt;code&gt;amazon.com&lt;/code&gt;（例如，通过 DNS 劫持或中间人攻击），并且生成了 &lt;code&gt;MAC(k, r∥amazon.com)&lt;/code&gt;，那么这个代码确实可以用于登录真实的 &lt;code&gt;amazon.com&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然而，这种攻击需要极高的技术能力，并且通常需要用户忽略浏览器的安全警告。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-如何进一步防范这种攻击"&gt;&lt;a href="#4-%e5%a6%82%e4%bd%95%e8%bf%9b%e4%b8%80%e6%ad%a5%e9%98%b2%e8%8c%83%e8%bf%99%e7%a7%8d%e6%94%bb%e5%87%bb" class="header-anchor"&gt;&lt;/a&gt;4. &lt;strong&gt;如何进一步防范这种攻击&lt;/strong&gt;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;使用更高级的认证机制&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如，U2F 设备可以结合更多的上下文信息（如证书指纹或公钥）来验证网站的真实性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;提高用户的安全意识&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;教育用户不要忽略浏览器的安全警告，并检查网站的 SSL/TLS 证书。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;部署证书透明度（Certificate Transparency）&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是一种公开日志系统，可以检测和防止恶意或错误签发的 SSL/TLS 证书。&lt;/p&gt;
&lt;h3 id="总结-1"&gt;&lt;a href="#%e6%80%bb%e7%bb%93-1" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h3&gt;&lt;p&gt;你提到的观点是正确的：如果攻击者成功伪造了 &lt;code&gt;amazon.com&lt;/code&gt;，生成的 &lt;code&gt;MAC(k, r∥amazon.com)&lt;/code&gt; 确实可以用于登录真实的 &lt;code&gt;amazon.com&lt;/code&gt;。然而，这种攻击的难度非常高，需要绕过 HTTPS、SSL/TLS 证书和 U2F 设备的验证机制。因此，尽管理论上存在这种可能性，但在实际应用中，这种攻击仍然非常难以成功。&lt;/p&gt;
&lt;p&gt;感谢你的指正！这让我更清晰地解释了这个问题。如果你有其他疑问，欢迎继续讨论！ 😊&lt;/p&gt;</description></item><item><title>PIN 和密码的区别</title><link>https://dandansad.com/2025/03/02/pin-%E5%92%8C%E5%AF%86%E7%A0%81%E7%9A%84%E5%8C%BA%E5%88%AB/</link><pubDate>Sun, 02 Mar 2025 17:13:54 +0800</pubDate><guid>https://dandansad.com/2025/03/02/pin-%E5%92%8C%E5%AF%86%E7%A0%81%E7%9A%84%E5%8C%BA%E5%88%AB/</guid><description>&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;PIN&lt;/th&gt;
					&lt;th&gt;密码&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;长度&lt;/td&gt;
					&lt;td&gt;4-6 位数字&lt;/td&gt;
					&lt;td&gt;至少 8 位，包含多种字符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;复杂度&lt;/td&gt;
					&lt;td&gt;低（仅数字）&lt;/td&gt;
					&lt;td&gt;高（字母、数字、符号）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;存储&lt;/td&gt;
					&lt;td&gt;通常存储在本地设备&lt;/td&gt;
					&lt;td&gt;通常存储在远程服务器上&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;用途&lt;/td&gt;
					&lt;td&gt;快速验证（如手机解锁、ATM）&lt;/td&gt;
					&lt;td&gt;高安全性场景（如银行账户）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;安全性&lt;/td&gt;
					&lt;td&gt;较低，但通常与硬件绑定&lt;/td&gt;
					&lt;td&gt;较高，但依赖服务器安全性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;用户体验&lt;/td&gt;
					&lt;td&gt;简单快捷&lt;/td&gt;
					&lt;td&gt;较复杂，可能需要密码管理器&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>Lec02-人员身份验证</title><link>https://dandansad.com/2025/03/02/lec02-%E4%BA%BA%E5%91%98%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81/</link><pubDate>Sun, 02 Mar 2025 17:09:30 +0800</pubDate><guid>https://dandansad.com/2025/03/02/lec02-%E4%BA%BA%E5%91%98%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;由于时间精力有限，目前只翻译部分内容。
本文使用人工智能协助翻译，内容仅供参考，可能有错误或遗漏。如果你对内容或超链接有疑问，可以查看原文。
参考资料地址：https://github.com/PKUFlyingPig/MIT6.1600&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h1 id="1-认证"&gt;&lt;a href="#1-%e8%ae%a4%e8%af%81" class="header-anchor"&gt;&lt;/a&gt;1 认证
&lt;/h1&gt;&lt;p&gt;通常情况下，计算机系统在处理请求之前会执行两个步骤请求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;验证&lt;/strong&gt;： 识别发出请求的人或机器（“当事人”）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;授权&lt;/strong&gt;： 决定委托人是否有权提出请求。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="2-密码passwords口令"&gt;&lt;a href="#2-%e5%af%86%e7%a0%81passwords%e5%8f%a3%e4%bb%a4" class="header-anchor"&gt;&lt;/a&gt;2 密码（&lt;code&gt;Passwords&lt;/code&gt;口令）
&lt;/h1&gt;&lt;p&gt;我们真正关心的是，对手将无法在少量的猜测中猜出你的密码。&lt;/p&gt;
&lt;p&gt;理想情况下，我们希望从对手的角度来看所有密码的可能性都是相同的。但事实并非如此。人们必须记住自己的密码，结果很多人可能会选择相同的密码。&lt;/p&gt;
&lt;p&gt;我们如何说服人类选择难以猜测的密码？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;需要更长的密码？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁止在密码中使用常用的英语单词吗？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;强制更改密码？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;是否要为该用户生成密码？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，尽管我们尽了最大努力，用户可能会选择简单的密码。为此，我们能做些什么呢？&lt;/p&gt;
&lt;h2 id="21-处理糟糕的密码"&gt;&lt;a href="#21-%e5%a4%84%e7%90%86%e7%b3%9f%e7%b3%95%e7%9a%84%e5%af%86%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;2.1 处理糟糕的密码
&lt;/h2&gt;&lt;p&gt;一个“好”密码可能从一个大约20位熵的分布中采样。用目前的技术，猜测$2^{20}$次是很容易的。因此，当使用密码作为认证机制时，我们必须找到一种限制猜测的方法。&lt;/p&gt;
&lt;p&gt;处理密码很容易猜测这一事实的一个标准方法是&lt;strong&gt;限制攻击者对密码的猜测次数&lt;/strong&gt;。限制猜测的数量可以有效地防止单个账户被泄露——前提是密码不会太弱。一个缺点是猜测限制造成了&lt;strong&gt;拒绝服务攻击&lt;/strong&gt;的可能性：攻击者可能会对你的密码进行10次猜测，并将你锁在你的手机或网上银行账户之外。&lt;/p&gt;
&lt;p&gt;此外，在许多物理计算机系统中，都有多个授权用户，每个用户都有自己的密码。如果猜测限制只在每个用户的基础上强制执行，那么如果允许对每个用户的密码猜测10次，攻击者通常会破坏机器上的某些帐户。防止这些类型的攻击需要一些额外的措施：网站&lt;strong&gt;通过IP限制使用密码验证身份的速率&lt;/strong&gt;，或&lt;strong&gt;使用验证码&lt;/strong&gt;，等等。&lt;/p&gt;
&lt;h2 id="22-存储密码"&gt;&lt;a href="#22-%e5%ad%98%e5%82%a8%e5%af%86%e7%a0%81" class="header-anchor"&gt;&lt;/a&gt;2.2 存储密码
&lt;/h2&gt;&lt;p&gt;正如我们所看到的，密码很容易猜测，因此完全避免基于密码的身份验证是最安全的选择。&lt;/p&gt;
&lt;p&gt;当系统必须使用密码进行身份验证时，存储密码的最安全的方法（例如，在服务器上）是使用&lt;strong&gt;加盐的加密密码哈希函数&lt;/strong&gt;。其目标是根据存储在服务器上的哈希值，使攻击者尽可能难以恢复明文密码。&lt;/p&gt;
&lt;p&gt;服务器选择一个随机的128位字符串，称为&lt;strong&gt;盐&lt;/strong&gt;，并且服务器存储盐和哈希值 $h = H(salt∥pw)$ ，$H$ 是一个特殊的密码哈希函数。&lt;/p&gt;
&lt;p&gt;然后，服务器存储一个像这样的表：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;user&lt;/th&gt;
					&lt;th&gt;salt&lt;/th&gt;
					&lt;th&gt;$H(salt∥pw)$&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;alice&lt;/td&gt;
					&lt;td&gt;$r_a$&lt;/td&gt;
					&lt;td&gt;$h_a$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;bob&lt;/td&gt;
					&lt;td&gt;$r_b$&lt;/td&gt;
					&lt;td&gt;$h_b$&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;同样，服务器可以使用盐和哈希函数来计算一个值 $h&amp;rsquo;=H（salt∥pw&amp;rsquo;）$ 。如果此散列值 $h&amp;rsquo;$ 与此用户的服务器存储值 $h$ 匹配，则服务器接受密码。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;密码哈希函数H被为相对耗时的计算，这使得攻击者更难以&lt;strong&gt;强制反转哈希值&lt;/strong&gt;，因为每次猜测密码都需要一秒钟的计算。（而不是计算标准哈希函数所需的微秒，比如SHA256）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用每个用户的随机盐，确保了对一个用户的密码的猜测在转换另一个用户的密码哈希时是无用的。加盐还可以击败&lt;strong&gt;预计算攻击&lt;/strong&gt;，攻击者预先计算许多常见密码的哈希，以加速稍后的哈希反转步骤。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="3-网络认证"&gt;&lt;a href="#3-%e7%bd%91%e7%bb%9c%e8%ae%a4%e8%af%81" class="header-anchor"&gt;&lt;/a&gt;3 网络认证
&lt;/h1&gt;&lt;p&gt;到目前为止，我们一直在讨论人类对设备（ATM、电话、笔记本电脑等）进行手动身份验证，通过在设备中物理地输入&lt;a class="link" href="https://dandansad.com/2025/03/02/pin-%e5%92%8c%e5%af%86%e7%a0%81%e7%9a%84%e5%8c%ba%e5%88%ab/" target="_blank" rel="noopener"
 &gt;PIN&lt;/a&gt;或密码。但是我们经常登录到网络上的一些服务器——Facebook、Gmail、MIT等等。在这个场景中，我们可以获取到更多身份验证机制和要求的安全属性。&lt;/p&gt;
&lt;h2 id="31-密码管理器"&gt;&lt;a href="#31-%e5%af%86%e7%a0%81%e7%ae%a1%e7%90%86%e5%99%a8" class="header-anchor"&gt;&lt;/a&gt;3.1 密码管理器
&lt;/h2&gt;&lt;p&gt;当使用密码对网站进行身份验证时，用户可以在他们的计算机上安装一个密码管理器，从而为他们生成随机密码。由于用户不需要记住这些密码，它们可以从高熵分布中真正随机抽样。一旦用户登录到他们的电脑，他们就可以访问他们随机生成的密码，并使用它们登录到他们的网站。&lt;/p&gt;
&lt;p&gt;但是基于密码的身份验证，即使有一个强大的密码，仍然需要通过网络发送密码。如果一个对手可以监视我们的网络，他们就可以看到我们的密码。我们稍后将讨论传输后安全，它可以防止网络窃听者，但更好的解决方案是在不通过网络发送密码的情况下进行身份验证。&lt;/p&gt;
&lt;h2 id="32-挑战-响应协议"&gt;&lt;a href="#32-%e6%8c%91%e6%88%98-%e5%93%8d%e5%ba%94%e5%8d%8f%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;3.2 挑战-响应协议
&lt;/h2&gt;&lt;p&gt;我们现在假设我们的计算机有一些密钥k（例如，一个随机的128位字符串），并且服务器也拥有相同的密钥k。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;服务器选择一个长随机字符串r，我们通常称其为nonce，并将其发送给身份验证客户端。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;客户端计算一个身份验证“标签”t←MAC（k，r），其中MAC（·，r）如果不知道k很难计算。（这里的函数MAC是一个消息认证码，我们将在？？中更具体地讨论它）将MAC标记t发送到服务器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;服务器从客户端接收到一个标签t‘，并确保t’=MAC（k，r）。如果是，则服务器认为身份验证已成功。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在实践中，客户端通常希望同时向服务器进行身份验证并发送请求请求，例如req= rm file.txt。为了实现这一点，客户端可以计算MAC标记t作为treq←MAC（k，r∥req），然后客户端将这对（treq，req）发送到服务器。通过这种方式，服务器可以同时对客户端进行身份验证，并确保请求请求来自客户端。&lt;/p&gt;
&lt;blockquote class="alert alert-note"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;📝&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;客户端同时向服务器进行身份验证并发送请求的一种不安全的方法是，客户端计算MAC标记t←MAC（k，r），然后向服务器发送（t，req）。网络攻击者可以在发送到服务器的途中将客户端的请求修改为（t，req‘），而服务器无法检测到此攻击。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;h1 id="4-双因素身份验证"&gt;&lt;a href="#4-%e5%8f%8c%e5%9b%a0%e7%b4%a0%e8%ba%ab%e4%bb%bd%e9%aa%8c%e8%af%81" class="header-anchor"&gt;&lt;/a&gt;4 双因素身份验证
&lt;/h1&gt;&lt;p&gt;正如我们已经看到的，密码是一种弱的身份验证机制：人类不擅长选择强密码，攻击者擅长窃取密码数据库，同时恢复许多用户的密码。&lt;/p&gt;
&lt;p&gt;加强基于密码的身份验证系统的一种常见技术是将密码与第二种身份验证方法结合起来——一种具有不同的失败模式。常见的身份验证方案有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一些你知道的东西：密码，&lt;a class="link" href="https://dandansad.com/2025/03/02/pin-%e5%92%8c%e5%af%86%e7%a0%81%e7%9a%84%e5%8c%ba%e5%88%ab/" target="_blank" rel="noopener"
 &gt;PIN&lt;/a&gt;，等等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一些你有的东西： USB钥匙，电话，等等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一些你是的：生物识别技术（指纹，面部识别标识符）。。。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="41-基于时间的一次性密码totp"&gt;&lt;a href="#41-%e5%9f%ba%e4%ba%8e%e6%97%b6%e9%97%b4%e7%9a%84%e4%b8%80%e6%ac%a1%e6%80%a7%e5%af%86%e7%a0%81totp" class="header-anchor"&gt;&lt;/a&gt;4.1 基于时间的一次性密码（TOTP）
&lt;/h2&gt;&lt;p&gt;在这种情况下，服务器会请求一个代码和密码。用户有一个设备，比如一个手机，它与服务器共享一个密钥k（例如，一个随机的128位字符串）。类似于MAC（k，gettimeofday()/30）。手机可以生成代码，并显示给用户，然后服务器可以通过重新计算代码来验证代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一个常见的攻击。&lt;/strong&gt; 基于时间的一次性密码也是不完善的身份验证机制。例如，攻击者可以通过假装是技术支持人员、用户的雇主或客户服务代表，简单地要求用户给她提供一次性代码。这本质上是一种&lt;strong&gt;网络钓鱼攻击&lt;/strong&gt;。然后代码可以持续30秒，所以攻击者就可以在网站的末端输入代码。类似的攻击还包括建立一个看起来像真实网站的假网站，等等。TOTP代码的一个好处（不像密码）是，攻击者必须在窃取后的30秒内使用被盗的TOTP代码，这需要更复杂的攻击。&lt;/p&gt;
&lt;blockquote class="alert alert-note"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;📝&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;&lt;strong&gt;网络钓鱼攻击&lt;/strong&gt;是指攻击者欺骗用户泄露Gmail密码，例如，通过创建一个看起来像gmail.com登录页面的网站。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;h2 id="42-避免网络钓鱼u2f简化"&gt;&lt;a href="#42-%e9%81%bf%e5%85%8d%e7%bd%91%e7%bb%9c%e9%92%93%e9%b1%bcu2f%e7%ae%80%e5%8c%96" class="header-anchor"&gt;&lt;/a&gt;4.2 避免网络钓鱼：U2F（简化）
&lt;/h2&gt;&lt;p&gt;为了完全防止网络钓鱼攻击，我们可以使用一个更复杂的身份验证协议。如果我们在我们发送到该设备的请求中包含了用户试图登录到的服务器的名称，那么该代码将被绑定到一个特定的网站。例如，这些代码可能看起来有点像MAC（k，r∥amazon.com）。U2F密钥组数沿着这些线路使用一个协议来进行身份验证。&lt;a class="link" href="https://dandansad.com/2025/03/02/u2f%e7%9b%b8%e5%85%b3%e7%96%91%e9%97%ae/" target="_blank" rel="noopener"
 &gt;如果攻击者设置了amason.com并让用户访问它，那么U2F设备将只生成一个适合amason.com的代码，而不是真正的amazon.com。&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="5-生物识别"&gt;&lt;a href="#5-%e7%94%9f%e7%89%a9%e8%af%86%e5%88%ab" class="header-anchor"&gt;&lt;/a&gt;5 生物识别
&lt;/h1&gt;&lt;p&gt;生物识别学是一些物理特征，比如指纹、面部等。它们用于身份验证非常方便，因为您不会忘记它们，也不会轻易丢失它们。生物识别技术在亲自对设备进行身份验证时最有用，比如手机解锁，或授予用户访问安全保险库。在这些设置中，执行身份验证的设备有一个“可信的输入路径”，这可以提供一些保证，即拥有该生物特征的真人是在另一端。生物识别技术对于通过网络进行身份验证并不是那么有用，因为网络通常不提供可信的输入路径（也就是说，不提供任何生物识别读数来自真实的人类），而且生物识别数据本身也不是特别秘密。特别是，如果我们使用生物识别技术进行网络身份验证，一个知道你的指纹是什么样子的对手可以登录到你的账户。&lt;/p&gt;</description></item><item><title>Lec01-什么是安全？</title><link>https://dandansad.com/2025/02/27/lec01-%E4%BB%80%E4%B9%88%E6%98%AF%E5%AE%89%E5%85%A8/</link><pubDate>Thu, 27 Feb 2025 15:12:55 +0800</pubDate><guid>https://dandansad.com/2025/02/27/lec01-%E4%BB%80%E4%B9%88%E6%98%AF%E5%AE%89%E5%85%A8/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;本文使用人工智能协助翻译，内容仅供参考，可能有错误或遗漏。如果你对内容或超链接有疑问，可以查看原文。
参考资料地址：https://github.com/PKUFlyingPig/MIT6.1600&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;6.1600课程团队：Henry Corrigan-Gibbs, Yael Kalai, Ben Kettle (TA), Nickolai Zeldovich
2022年秋季&lt;/p&gt;
&lt;blockquote class="alert alert-warning"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;⚠️&lt;/span&gt;
 &lt;span class="alert-title"&gt;免责声明&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;本套笔记为正在进行中的工作。其中可能存在错误，且缺少引用来源，内容亦不完整。如您发现任何错误，敬请告知工作人员。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;h1 id="1-概述"&gt;&lt;a href="#1-%e6%a6%82%e8%bf%b0" class="header-anchor"&gt;&lt;/a&gt;1 概述
&lt;/h1&gt;&lt;p&gt;本课程的目的是向您介绍有关计算机系统安全的最重要的 “重要理念”。在整个课程中，我们将涉及计算机安全、密码学和（在一定程度上）计算机系统等领域的观点。&lt;/p&gt;
&lt;h1 id="2-什么是安全"&gt;&lt;a href="#2-%e4%bb%80%e4%b9%88%e6%98%af%e5%ae%89%e5%85%a8" class="header-anchor"&gt;&lt;/a&gt;2 什么是安全？
&lt;/h1&gt;&lt;p&gt;安全是一个非常广泛的概念，但通常计算机安全的目标是确保某个计算机系统即使在面对试图破坏系统的“敌手”（或“攻击者”）时也能“正确运行”。&lt;/p&gt;
&lt;blockquote class="alert alert-info"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;在本课程中，我们将交替使用“敌手”和“攻击者”这两个术语。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;p&gt;为了实现这一目标，我们需要某种系统性的计划。也就是说，我们必须仔细定义系统“正确运行”的含义，并指定我们希望防御的“敌手”类别。&lt;/p&gt;
&lt;p&gt;在本课程中，我们通常将计划分为三个部分：&lt;strong&gt;目标&lt;/strong&gt;、&lt;strong&gt;威胁模型&lt;/strong&gt;和&lt;strong&gt;实现&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：安全目标定义了我们希望系统实现的内容。例如，一个非正式的目标可能是“只有Alice可以读取文件F”，或者“如果有人篡改文件F，Alice将能够检测到”。正如您将在课程中学到的，确定您的安全目标究竟是什么通常是非常微妙且具有挑战性的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;威胁模型&lt;/strong&gt;：威胁模型（或“敌手模型”）指定了我们希望防御的敌手类别。换句话说，威胁模型指定了敌手的能力：敌手在试图破坏我们的安全目标时可以做什么？通过定义威胁模型，我们可以使实现安全目标变得可行。例如，在分析基于密码的登录系统的安全性时，我们的威胁模型可能会指定敌手可以猜测密码，但不能窃取服务器。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实现&lt;/strong&gt;：实现是我们如何实现目标。例如，我们可能会设置文件F的权限，使用Linux来强制执行这些权限，并要求双因素认证来访问系统。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class="alert alert-info"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;当你在新闻中读到安全漏洞时，值得尝试去理解这个漏洞是由于&lt;strong&gt;目标&lt;/strong&gt;、&lt;strong&gt;威胁模型&lt;/strong&gt;还是&lt;strong&gt;实现&lt;/strong&gt;的问题引起的。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;p&gt;目标和威胁模型共同构成了我们对安全的&lt;strong&gt;定义&lt;/strong&gt;。因此，它们不可能是“错误的”——目标可能最终并不完全符合我们的需求，威胁模型可能没有涵盖我们的系统在现实世界中可能面临的所有攻击，系统设计师在发现这一点时可能会感到惊讶，但目标和威胁模型共同定义了我们希望实现的安全属性。另一方面，实现肯定可能是错误的——如果由于错误、疏忽、供应链漏洞或其他任何原因，实现无法在威胁模型下保证目标，那么实现就存在错误。&lt;/p&gt;
&lt;h2 id="21-安全是困难的"&gt;&lt;a href="#21-%e5%ae%89%e5%85%a8%e6%98%af%e5%9b%b0%e9%9a%be%e7%9a%84" class="header-anchor"&gt;&lt;/a&gt;2.1 安全是困难的
&lt;/h2&gt;&lt;p&gt;构建安全的系统是具有挑战性的。至少有两个广泛的原因。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先，安全系统必须防御最坏情况下的行为。&lt;/strong&gt; 安全系统必须防御威胁模型范围内的&lt;strong&gt;所有可能的攻击&lt;/strong&gt;。相比之下，当我们只关注功能或正确性时，我们通常满足于一个在用户关心的场景下表现良好的系统。换句话说，安全关注的是&lt;strong&gt;最坏情况下的行为&lt;/strong&gt;，而正确性通常关注的是&lt;strong&gt;预期情况下的行为&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote class="alert alert-info"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;一些开发者确实会担心他们的系统在所有可能的输入和极端情况下的正确性；这种思维方式通常是确保安全性所必需的。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;p&gt;例如，假设我们有一个学生信息系统，其安全目标是：“&lt;strong&gt;只有&lt;/strong&gt;助教可以访问成绩。” 测试随机抽取的助教是否可以访问成绩（正确性）很容易，但测试是否存在某种交互序列允许&lt;strong&gt;其他人&lt;/strong&gt;访问成绩（安全性）则要困难得多。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其次，实现永远无法防御所有可能的威胁。&lt;/strong&gt; 当我们指定威胁模型时，我们限定了实现必须防御的敌手集合。但现实世界中的敌手可能会以超出我们威胁模型的方式行事，从而破坏我们的安全目标。&lt;/p&gt;
&lt;p&gt;例如，除了助教之外，其他人可能通过以下方式访问成绩：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;发现服务器软件中的漏洞，&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;闯入助教的办公室，&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;入侵助教的笔记本电脑，&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;窃取管理员账户的密码，&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;诱骗助教泄露成绩，&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;破解服务器的加密，&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在注册处找到工作并让自己成为助教。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个列表永远不会结束。因为我们的威胁模型无法涵盖所有可能的威胁，&lt;strong&gt;安全永远不是完美的&lt;/strong&gt;。几乎总是会有&lt;strong&gt;某些&lt;/strong&gt;攻击者能够破坏您的系统。&lt;/p&gt;
&lt;p&gt;这就是为什么我们需要威胁模型：威胁模型定义了我们需要担心的攻击类型，以及我们决定不在范围内的攻击类型。&lt;/p&gt;
&lt;h2 id="22-设计安全目标和威胁模型"&gt;&lt;a href="#22-%e8%ae%be%e8%ae%a1%e5%ae%89%e5%85%a8%e7%9b%ae%e6%a0%87%e5%92%8c%e5%a8%81%e8%83%81%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;2.2 设计安全目标和威胁模型
&lt;/h2&gt;&lt;p&gt;指定安全目标和威胁模型的核心在于比较防御攻击的成本与攻击发生时的成本。几乎不可能精确计算这些成本，但这个框架在概念上是有用的。能够阻止重大漏洞的廉价防御措施可能值得实施，但防御可能泄露不重要信息的射频（RF）侧信道攻击则可能不值得。&lt;/p&gt;
&lt;p&gt;构建威胁模型总是需要迭代——您不会在第一次尝试时就做对。总会有一些您最初没有考虑到的攻击类型最终变得重要。&lt;/p&gt;
&lt;h2 id="23-设计如何实现"&gt;&lt;a href="#23-%e8%ae%be%e8%ae%a1%e5%a6%82%e4%bd%95%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;2.3 设计如何实现
&lt;/h2&gt;&lt;p&gt;在本课程中，我们将主要关注那些具有巨大回报的技术——开发软件和使用工具的方法，这些方法可以消除整个类别的攻击（或使它们变得更加困难）。&lt;/p&gt;
&lt;h1 id="3-例子"&gt;&lt;a href="#3-%e4%be%8b%e5%ad%90" class="header-anchor"&gt;&lt;/a&gt;3 例子
&lt;/h1&gt;&lt;p&gt;我们给出了一些由于安全目标或威胁模型选择不当而导致的安全失败的例子。&lt;/p&gt;
&lt;h2 id="31-错误的目标"&gt;&lt;a href="#31-%e9%94%99%e8%af%af%e7%9a%84%e7%9b%ae%e6%a0%87" class="header-anchor"&gt;&lt;/a&gt;3.1 错误的目标
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;商务舱机票&lt;/strong&gt;。一家航空公司试图通过允许商务舱机票持有者随时免费更改机票（即出发日期、出发地和目的地）来增加其商务舱机票的价值。一位顾客意识到他们可以在登机后更改机票。然后，该顾客可以以一张机票的价格乘坐无限次商务舱航班。&lt;/p&gt;
&lt;p&gt;在这种情况下，航空公司的目标并没有满足他们的实际需求——也许他们需要增加一个额外的目标，即“每次有人乘坐航班时，我们都会收到付款”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;莎拉·佩林的电子邮件&lt;/strong&gt;。莎拉·佩林有一个雅虎电子邮件账户，雅虎使用安全问题来重置密码——他们的目标可能是“除非知道用户安全问题的所有答案，否则任何人都无法重置用户的密码。”（安全问题通常是诸如“您母亲的娘家姓是什么？”之类的问题。）事实证明，可以在互联网上找到佩林账户恢复安全问题的所有答案。&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;雅虎的实现可能是完美的，但他们的目标并没有为某些用户提供任何有意义的安全性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;指令集架构（ISA）规范&lt;/strong&gt;。在为处理器定义ISA时，设计者认为时间并不重要，处理器可以花费可变数量的周期来执行特定指令。这对性能和兼容性有很大的好处，但正如我们将在学期后面讨论的那样，研究人员最近利用这种时间可变性对广泛的处理器进行了复杂的攻击。&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;处理器的实现符合规范，但规范本身允许这种攻击。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复杂的访问控制策略&lt;/strong&gt;。弗吉尼亚州费尔法克斯的一所学校使用了一个具有复杂访问控制结构的在线课程管理软件：每个教师负责一些班级，每个班级有许多学生，每个学生有许多文件。教师无法访问学生的文件，还有一个可以访问所有文件的校长。教师可以更改学生的密码，并可以将学生添加到他们的班级中。结果发现，教师可以将校长添加为学生，更改校长的密码，然后通过校长的账户访问所有文件。虽然每个访问控制策略单独听起来都合理，但它们共同导致了糟糕的结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mat Honan的Gmail账户&lt;/strong&gt;。一位名为Mat Honan的《连线》杂志记者的Gmail账户通过一次巧妙的攻击被攻破。&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;Honan有一个Gmail账户。Gmail的重置密码功能避免了使用安全问题，而是使用了一个备份电子邮件账户。攻击者触发了重置密码功能，该功能向Honan的Apple电子邮件账户发送了一个重置链接。&lt;/p&gt;
&lt;p&gt;攻击者随后试图访问Honan的Apple电子邮件账户。攻击者触发了Apple账户的重置密码功能。Apple的重置密码功能需要Honan的地址和信用卡号码的最后四位数字。攻击者能够公开找到Honan的地址，但无法轻易找到他的信用卡号码。&lt;/p&gt;
&lt;p&gt;攻击者通过Honan的Amazon账户找到了信用卡信息。Amazon知道他的信用卡号码，要求提供完整的信用卡号码才能重置账户。然而，Amazon允许在不登录的情况下为某个账户购买东西，只要提供一个新的信用卡号码。它还允许将这个新的信用卡号码保存到用户的Amazon账户中。因此，攻击者使用自己的信用卡在Amazon上进行了购买。然后，攻击者将自己的信用卡号码保存到Honan的Amazon账户中。接下来，攻击者触发了Amazon的重置密码功能，并使用保存到账户中的信用卡号码重置了Honan的Amazon密码并访问了他的Amazon账户。攻击者随后能够在Honan的Amazon账户中看到他真实信用卡的最后四位数字，使用这些数字重置了他的Apple邮件账户，然后使用该账户重置了Honan的Gmail账户。&lt;/p&gt;
&lt;p&gt;像这样的复杂系统链可能非常难以推理，但这些交互最终对安全至关重要。&lt;/p&gt;
&lt;h2 id="32-错误的威胁模型"&gt;&lt;a href="#32-%e9%94%99%e8%af%af%e7%9a%84%e5%a8%81%e8%83%81%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;3.2 错误的威胁模型
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;假设特定策略：CAPTCHA&lt;/strong&gt;。CAPTCHA被设计为通过自动化解决成本高昂，但人类易于阅读。确实，为CAPTCHA构建一个通用的光学字符识别系统可能成本高昂，但想要绕过CAPTCHA的攻击者并不这样做。相反，他们在劳动力成本低廉的国家建立了计算机中心。攻击者然后支付在这些中心工作的人员来解决CAPTCHA。&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;结果是，解决一个CAPTCHA的成本只有几分之一美分。解决CAPTCHA的成本仍然不为零，但成本远低于系统设计者可能预期的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;计算能力：DES&lt;/strong&gt;。曾经有一个名为DES的加密标准，它有$2^{56}$个可能的密钥。在设计时，美国政府标准机构断言它甚至可以抵御强大的攻击者，但今天，现代计算机可以以适中的成本尝试所有$2^{56}$个密钥。（甚至在DES设计时，学术研究人员就明白56位密钥不足以防止穷举密码分析。&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;）&lt;/p&gt;
&lt;blockquote class="alert alert-info"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;例如，&lt;a class="link" href="https://crack.sh/" target="_blank" rel="noopener"
 &gt;https://crack.sh/&lt;/a&gt; 使用一组FPGA（现场可编程门阵列）来提供一种服务，该服务会穷举检查所有可能的密钥。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;p&gt;由于DES在现代计算机面前的弱点，所有使用该标准的人都必须升级他们的分组密码。例如，麻省理工学院不得不从使用DES进行身份验证转向使用具有更长密钥的更新分组密码，如AES。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;依赖关系：通过短信的双因素认证（2FA）&lt;/strong&gt;。许多2FA系统使用短信进行身份验证，但攻击者只需要说服AT&amp;amp;T商店的店员为您的电话号码提供一个新的SIM卡即可。&lt;/p&gt;
&lt;blockquote class="alert alert-info"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;这些攻击通常被称为“SIM交换”或“SIM劫持”。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;软件版本：Xcode&lt;/strong&gt;。iPhone应用程序通常在开发者的机器上创建和编译，发送到Apple的App Store，然后从那里发送到iPhone。iPhone应用程序是使用一个名为Xcode的工具创建的，该工具通常从Apple服务器下载。然而，Xcode是一个大型软件，对于中国防火墙后面的开发者来说，下载速度非常慢。中国境内的某人建立了一个更快的Xcode镜像，许多中国开发者使用了这个镜像中的Xcode版本。然而，这个镜像并没有提供Apple的Xcode版本——相反，它提供了一个稍微修改过的Xcode版本，该版本会在每个使用它编译的应用程序中注入一些恶意代码。这花了很长时间才被发现。&lt;/p&gt;
&lt;blockquote class="alert alert-info"&gt;
 &lt;div class="alert-header"&gt;
 &lt;span class="alert-icon"&gt;&lt;/span&gt;
 &lt;span class="alert-title"&gt;Info&lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="alert-body"&gt;
 &lt;p&gt;维基百科上关于XcodeGhost的文章，https://en.wikipedia.org/wiki/XcodeGhost 提供了有关此攻击的更多详细信息。&lt;/p&gt;
 &lt;/div&gt;
 &lt;/blockquote&gt;
&lt;h2 id="33-有问题的实现"&gt;&lt;a href="#33-%e6%9c%89%e9%97%ae%e9%a2%98%e7%9a%84%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;3.3 有问题的实现
&lt;/h2&gt;&lt;p&gt;错误、配置错误和其他错误是安全问题的常见原因。一个经验法则是，每1000行代码大约会有1个错误。这是一个非常粗略的估计，但基本思想是代码越多，错误就越多。减少安全漏洞的有效策略是减少系统中的代码量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缺少检查：iCloud&lt;/strong&gt;。Apple的iCloud执行许多功能——电子邮件、日历、存储和“查找我的iPhone”。每个功能都有自己的登录方式，但在所有功能中，一个共同的目标是限制攻击者猜测用户密码的能力。为此，他们在所有登录界面中添加了速率限制，允许每小时只有10次登录尝试——但他们忘记了“查找我的iPhone”的登录界面。&lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;由于这些认证代码在多个地方重复，有许多地方需要记住添加速率限制，但攻击者只需要一个薄弱的登录界面就可以暴力破解密码。一般来说，避免这种重复将使构建安全系统变得更加容易。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不安全的默认设置&lt;/strong&gt;。当您设置新服务时，它们几乎总是带有一些默认设置以简化设置。Wi-Fi路由器带有默认密码，AWS S3存储桶带有默认权限，等等。这些默认设置可能很方便，但它们对安全非常重要，因为许多人会忘记或忽略更改默认设置。因此，默认设置成为系统的操作方式。为了构建一个安全的系统，重要的是默认设置是安全的。&lt;/p&gt;
&lt;h1 id="4-安全系统设计的一般原则是什么"&gt;&lt;a href="#4-%e5%ae%89%e5%85%a8%e7%b3%bb%e7%bb%9f%e8%ae%be%e8%ae%a1%e7%9a%84%e4%b8%80%e8%88%ac%e5%8e%9f%e5%88%99%e6%98%af%e4%bb%80%e4%b9%88" class="header-anchor"&gt;&lt;/a&gt;4. 安全系统设计的一般原则是什么？
&lt;/h1&gt;&lt;h2 id="41-目标和威胁模型"&gt;&lt;a href="#41-%e7%9b%ae%e6%a0%87%e5%92%8c%e5%a8%81%e8%83%81%e6%a8%a1%e5%9e%8b" class="header-anchor"&gt;&lt;/a&gt;4.1 目标和威胁模型
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;创建简单、通用的目标。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过更好的设计避免假设（例如“没有人能够获得用户的SIM卡”）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;学习并迭代。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;实践深度防御：不要依赖单一的防御措施来保护所有安全——使用备用防御措施来防范不可避免的错误是很有用的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="42-实现"&gt;&lt;a href="#42-%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;4.2 实现
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;更简单的系统会带来更少的问题。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将安全关键部分分解为一个小的独立系统或代码片段（例如，硬件安全密钥）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重用设计良好的代码，例如经过良好测试的加密库。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;理解并测试极端情况。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="参考文献"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e6%96%87%e7%8c%ae" class="header-anchor"&gt;&lt;/a&gt;参考文献
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Diffie, Whitfield and Martin E. Hellman. “Exhaustive Cryptanalysis of the NBS Data Encryption Standard”. In: Computer 6.10 (1977), pp. 74–84.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hill, Mark D. et al. “On the Spectre and Meltdown Processor Security Vulnerabilities”. In: IEEE Micro 39.2 (2019), pp. 9–19.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Honan, Mat. How Apple and Amazon Security Flaws Led to My Epic Hacking. &lt;a class="link" href="https://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/" target="_blank" rel="noopener"
 &gt;https://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/&lt;/a&gt;. Aug. 2012.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Motoyama, Marti et al. “Re: CAPTCHAs—Understanding CAPTCHASolving Services in an Economic Context”. In: Proceedings of the 19th USENIX Security Symposium. Washington, DC, Aug. 2010.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trew, J. ‘Find My iPhone’ exploit may be to blame for celebrity photo hacks (update). &lt;a class="link" href="https://www.engadget.com/2014-09-01-find-my-iphone-exploit.html" target="_blank" rel="noopener"
 &gt;https://www.engadget.com/2014-09-01-find-my-iphone-exploit.html&lt;/a&gt;. Sept. 2014.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Zetter, Kim. Palin e-mail hacker says it was easy. &lt;a class="link" href="https://www.wired.com/2008/09/palin-e-mail-ha/" target="_blank" rel="noopener"
 &gt;https://www.wired.com/2008/09/palin-e-mail-ha/&lt;/a&gt;. Sept. 2008.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Kim Zetter. Palin e-mail hacker says it was easy. &lt;a class="link" href="https://www.wired.com/2008/09/palin-e-mail-ha/" target="_blank" rel="noopener"
 &gt;https://www.wired.com/2008/09/palin-e-mail-ha/&lt;/a&gt;. Sept. 2008.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Mark D. Hill et al. “On the Spectre and Meltdown Processor Security Vulnerabilities”. In: IEEE Micro 39.2 (2019), pp. 9–19.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Mat Honan. How Apple and Amazon Security Flaws Led to My Epic Hacking. &lt;a class="link" href="https://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/" target="_blank" rel="noopener"
 &gt;https://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/&lt;/a&gt; . Aug. 2012.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Marti Motoyama et al. “Re:CAPTCHAs—Understanding CAPTCHA-Solving Services in an Economic Context”. In: Proceedings of the 19th USENIX Security Symposium. Washington, DC, Aug. 2010.&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Whitfield Diffie and Martin E. Hellman. “Exhaustive Cryptanalysis of the NBS Data Encryption Standard”. In: Computer 6.10 (1977), pp. 74–84.&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;J. Trew. ‘Find My iPhone’ exploit may be to blame for celebrity photo hacks (update). &lt;a class="link" href="https://www.engadget.com/2014-09-01-find-my-iphone-exploit.html" target="_blank" rel="noopener"
 &gt;https://www.engadget.com/2014-09-01-find-my-iphone-exploit.html&lt;/a&gt; . Sept. 2014.&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item></channel></rss>