首页
学习
活动
专区
圈层
工具
发布

用欧拉计划学Rust编程(第79题)

第79题 密码推断

问题描述:

网上银行常用的一种密保手段是向用户询问密码中的随机三位字符。例如,如果密码是531278,询问第2、3、5位字符,正确的回复应当是317。

在文本文件keylog.txt中包含了50次成功登陆的正确回复。

假设三个字符总是按顺序询问的,分析这个文本文件,给出这个未知长度的密码最短的一种可能。

解题步骤

1)分析keylog.txt

文件中前几个数:319、680、180、690、129、620,根据一个3位数回复,比如319,能够知道3出现在1前面,1出现在9前面。

读文件,把这种信息用元组保存起来。

代码语言:javascript
复制
let data = std::fs::read_to_string("keylog.txt").expect("打开文件失败");
let data2 = data.trim().replace("\r", "");
let lines = data2.split("\n");

let mut set: Vec<(&str, &str)> = vec![];
for line in lines {
    let a = &line[..1];
    let b = &line[1..=1];
    let c = &line[2..];
    if !set.contains(&(a, b)) {
        set.push((a, b));
    }
    if !set.contains(&(b, c)) {
        set.push((b, c));
    }
}

2)GraphViz

排除掉重复的元素,手工分析这些先后顺序,也可以得到一个初步结果。如果你知道有一个GraphViz这个画图利器,把刚才的元素关系生成图元命令。

代码语言:javascript
复制
println!("digraph G {{");
println!("  rankdir=LR;");
for (a, b) in set {
    println!("  {} -> {};", a, b);
}
println!("}}");

程序输出这样一组命令:

代码语言:javascript
复制
digraph G {
rankdir=LR;
  3 -> 1;
  1 -> 9;
  6 -> 8;
  8 -> 0;
  1 -> 8;
  6 -> 9;
  9 -> 0;
  1 -> 2;
  2 -> 9;
  6 -> 2;
  2 -> 0;
  7 -> 6;
  8 -> 9;
  3 -> 6;
  7 -> 1;
  1 -> 0;
  7 -> 2;
  1 -> 6;
  6 -> 0;
  7 -> 3;
  3 -> 8;
  2 -> 8;
  7 -> 9;
}

从graphviz.org网站下载并安装GraphViz软件,用上面的几行文本可以快速生成图形。

73162890

多么醒目的答案。


下一篇
举报
领券