import os import random ANSWER = list(range(10**4)) random.shuffle(ANSWER) CHANCE = 15 def peep(): global CHANCE if CHANCE <= 0: print("You ran out of CHANCE. Bye!") exit(1) CHANCE -= 1 index = map(int, input("Index (space-separated)> ").split(" ")) result = [ANSWER[i] for i in index] random.shuffle(result) return result def guess(): guess = input("Guess the numbers> ").split(" ") guess = list(map(int, guess)) if guess == ANSWER: flag = os.getenv("FLAG", "FAKE{REDACTED}") print(flag) else: print("Incorrect") def main(): menu = """ 1: peep 2: guess""".strip() while True: choice = int(input("> ")) if choice == 1: result = peep() print(result) elif choice == 2: guess() else: print("Invalid choice") break main()
10000までの数字が一つずつあって、シャッフルされた配列を15回のクエリで求める。
クエリは「添字iの値」を取得できるやつだがシャッフルされて返ってくるので素直には解けない。
とはいえ重複が許可されるので0 1 1
とかを送って333 999 333
だったらARRAY[0] = 999
みたいな感じで解ける
重複が許されない場合も添字の下から1bitずつ求めるみたいなことができるらしい → https://qiita.com/kusano_k/items/b63cc22c38cbf172f79d#guess-normal
from ptrlib import Socket, Process from collections import Counter import ast ans = [] sock = Socket("nc guess-mis.wanictf.org 50018") # sock = Socket("localhost", 9999) for i in range(10): sock.sendlineafter("> ", "1") query = [] for j in range(1000): query.append(" ".join([str(1000*i + j) for _ in range(j+1)])) sock.sendlineafter("> ", " ".join(query)) xs = ast.literal_eval(sock.recvline().decode()) ans.extend([v[0] for v in Counter(xs).most_common()][::-1]) print(len(ans)) sock.sendlineafter("> ", "2") sock.sendlineafter("> ", " ".join(str(a) for a in ans)) sock.interactive()