三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Hydro Hack 功能:手刃伪AC

Hydro Hack 功能:手刃伪AC

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,需要做好三件事:SPJValidator配置文件

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)中读取 ab,然后判断选手输出是不是 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 了。操作步骤如下:

  1. 找到目标提交:在题目提交记录里,找到一份 AC 的提交(比如我那份输出 8 的代码),点进去。
  2. 点击 Hack 按钮:记录详情页的右上角有一个 Hack 按钮。
  3. 构造 Hack 数据:在弹出的界面里,输入你想用来卡掉对方的数据。比如对于这道题,输入 1 2(期望输出 3,但对方会输出 8)。
  4. 提交 Hack:点击提交,系统会自动用这组数据去重测目标提交。

如果 Hack 成功,对方的提交状态会从 Accepted 变成 Wrong Answer。而你的 Hack 记录也会被保留下来,供后人瞻仰

3. Hack 的内部流程

当你点击 Hack 按钮后,Hydro 会做以下几件事:

  1. 校验输入:用 validator 检查你提供的数据是否合法。
  2. 运行目标代码:用你的输入数据重新运行被 Hack 的那份提交。
  3. 判断结果:用 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)。

← 返回列表