- CLI
- 网络安全
【免费下载链接】Ciphey
⚡ Automatically decrypt encryptions without knowing the key or cipher, decode encodings, and crack hashes ⚡
本文以 Ciphey 仓库中的实现计划文档 docs/wait_athena.md 为主体,结合 src/checkers/wait_athena.rs、src/storage/wait_athena_storage.rs、src/timer/mod.rs 等源码实现,完整讲解 WaitAthena Checker 的设计动机、架构分工、核心数据结构与完整落地路径。读完本文,你将理解 Ciphey 默认 Athena Checker 与 WaitAthena Checker 的行为差异,掌握--top-results参数背后的全局存储、计时器联动与 A* 搜索集成机制,并能在自己的编码破解场景中准确判断何时使用这一"多结果收集"模式。
WaitAthena 是什么:从"找到即停"到"收集到超时"
Ciphey 的默认检查器是 Athena Checker(见 src/checkers/athena.rs)。它按顺序运行 LemmeKnow、密码、英语等子检查器,一旦某个检查器判定当前文本是明文,就立即返回并结束搜索。这种"找到第一个合法明文就退出"的策略对绝大多数密文是高效的,但对歧义性编码(ambiguous encodings)不够友好——同一段密文可能存在多种合理解读,例如多层编码、大小写不敏感文本、可被多种解码路径命中的字符串等,用户往往希望看到全部可能性。
WaitAthena Checker 正是为这一场景设计的变体。它在 docs/wait_athena.md 中被定义为athena.rs的"精确克隆",仅有三处关键差异:
- 结果收集而非立即返回:把每次找到的明文存入一个全局列表,而不是立刻结束程序;
- 计时器到期统一展示:程序计时器(
timeout)归零时,一次性展示已收集到的全部明文; - 计时器模块联动:需要修改 timer 模块,使其在倒计时结束时调用打印明文列表的函数。
对应到实际代码,src/checkers/wait_athena.rs 的文件头注释准确描述了这一定位:
WaitAthena checker is a variant of Athena that collects all plaintexts found during the search. While Athena exits immediately when a plaintext is found, WaitAthena continues checking and stores all plaintexts it finds until the timer expires.
变更记录 docs/changes/2024-07-10-wait-athena-checker.md 进一步总结了该特性的权衡:
- 优点:一次性提供多个潜在明文,便于歧义密文的全方位分析;与所有既有解码器/检查器保持兼容;通过单一 CLI 参数
--top-results启用;自动禁用人类检查器,避免打断搜索;持续搜索直到计时器到期,最大化候选明文数量。 - 缺点:即使已经找到合法明文也会继续搜索,耗时会变长;可能同时返回误报与真实明文;所有结果需在计时器到期前常驻内存,内存占用上升。
八个关键设计澄清
原文档记录了与项目维护者的讨论结论,这些澄清约束了整套实现,且均已在实际代码中落地:
| # | 决策点 | 结论 |
|---|---|---|
| 1 | 搜索器(Searcher)集成 | 无需修改src/searchers/mod.rs 的搜索逻辑,仅需新增 CLI 参数--top-results来决定使用标准 Athena 还是 WaitAthena。从当前源码看,后续进一步将收集逻辑下沉到了 src/searchers/astar.rs(见后文"与 A* 搜索的深度集成") |
| 2 | 人类检查器交互 | WaitAthena 流程不涉及人类检查器,自动接受所有潜在明文,不逐条询问用户 |
| 3 | 去重逻辑 | 不实现去重,实际中重复明文极不可能出现 |
| 4 | 依赖要求 | lazy_static已是项目既有依赖,无需新增任何依赖 |
| 5 | 性能考量 | 无需对 WaitAthena 做特殊限流或优先级处理 |
| 6 | 与既有解码器兼容 | 所有既有解码器只要实现checker_typetrait、遵循标准检查器模式即可正常工作 |
| 7 | 错误处理 | 文档原计划对 mutex 中毒(poisoning)等存储错误直接panic;实际实现改为恢复(poisoned.into_inner())并记录警告日志,见 src/storage/wait_athena_storage.rs |
| 8 | 结果排序 | 初始实现按发现顺序展示、不排序;排序作为未来改进项 |
核心数据结构:线程安全的全局明文存储
WaitAthena 的跨线程工作方式决定了需要一块"检查器可写入、计时器可读取"的共享存储。文档给出的方案是lazy_static+Mutex,实际实现位于 src/storage/wait_athena_storage.rs,并在文档设计的基础上增加了decoder_name字段,使每个结果都能追溯到产生它的解码器与检查器:
#[derive(Debug, Clone)] pub struct PlaintextResult { /// The plaintext text pub text: String, /// The description of the result pub description: String, /// The name of the checker used to generate the result pub checker_name: String, /// The name of the decoder used to generate the result pub decoder_name: String, } lazy_static! { static ref PLAINTEXT_RESULTS: Mutex<Vec<PlaintextResult>> = Mutex::new(Vec::new()); }围绕这一静态容器,模块暴露了三个核心函数:
add_plaintext_result(text, description, checker_name, decoder_name):构造PlaintextResult并压入全局 Vec;写入前通过trace!记录来源检查器、文本与解码器,写入后记录当前结果总数,便于排查问题;get_plaintext_results() -> Vec<PlaintextResult>:克隆并返回全部结果,供计时器到期后的展示逻辑使用;clear_plaintext_results():清空结果,供每次新的破解会话开始时调用,避免上次运行的结果污染本次输出。
值得一提的错误处理差异:文档设计稿中对锁失败直接.unwrap()触发 panic,实际代码则对Mutex::lock()的结果做了match处理,遇到 poisoned 状态时调用poisoned.into_inner()恢复访问并输出warn!("Mutex was poisoned, recovering")。从源码结构看,这是为 long-running 的搜索循环提供更强的健壮性——单一线程 panic 后,其余线程仍能继续写入结果。
模块注册位于 src/storage/mod.rs 中的pub mod wait_athena_storage;。
WaitAthena Checker 的实现:与 Athena 的对照
src/checkers/wait_athena.rs 实现了Checker<WaitAthena>的Checktrait。先看它的元信息:
pub struct WaitAthena; impl Check for Checker<WaitAthena> { fn new() -> Self { Checker { name: "WaitAthena Checker", description: "Runs all available checkers and stores results until timer expires", link: "", tags: vec!["wait_athena", "all"], expected_runtime: 1.0, popularity: 1.0, lemmeknow_config: Identifier::default(), sensitivity: Sensitivity::Medium, // Default to Medium sensitivity enhanced_detector: None, _phantom: std::marker::PhantomData, } } // ... }与 Athena 的对照(src/checkers/athena.rs)可看出:expected_runtime从 Athena 的0.01调整为1.0,语义上承认"该检查器要一直运行到计时器到期";两者默认敏感度都是Sensitivity::Medium,都实现了with_sensitivity/get_sensitivity。
在check()方法内,执行顺序与原文档一致,且新增了 Wordlist 检查器的分支(对应 docs/changes/2024-07-01-wordlist-checker.md 引入的能力):
- Regex 模式:若配置了
config.regex,只运行RegexChecker(这与 Athena 一致——用户用 regex 说明在找特定信息,其余检查器全部关闭)。识别命中后,不经过人类检查器,直接把text、description、checker_name、"RegexChecker"存入全局存储; - Wordlist 模式:若配置了
config.wordlist,先运行WordlistChecker,命中后存储结果; - LemmeKnow:检测已知数据格式(IP、邮箱、哈希等),命中后存储;
- PasswordChecker:检测常见口令,命中后存储;
- EnglishChecker:检测是否英文文本,命中后存储。
每个子分支的关键差异都在注释中标注:// Store the result instead of returning immediately以及// No human checker involvement。也就是说,WaitAthena 对每个候选明文都自动接受(check_res.is_identified = true)并写入存储,随后return check_res让上层流程继续推进——这保证了 A* 搜索能在top_results模式下继续扩展节点,而不是像 Athena 那样因为人类检查器确认后立刻终止。
模块注册位于 src/checkers/mod.rs:pub mod wait_athena;,同时CheckerTypes枚举新增了CheckWaitAthena(Checker<WaitAthena>)变体,并在check、with_sensitivity、get_sensitivity三个方法中补齐了对应分支;全局检查器注册表CHECKER_MAP也加入了("WaitAthena Checker", CheckerBox::new(Checker::<WaitAthena>::new())),这意味着 WaitAthena 可以作为普通检查器被搜索算法按名称调度。
计时器改造:到期后展示全部结果
src/timer/mod.rs 承担了"倒计时到期 → 展示结果"的职责。start(duration)启动一个后台线程,每秒推进time_spent并调用countdown_until_program_ends(来自 src/cli_pretty_printing/mod.rs,每 5 秒打印一次剩余时间)。倒计时归零后:
let config = get_config(); log::trace!("Timer expired. top_results mode: {}", config.top_results); if config.top_results { log::info!("Displaying all collected plaintext results"); filter_and_display_results(); } else { log::info!("Not in top_results mode, skipping display_wait_athena_results()"); }filter_and_display_results从wait_athena_storage::get_plaintext_results()取回全部结果,委托给 CLI 美化模块的display_top_results(&results)。与文档设计稿相比,实际实现有两处健壮性调整:
- 文档中
sender.send(()).expect(...),实际改为match记录warn!日志——注释说明这在 benchmark 场景下是预期行为; - 结果展示从 timer 模块内联打印,收敛到 src/cli_pretty_printing/mod.rs 的
display_top_results,保持"所有 CLI 输出统一经由 pretty-printing 模块"的架构约定。
结果展示的实战细节
display_top_results(src/cli_pretty_printing/mod.rs)定义了完整的用户交互流程:
- 结果为空时输出
No potential plaintexts found.; - 非空时以
🎊 List of Possible Plaintexts 🎊开头,并输出结果总数; - 超过 10 个结果时,程序会以警告提示"结果太多建议写入文件",并询问
Would you like to write to a file? (y/N)。若用户选择写入,每个结果按Result #i、Decoder、Checker、Description四行组织,默认文件名是$HOME/ciphey_text.txt; - 若未选择写入(或结果 ≤10),则在终端逐条打印
Result #i、Decoder、Checker、Description,结果之间以---分隔,最后输出=== End of Top Results ===。
另外,普通模式下的成功输出函数program_exiting_successful_decoding在top_results开启时会提前返回(if config.top_results { return; }),避免与计时器到期的汇总展示产生双重输出。
配置项与 CLI:如何开启 WaitAthena 模式
Config 结构体新增top_results字段
src/config/mod.rs 的Config结构体新增字段:
/// Whether to collect all plaintexts until timeout expires /// instead of exiting after finding the first valid plaintext pub top_results: bool,默认值为false,即默认行为与过去完全一致(找到第一个明文即退出)。top_results也是 TOML 配置白名单中的合法键之一(parse_toml_with_unknown_keys的known_keys数组包含"top_results"),因此用户既可以通过命令行参数启用,也可以在~/.ciphey/config.toml中持久化配置。
CLI 参数
src/cli/mod.rs 使用 clap 声明参数:
/// Show all potential plaintexts found instead of exiting after the first one /// Automatically disables the human checker #[arg(long)] top_results: bool,在cli_args_into_config_struct中:
// Set top_results mode if the flag is present config.top_results = opts.top_results; // If top_results is enabled, automatically disable the human checker if config.top_results { config.human_checker_on = false; }注意"自动禁用人类检查器"这一副作用:既然要一口气收集全部候选明文,自然不能再逐条弹出y/N询问,这与设计澄清 #2 完全一致。实际命令形如:
ciphey -t "SGVsbG8gV29ybGQh" --top-results ciphey -t "密文" --top-results --cracking-timeout 10--cracking-timeout(默认 5 秒)决定了 WaitAthena 的收集窗口:时间越长,搜索树展开越充分、候选明文越多,但内存与耗时也随之上升。首次运行向导 src/cli/first_run.rs 也会询问用户偏好("找到第一个就停"还是"收集全部可能明文"),并将选择写入top_results配置键;若用户选择了收集模式,向导还会提示该模式下建议将 timeout 设置为 3 秒左右,避免过高的倒计时导致机器卡顿。
库接口集成:perform_cracking的分流逻辑
src/lib.rs 的perform_cracking是库级入口。它在top_results模式下做了三件事:
- 强制关闭人类检查器并清空上次遗留的结果:
let mut modified_config = config; if modified_config.top_results { modified_config.human_checker_on = false; // Clear any previous results when starting a new cracking session storage::wait_athena_storage::clear_plaintext_results(); } config::set_global_config(modified_config);- 输入文本的初始明文预检改用 WaitAthena。
check_if_input_text_is_plaintext按配置分流:
if config.top_results { let wait_athena_checker = Checker::<WaitAthena>::new(); wait_athena_checker.check(text) } else { let athena_checker = Checker::<Athena>::new(); athena_checker.check(text) }这对应设计步骤 #8:程序启动时先判断输入是否本身就是明文,以节省 CPU 周期;在收集模式下,这一预检同样会把命中结果写入全局存储。
- 继续执行 A搜索*,由搜索器负责在收集模式下持续探索(见下节)。
与 A* 搜索的深度集成(源码现状)
设计文档在"回顾性实现洞察"(Retrospective Implementation Insights)一节中明确指出:如果重新实现该特性,应让 A搜索在top_results模式下即使找到合法明文也继续搜索*,而不是依赖检查器侧存储结果——这样可以消除单独的全局存储机制,让特性与核心搜索算法融为一体。从当前仓库源码看,这一方向已经落地:
- src/searchers/astar.rs 中,当某节点被判定为成功结果时,若
get_config().top_results为真,会把node.state.text的第一个明文、解码路径中最后一个解码器名称、检查器名称一起写入wait_athena_storage::add_plaintext_result(...),描述格式为Decoded successfully at depth {当前深度}; - 随后只有在非
top_results模式时才stop.store(true)并退出循环;在top_results模式下,搜索继续展开,直到计时器到期触发展示。
这意味着实际的 WaitAthena 收集路径有两条:初始明文预检(check_if_input_text_is_plaintext)与 A* 搜索中的成功节点。两条路径共用同一存储,最终由计时器统一汇总展示。
测试策略与设计权衡
原文档的测试计划分三层:
- WaitAthena 检查器单元测试:已实现于 src/checkers/wait_athena.rs 的
#[cfg(test)]模块,共 4 个用例:test_check_english_sentence:英文句子"test valid english sentence"应被识别;test_check_dictionary_word:单词"exuberant"应被识别(源码中将文档示例的"and"换成了更具区分度的词);test_default_sensitivity_is_medium:默认敏感度为Sensitivity::Medium;test_with_sensitivity_changes_sensitivity:with_sensitivity能正确切换到Low/High。
- 集成测试:验证 WaitAthena 能收集多个明文。可从 tests/integration_test.rs 与 src/lib.rs 的
perform_cracking测试了解端到端调用的基准行为。 - 手工测试:用不同密文验证所有明文均被收集。
实现中值得注意的工程取舍:
- 线程安全:
Mutex<Vec<PlaintextResult>>是全局唯一存储,检查器线程与计时器线程都通过它交换数据;poisoned 恢复策略取代了文档初版的 panic 方案,提升长时搜索的健壮性; - 错误处理:除存储锁恢复外,timer 的
send失败也只记录日志不再 panic,注释明确说明"这在 benchmark 中是预期行为"(相关基准见 benches/benchmark_whole_program.rs); - 用户体验:超过 10 条结果时主动引导写入文件,防止终端刷屏;每条结果附带 Decoder / Checker / Description,便于用户判断各候选明文的可信来源;
- 无去重:按设计澄清 #3 不做去重,接受极低概率的重复可能。
潜在挑战
- 线程安全:存储机制必须保证多线程并发写入/读取安全——由
Mutex保证,所有访问点集中在 src/storage/wait_athena_storage.rs; - 错误处理:设计初版对 mutex 中毒与意外错误直接 panic,实际代码已改为记录日志并恢复,兼顾可诊断性与可用性;
- 用户体验:输出必须清晰、有助益——包括结果总数、编号、来源解码器/检查器、描述,以及超量时的落盘引导。
未来改进方向
原文档给出了明确的演进路线,其中部分已在源码中实现:
- 与 A搜索更深集成*:让搜索算法在
top_results模式下持续搜索——已在 src/searchers/astar.rs 落地; - 结果打分与排序:按置信度对结果排序,可结合明文熵、检查器置信分数、到达明文的解码器数量、是否含字典词/合法语法等指标(从 src/searchers/astar.rs 的启发式函数
generate_heuristic/calculate_string_worth看,此类信号在项目内已存在); - 去重策略:若实践中重复明文成为问题,可按规范化版本(忽略大小写、归一化空白)去重;
- 可配置结果上限:防止超大结果集造成内存问题;
- 搜索过程进度反馈:计时器到期前周期性提示已收集候选数;
- 结果分类:按识别它们的检查器类型(英文文本 / 口令 / 特定格式)分组展示;
- 并行检查器执行:既然不再"命中即退",可并行运行多个检查器加速;
- 内存优化:尽量存储引用、按需拷贝;
- 置信度阈值:可配置过滤低置信结果,减少输出噪声;
- 导出功能:把全部候选明文导出到文件,便于对歧义/复杂编码做后续分析(结果超过 10 条时的落盘引导已部分覆盖此能力)。
结语
WaitAthena Checker 是 Ciphey 在"效率优先"与"完整性优先"之间提供的一个可切换选项:默认 Athena 找到第一个合法明文即退出,--top-results模式则把搜索窗口拉满到计时器到期,借助Mutex保护的全局存储汇总全部候选明文,并在倒计时归零时由 timer 模块统一展示。从 docs/wait_athena.md 的实现计划到 src/checkers/wait_athena.rs、src/storage/wait_athena_storage.rs、src/timer/mod.rs、src/searchers/astar.rs 的落地代码,可以看到设计文档中的"回顾性洞察"(让搜索算法而非检查器承担收集职责)已经转化为实际架构。对使用者而言,这条特性的价值在于:面对歧义密文、多层编码或不确定的破解路径时,ciphey -t <密文> --top-results能一次给出全部可能性,再结合 Decoder / Checker / Description 逐条甄别,让"自动破解"变成"可解释的多解分析"。
- CLI
- 网络安全
【免费下载链接】Ciphey
⚡ Automatically decrypt encryptions without knowing the key or cipher, decode encodings, and crack hashes ⚡
相关推荐
Ciphey WaitAthena Checker 与 --top-results 模式:多明文收集机制的原理与使用指南
Ciphey WaitAthena Checker 与 top results 模式:多明文收集机制的原理与使用指南 导读 Ciphey 在默认模式下采用 At
CLI网络安全Ciphey 存储模块深度解析:SQLite 缓存、WaitAthena 结果与静态数据资源的统一管理
Ciphey 存储模块深度解析:SQLite 缓存、WaitAthena 结果与静态数据资源的统一管理 本篇技术指南以 Ciphey 的 src/storage
CLI网络安全Ultralytics Results 结果类深度解析:engine.results 中 Boxes、Masks、Keypoints、Probs、OBB 与 Results 的完整使用指南
Ultralytics Results 结果类深度解析:engine.results 中 Boxes、Masks、Keypoints、Probs、OBB 与 R
人工智能计算机视觉深度学习机器学习预训练
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考