计算机密码已经存在很长时间了。事实上,60年前,CTSS 是最早使用密码的计算机系统之一。它的实现非常简单:在 CTSS 中,密码以明文形式存储在磁盘上的文件中。登录时,用户输入一个密码,计算机随后将该密码与磁盘上的密码进行比较。如果比较失败,则拒绝访问;如果成功,则允许访问。MIT 的研究人员很快就发现了该密码系统中的几个安全漏洞。我们将探讨其中之一:计时攻击。
IBM 7090 控制台 (公有领域)
在计时攻击中,我们利用可以通过计算所花费的时间来推断计算路径这一事实。在 CTSS 中,密码检查使用简单的字符串匹配算法,类似于:
bool CheckPassword(string pwd1, string pwd2) {
if (pwd1.Length != pwd2.Length) {
return false;
}
for (int i = 0; i < pwd1.Length; i++) {
if (pwd1[i] != pwd2[i]) {
return false;
}
}
return true;
}为了本题的目的,我们将使用一个(非常)简化的计时模型和上述算法。计时模型如下:
- 分支语句(
if或for)耗时 1 ms。 - 赋值或更新内存地址耗时 1 ms。
- 两个内存地址之间的比较耗时 3 ms。
return语句耗时 1 ms。
密码由 1 到 20 个英文字母(大小写均可)和数字组成。
交互
这是一个交互式问题。你的提交将针对一个交互器运行,该交互器读取你的程序的标准输出并向你的程序的标准输入写入数据。此交互需要遵循特定的协议:
- 你的程序首先发送一个密码字符串,由 1 到 20 个英文字母(大小写均可)和数字组成。
- 根据密码是否正确,交互器会做出以下响应:
- 如果密码正确,返回 “ACCESS GRANTED”。你的程序随后应正常退出。
- 如果密码不正确,返回 “ACCESS DENIED (t ms)”,其中 $t$ 是验证密码所花费的时间(以毫秒为单位)。你的程序随后可以进行下一次猜测。
确保在每次写入后刷新缓冲区。你最多可以猜测 2500 次。题目提供了一个测试工具来帮助你开发解决方案。
样例
输入格式 1
A HunFhun Hunter1 Hunter2
输出格式 1
ACCESS DENIED (5 ms) ACCESS DENIED (41 ms) ACCESS DENIED (68 ms) ACCESS GRANTED