HackThisSite - Programming Mission 12

Challenge

Level 12 — String manipulation

页面给出一串随机字符串。把所有数字取出来,按质数/合数分类(都是一位数,01 不计):先求所有合数之和,再求所有质数之和,两者相乘得到一个乘积。然后取字符串里前 25 个非数字字符,把每个字符的 ASCII 值加一(例:#$),把这 25 个字符与乘积首尾相接连成答案。限时 5 秒

Your answer should look like this: oc{lujxdpb%jvqrt{luruudtx140224

状态:verified(服务端返回 Good Job, ***, You have successfully completed this mission)。

Solution

  • 实例页 https://www.hackthissite.org/missions/prog/12/ 里,随机字符串不在正文,而是塞在一个只读文本框里:<input type="text" value="0gww@d@9fdns7$0dvukzaozhex119223fz355jsf1wf4#e#gw1m30k94#phc59mmh@9hpvrhcvogerchqlw3f@choou1?1k3q?2kbdapa025ogk0l$#zo8lg19tk06gasgb2eyb01ro#$5c@bilv9t?5gxpd4oehv5v@$6tj1dgft4xr9x36$ihq3$vhs8dd900cxiekvq9$#jot2hz794na2oryxqw$8wg7f8eqetpn#t?d17?jkmevz@@zm2qx8e1z3a#bmzagg3hi?3l?ch?3elnb@85djdvn31jr3uieykqxvgor7g429c5@ew2gaa2v9034fs9j@73@iu#1lftupdbzy#mb2zp320wlnov5t5$bobha?65480nwqjvbmn7t9#3gc2uykfdfsic8fxz#sgg$od7je9f19uvm$#zpyhyyxnm29$m3qs3l46h2jzlt8i24ekczkps3xrqshl@e#3cn9g86iw3fxt$8nog@z50#69pssqcnuyo4u7#$hll9tklt7f2r$4ye7ou86rejoyuz1?6xgpcbsejpvakx4gbfu3?k2pt?oyeq#sk#ra2kv8sqypx2ke$c#gkmcn4lqkj51n?flcyaj7xwbaki0ddl8v4ezz@durlny2zr" />。解析时直接正则抓 value="..." 最稳。
  • 题面给了一行示例答案 oc{lujxdpb%jvqrt{luruudtx140224:前 25 个字符是加一后的非数字字符,后面的 140224 是乘积。这就是校验格式。5 秒限时同样意味着必须在单进程内执行完毕。
  1. 数字分类:只取单个数字字符0-9),其中 01 既不算质数也不算合数;剩下的 4/6/8/9 是合数,2/3/5/7 是质数。合数求和 sum_c、质数求和 sum_p,乘积 product = sum_c * sum_p
  2. 前 25 个非数字字符:按原串顺序跳过所有数字字符,取满 25 个为止(包括 @ $ # ? 这些符号),每个字符 chr(ord(c) + 1)。顺序不能变,也不能去重。
1
2
3
4
5
6
7
8
9
10
11
PRIMES = {2, 3, 5, 7}
COMPOSITES = {4, 6, 8, 9}

def solve(s):
digits = [int(c) for c in s if c.isdigit()]
sum_c = sum(d for d in digits if d in COMPOSITES)
sum_p = sum(d for d in digits if d in PRIMES)
product = sum_c * sum_p
first25 = [c for c in s if not c.isdigit()][:25]
shifted = "".join(chr(ord(c) + 1) for c in first25)
return shifted + str(product), (sum_c, sum_p, product)
1
2
3
4
5
6
$ cd <hts-workspace> && export HTS_COOKIE='<mission-cookie>'
$ uv run python challenges/hts-prog/12/solve.py
string : 3#6yjkk0j1xpl5kfqr8$h33@uj70accae4cnncw9yaum@2tptgltmkmoo6g4 ...
sums : composite=378 prime=314 product=118692
answer : $zkllkyqmlgrs%iAvkbddbfdo118692
verdict : True

verdict: True 对应服务端 Good Job, ***, You have successfully completed this mission。同一个脚本再跑一次会重新抓实例、重新算,因此每次的答案都不同(product 随实例变化):

1
submit : POST /missions/prog/12/index.php  solution=<25 字符 + 乘积>
  • 0/1 计进去(它们既非质数也非合数)会导致乘积偏差很大,是这道题最常见的错法。
  • 只对前 25 个非数字字符做加一;第 26 个及以后不参与,不要先全串加一再截断(视觉上很像,结果不同)。
  • 数字只取单个字符:不要把连续数字当成多位数(题面明确 assume all numbers are one digit)。
  • 乘积是十进制字符串直接接在后面,不要补零、不要加分隔符。

Vulnerabilities

和同一类别里的其它限时题一样:服务端把完整的随机串下发给客户端,算法在题面里写清楚,客户端算完直接提交。这里唯一防护是 5 秒限时,对脚本而言就是一次 HTTP 往返;解析字符串的开销可以忽略。真正的修复方向是服务端持状态并对每次提交做一次性校验,或者在题面里不下发完整数据(只给需要的统计视图)。

$zkllkyqmlgrs%iAvkbddbfdo118692