第79题 密码推断
问题描述:
网上银行常用的一种密保手段是向用户询问密码中的随机三位字符。例如,如果密码是531278,询问第2、3、5位字符,正确的回复应当是317。
在文本文件keylog.txt中包含了50次成功登陆的正确回复。
假设三个字符总是按顺序询问的,分析这个文本文件,给出这个未知长度的密码最短的一种可能。
解题步骤
1)分析keylog.txt
文件中前几个数:319、680、180、690、129、620,根据一个3位数回复,比如319,能够知道3出现在1前面,1出现在9前面。
读文件,把这种信息用元组保存起来。
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这个画图利器,把刚才的元素关系生成图元命令。
println!("digraph G {{");
println!(" rankdir=LR;");
for (a, b) in set {
println!(" {} -> {};", a, b);
}
println!("}}");
程序输出这样一组命令:
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
多么醒目的答案。