# Office 文件密码重试工具

通过密码字典逐个尝试密码，解密带「打开密码」的 Office 文件（Excel / Word / PPT）。


## 功能

- **待解密文件**：支持 `.xlsx/.xlsm/.xls/.docx/.doc/.pptx/.ppt`（默认从 `ec_files` 目录选择）
- **保存位置 / 文件名**：默认保存到 `ec_files`，文件名默认 `ec_运行年月日时分秒_原文件名`
- **密码字典**：从 `dict` 目录选择 `.txt` 字典文件（支持 utf-8 / gbk / utf-16，流式读取）
- **字典生成（渐进式轮次）**：不再手动勾选大小写/数字/符号，字符集固定在程序内部；
  按社会工程学概率分轮推进，第 1 轮约 1 万条、之后每轮 ×10（1 万 → 10 万 → 100 万…），
  也可临时改成本轮的任意条数；「最多生成」默认 8 轮（可调 1~50，随「记住这些信息」
  一起保存），超过上限时生成会被阻止并提示调高，防止一路点「下一轮」写出过多大字典。
  候选顺序固定为：
  ⓪ 已知线索（关键词排列组合 / 已知位数纯数字穷举，确定知道的候选最先尝试）
  ① 个性化信息（姓名/拼音、生日、手机尾号的大小写与 `+123`/`+年份`/拼接变体）
  ② 内置词表（常见弱口令 / 键盘序 / 情感拼音 / 年份）
  ③ 日期（`YYYYMMDD` 优先，1990–2009 生日最前，其次 6/4/2 位）
  ④ 手机号段 + 4 位尾号（重复号 / 连号 / 谐音尾号优先）
  ⑤ 字母与数字组合（数字在前 `123456a`、字母在前 `a123456`、首字母大写 `Admin123`）
  ⑥ leet 变形（`p@ssword`、`p4ssword`、`p@ssw0rd`）
  ⑦ 顺序数字（1、2、3…，放在概率段之后）
  ⑧ 全字符集兜底（保证 1..位数上限每层都有候选）

  弹窗用表格展示每个阶段「已试 / 本轮新增 / 阶段总量」，并预估体积、磁盘余量与
  单/多进程耗时；候选密码最大长度默认 12（收在「高级设置」里，超过该长度的候选
  不生成）。生成前做**磁盘空间分级检查**：本轮预估体积（含 20% 余量）将占目标磁盘
  剩余空间 90% 以上时弹窗警告（可继续），剩余空间装不下时直接阻止；
  估算行实时显示「磁盘剩余 X · 预计占剩余 Y%」。生成是**流式**的
  （内存与字典规模无关，实测 500 万条约 39MB、24 秒），后台线程执行、可随时取消，
  取消不留半成品文件。
- **已知线索（自定义生成，优先尝试）**：在生成弹窗的「已知线索」区块填写
  确定知道的密码线索，候选会写进字典最前面、最先被尝试：
  - **关键词**（多个，逗号/空格分隔）：做 1~3 个词的排列拼接 × 每词大小写变体
    （如 `zhang, 520` → `zhang`、`ZHANG`、`zhang520`、`520zhang`…）；
  - **密码位数 + 纯数字**：按数值序穷举该位数的全部数字（含前导零，如 8 位
    即 `00000000`→`99999999`）；位数仅在勾选「纯数字」或有关键词时生效
    （位数 + 全字符集的组合空间跑不完，界面会提示线索不完整）；
  - 三项可任意组合（如「关键词 + 位数」只保留长度恰好等于该位数的组合）；
  - 修改线索只重置「已知线索」阶段的已试进度，其余阶段进度保留；
    线索原文不写入任何本地文件（元数据只存哈希）。
- **字典迭代（多轮推进）**：每份生成的字典旁挂 `xxx.txt.meta.json`，记录本轮覆盖了
  各阶段的哪一段。跑完未命中时，结果弹窗可直接生成第 N 轮——新一轮从已试进度之后
  继续，**只包含没试过的候选**；个性化信息改了只重排「个性化」阶段，其余进度保留。
  生成完成会登记「已生成、未跑过」，重复打开生成弹窗时提示直接使用那份文件，
  避免写出两份内容相同的字典。生成完成后自动回填主界面字典框，并询问是否立即开始解密。
- **外部字典也能进账本**：字典选择弹窗提供「登记已跑完…」，把在别处跑完的外部字典
  登记为「对该文件完整尝试过」；生成新一轮时按**行内容精确排除**其中确定试过的候选
  （8 字节哈希排序数组 + 二分查找，无假阳性，绝不漏试；超过 500 万行自动放弃并提示）。
- **尝试记录与提醒**：`state/coverage.json` 按文件内容（大小 + 首尾各 1MB 的哈希）
  记录「哪个字典试过哪个文件、跑到第几条、是否跑完」，文件改名/移动后仍认得。
  主界面在字典行下方显示「本文件已试 N 轮 / M 条 · 下一轮建议 K 条」，字典选择列表
  标注「第 2 轮 · 已跑完未命中」；选择已完整跑过的字典会先提示（用户仍可坚持再跑）。
- **个性化信息可选记住**：勾选「记住这些信息（仅保存在本机 state/）」才写入
  `state/profile.json`，默认不落盘、不联网。
- **解密进度**：进度条 + 实时尝试数 / 耗时 / 速率
- **停止**：可中途停止（不再只能硬退出），停止后自动保留进度
- **断点续跑**：同一「文件 + 字典」再次开始时，询问是否从上次进度继续
  （用文件大小 + 修改时间校验，文件被替换则不会误用旧进度）
- **运行历史**：每次运行都会记录到 `state/history.jsonl`（结果、尝试数、命中密码、耗时），
  界面「运行历史」按钮可查看
- **多进程加速**：可勾选启用；旁边的「详细说明」tip 面向新手，讲清了设置方法、
  推荐进程数、「跑久了变慢怎么办」的操作建议与注意事项（底层原理见 `docs/经验总结.md`）
- **退出**：结束所有线程与子进程并直接退出

## 扩展工具：DGT 字典生成（另行付费/购买）
一个**独立的**字典生成工具
问答式字典生成扩展工具：回答「密码大概类型 / 几位 / 里面可能有哪些词」，
它就围绕这些答案生成一份一开始就对准方向的定向字典，交给主程序去试——
通常比内置的通用生成小得多、准得多，命中更快。
- **独立扩展，另行付费/购买**，不随主程序赠送（获取方式请联系开发者）；
- 程序内的 DGT 说明弹窗只提供**获取指引**（联系客服），不提供「打开本地文档」
  这类入口：文档不随程序交付，点了没反应比没有更糟；
- 主程序**不装 DGT 功能完全不变**；DGT 字典格式与内置生成逐字段兼容，
  放进 `dict/` 目录即可直接用，「跳过已试 / 断点续跑 / 覆盖统计」照常工作；
- 在主程序的「字典管理」「字典迭代生成」弹窗里可看到 DGT 介绍，
  

## 性能说明

口令爆破的瓶颈是**密钥派生（KDF）**，而不是文件解析：

- 标准加密（standard）：每个口令 1 次 KDF，约 30ms（实测约 33 次/秒）
- agile 加密：官方 `load_key(verify_password=True)` 会跑 **2 遍**迭代哈希，
  本工具的快路径只跑 1 遍，**实测提速约 1.97 倍**（148ms → 75ms/次）
- `hashlib` 在输入小于 2047 字节时不释放 GIL ⇒ **线程无法并行**，
  加速只能靠多进程；请按机器核数设置「进程数」

## 注意
- **不要手动修改程序生成的字典文件**（带旁挂 `xxx.txt.meta.json` 的那份）：
  元数据记录了「每个阶段覆盖到字典的第几行」，手动插入 / 删除 / 改写任何一行都会
  让行号与阶段区间错位——下一轮生成会从错误的位置继续，**跳过还没试过的候选**
  （表现为「漏试」）；修改时间变化还会让断点与覆盖提示失效。
  程序在记录尝试结果时会校验「元数据行数 vs 实际行数」，发现被改过会降级为
  外部字典处理（进度从头算，宁可重试不漏试），但**同秒内的等长改写检测不到**，
  所以请一律不要手改。想补几个确定的密码，请用生成弹窗的「已知线索」关键词——
  它们会排在字典最前面优先尝试，且不污染进度账本。
- **外部字典（没有 `.meta.json` 的）可以手动修改**：改完后按新文件处理，
  断点会失效、从头重跑（只多花时间，不会漏试）；生成新一轮时按行内容精确排除
  的也是改后文件的实时内容。
- 生成 ≠ 跑过：只有真正运行过的字典才推进覆盖前缀；「已生成、未跑过」只用于防重复生成。
- 交互式中途停止时，账本只按「已读行数」推进前缀，可能重试少量候选；这是刻意的
  保守取舍（与多进程续跑的「安全前缀」同一原则）。
- 旧二进制格式（`.xls/.doc/.ppt`）的 `load_key` 不支持 `verify_password`，
  本工具按格式分派调用；实测这些格式的密码校验与解密由 msoffcrypto 内部完成。
- 命中密码会明文记录在 `state/history.jsonl`（本机文件），请自行保管。