diff --git a/players/hsfzxjy/从零开始的 HTTP 链接/README.md b/players/hsfzxjy/从零开始的 HTTP 链接/README.md new file mode 100644 index 0000000..7c26f1f --- /dev/null +++ b/players/hsfzxjy/从零开始的 HTTP 链接/README.md @@ -0,0 +1,70 @@ +# 从零开始的 HTTP 链接 + +此处提供一个使用 socket 编程完成 TCP 桥接的解法。 + +运行 `python3 bridge.py :8080 202.38.93.111:0`,浏览器访问 `localhost:8080` 即可。 + +```python +""" +python3 bridge.py :8080 202.38.93.111:0 +""" + +import sys +import socket +import select +import logging + + +def address(addr): + host, port = addr.split(":", 1) + return host, int(port) + + +def main(bind, connect, log_level): + logging.basicConfig(level=log_level, format="%(asctime)s:%(levelname)s:%(message)s") + serv = socket.create_server(bind) + rtol = {} + ltor = {} + try: + while True: + readers, _, _ = select.select( + tuple(rtol.values()) + tuple(ltor.values()) + (serv,), (), () + ) + for reader in readers: + if reader is serv: + local_client, addr = reader.accept() + remote_client = socket.create_connection(connect) + ltor[local_client.fileno()] = remote_client + rtol[remote_client.fileno()] = local_client + elif reader.fileno() in ltor: + data = reader.recv(2 ** 12) + if data: + logging.info("L -> R: %r", data) + ltor[reader.fileno()].sendall(data) + else: + remote = ltor[reader.fileno()] + del ltor[reader.fileno()], rtol[remote.fileno()] + remote.close() + reader.close() + else: + data = reader.recv(2 ** 12) + if data: + logging.info("R -> L: %r", data) + rtol[reader.fileno()].sendall(data) + else: + local = rtol[reader.fileno()] + del rtol[reader.fileno()], ltor[local.fileno()] + reader.close() + local.close() + except Exception as e: + raise e + finally: + for sock in tuple(rtol.values()) + tuple(ltor.values()) + (serv,): + sock.close() + + +if __name__ == "__main__": + bind = address(sys.argv[1]) + connect = address(sys.argv[2]) + main(bind, connect, "INFO") +``` \ No newline at end of file diff --git a/players/hsfzxjy/永不溢出的计算器/README.md b/players/hsfzxjy/永不溢出的计算器/README.md new file mode 100644 index 0000000..16b9f4a --- /dev/null +++ b/players/hsfzxjy/永不溢出的计算器/README.md @@ -0,0 +1,56 @@ +# 永不溢出的计算器 + +思路基本同官方。鉴于本题没有提供 TCP 接口,这里给出一个在浏览器里搜索不同二次剩余的脚本。 + +将以下代码贴在浏览器控制台运行即可。如果脚本停了,最后输出的两个数即是所要的 x 和 y。 + +此处的原理是利用页面暴露在全局的 WebSocket 对象 `socket` 直接收发数据。 + +```javascript +(() => { + function rand(a, b) { + return Math.round(Math.random() * (b - a) + a) + } + + function selectLargeNum() { + const len = Math.round(rand(154, 307)) + let ret = '' + for (let i = 0; i < len; i++) ret += rand(0, 9) + return ret.replace(/^0+/, '') + } + + class Result { + constructor() { + this.reset() + } + reset() { + this.promise = new Promise(resolve => this.resolve = resolve) + this.text = '' + } + } + + let result = new Result + socket.addEventListener('message', (msg) => { + result.text += msg.data + if (! /\r\n>\s+$/.test(result.text)) return + result.resolve(/(\d+)\r\n>\s+$/.exec(result.text)[1]) + }) + + + async function loop() { + let num = selectLargeNum() + result.reset() + socket.send(num + ' ^ 2\n') + let res = await result.promise + result.reset() + socket.send('sqrt(' + res + ')\n') + res = await result.promise + console.log(res) + console.log(num) + if (num !== res) return + setTimeout(loop, 100) + } + + loop() +})() +``` \ No newline at end of file diff --git a/players/hsfzxjy/超基础的数理模拟器/README.md b/players/hsfzxjy/超基础的数理模拟器/README.md new file mode 100644 index 0000000..2473804 --- /dev/null +++ b/players/hsfzxjy/超基础的数理模拟器/README.md @@ -0,0 +1,72 @@ +# 超基础的数理模拟器 + +由于学过符号计算软件,本人首先想到用 Mathematica 去算积分,绕了点弯路,但还是可做的。以下给出代码。其中有几个要点: + + 1. Mathematica 的 `ToExpression` 转换后的表达式是 `Integrate[...]` 也即符号积分,此时有可能算出奇怪的答案(比如复数解)。此时应该将 `Integrate` 替换为 `NIntegrate`。 + 2. 其他一些替换,如把自然对数底 `e` 换成 `E`;最后的 `{d x}` 换成 `dx`;`\` 换成 `\\`;被积函数要用 `{}` 括起来。 + +偶尔会有几个积分算不出来,但概率不大。半小时左右能拿到 flag。 + +```python +import re +import pexpect +import requests + + +headers = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36", + "Referer": "http://202.38.93.111:10190/", +} + +s = requests.session() +s.cookies.clear() + +address = "http://202.38.93.111:10190/" + +tex_pattern = re.compile( + r"(?P\d+)\s*题[.\s\S]+

\s*\$(?P.+)\$\s*

", re.M | re.X | re.U, +) +body_pattern = re.compile(r"(^[^\s]+\s)(?P.*)\\") + + +def process_expr(expr: str): + expr = expr.replace("{d x}", "dx") + expr = re.sub(r"\be\b", "E", expr) + expr = body_pattern.sub(r"\g<1>(\g)\\", expr) + expr = expr.replace("\\", "\\\\") + return expr + + +def get_code(expr: str): + return f'ToExpression["{expr}",TeXForm,Hold]/.Integrate->NIntegrate//ReleaseHold' + + +def next_probem(ans=""): + if ans: + response = s.post(address + "/submit", data=dict(ans=ans)) + else: + response = s.get(address) + print(response.text) + matched = tex_pattern.search(response.text) + expr = matched.group("expr") + progress = matched.group("progress") + expr = process_expr(expr) + code = get_code(expr) + p = pexpect.spawn("wolframscript", ["-code", code]) + p.wait() + if p.exitstatus != 0: + return "", progress + try: + answer = "{:.6f}".format(float(p.read().decode().strip())) + except ValueError: + return "", progress + return answer, progress + + +ans = "" +while True: + ans, round = next_probem(ans) + print(ans, round) + if round == 0: + break +``` \ No newline at end of file