Hydro Hack 功能:手刃伪AC
在之前的几篇文章里,我们聊了 SPJ(Special Judge)的基础和进阶用法。这次我们来看 Hydro 另一个有趣又实用的功能 —— Hack。
简单来说,Hack 就是:你 AC 了一道题之后,可以构造一组数据去卡掉别人的 AC 代码。如果成功,对方的提交会被重测并变成 WA。
听起来很刺激对吧?下面我用一个活生生的例子,带大家把整个流程走一遍。
0. 一个注定被 Hack 的提交
先来看一道题:P0006 - A+B Problem。
题目链接:https://hydro.ac/d/hc_system/p/P0006/
(就是A+B Problem)
然后,我交了一份这样的代码上去:
#include <bits/stdc++.h>
using namespace std;int main() {cout << 8;return 0;
}
特别唐是不是?它 AC 了。
为什么?因为题目只有一个测试点,而那个测试点的输入恰好是 3 5。所以这份“输出 8”的代码堂而皇之地拿到了 AC。
但这道题的特别之处在于:它开启了 Hack 功能。这意味着,任何人都可以构造一组数据,让这份不严谨的代码现出原形。
1. 准备工作:题目配置
要让一道题支持 Hack,需要做好三件事:SPJ、Validator 和 配置文件。
1.1 checker.cc:判断答案对错
#include "testlib.h"
int main(int argc, char** argv) {registerTestlibCmd(argc, argv);long long a = inf.readLong();long long b = inf.readLong();long long ans = ouf.readLong();if (a + b == ans)quitf(_ok, "Accepted!");elsequitf(_wa, "Wrong answer");return 0;
}
这里的关键是 inf —— 它从输入文件(.in)中读取 a 和 b,然后判断选手输出是不是 a+b。因为答案不依赖 .ans 文件,Hack 时只需要提供输入数据就行。
1.2 validator.cc:校验输入数据合法性
#include "testlib.h"
int main() {registerValidation();__int128_t a = inf.readLong();inf.readSpace();__int128_t b = inf.readLong();inf.readEof();__int128_t c = a + b;ensure(INT64_MIN <= c && c <= INT64_MAX);return 0;
}
Validator 的作用是确保输入数据符合题目要求。比如这里要求 \(a+b\) 不超过 64 位有符号整数的范围,防止构造数据时溢出。
1.3 config.yaml:把一切串起来
type: default
time: 1s
memory: 256m
checker_type: testlib
checker: checker.cc
validator: validator.cc
subtasks:- score: 100id: 1cases:- input: 1.inoutput: 1.out
注意 validator: validator.cc 这一行 —— 它告诉 Hydro 在评测和 Hack 时都要用 validator 校验输入数据。
2. 发起 Hack:手刃“输出 8”的代码
当一份 AC 代码存在漏洞时,你就可以发起 Hack 了。操作步骤如下:
- 找到目标提交:在题目提交记录里,找到一份 AC 的提交(比如我那份输出
8的代码),点进去。 - 点击 Hack 按钮:记录详情页的右上角有一个 Hack 按钮。
- 构造 Hack 数据:在弹出的界面里,输入你想用来卡掉对方的数据。比如对于这道题,输入
1 2(期望输出3,但对方会输出8)。 - 提交 Hack:点击提交,系统会自动用这组数据去重测目标提交。
如果 Hack 成功,对方的提交状态会从 Accepted 变成 Wrong Answer。而你的 Hack 记录也会被保留下来,供后人瞻仰。
3. Hack 的内部流程
当你点击 Hack 按钮后,Hydro 会做以下几件事:
- 校验输入:用 validator 检查你提供的数据是否合法。
- 运行目标代码:用你的输入数据重新运行被 Hack 的那份提交。
- 判断结果:用 checker(SPJ)判断输出是否正确。如果错了,Hack 成功,对方被 Rejudge 并降分。
整个过程和正常评测几乎一样,只是输入数据换成了你构造的那一组。
4. 关于 Hack 的几个要点
- Hack 数据只需要输入文件:因为 checker 从
inf读数据,不依赖.ans文件。 - Validator 是必须的:没有 validator,Hack 功能无法正常工作。
- Hack 成功会触发重测:被 Hack 的提交会变成 WA,分数也会相应扣除。
- 比赛中的 Hack 有特殊规则:比赛期间的 Hack 可能不会立即触发整体重测。
5. 结语
Hack 功能的存在,让 OJ 不再只是一个“做完题就结束”的地方。它鼓励大家去思考:“别人的代码真的对吗?”“有没有我没想到的边界情况?”
而且说实话,Hack 别人的 AC 代码,比自己 AC 一道题还爽(doge)。