From 709ef721afb0dc239e5246f5205f701b99d4a199 Mon Sep 17 00:00:00 2001 From: Runxi Yu <me@runxiyu.org> Date: Tue, 25 Mar 2025 03:25:30 +0800 Subject: Add Python challenge-solver script --- challenge.html | 2 +- static/solver.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 static/solver.py diff --git a/challenge.html b/challenge.html index 77e1eed..03c5988 100644 --- a/challenge.html +++ b/challenge.html @@ -48,7 +48,7 @@ </section> <section> - <p><a href="/.powxy/static/solver.c">A C implementation of the challenge solver</a> is available.</p> + <p><a href="/.powxy/static/solver.c">A C implementation</a> and <a href="/.powxy/static/solver.py">a Python implementation</a> of the challenge solver are available.</p> </section> </main> </body> diff --git a/static/solver.py b/static/solver.py new file mode 100644 index 0000000..0fe66f0 --- /dev/null +++ b/static/solver.py @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-2-Clause +# SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> + +import base64 +import hashlib +import sys +import struct + +def validate_bit_zeros(bs: bytes, n: int) -> bool: + q, r = divmod(n, 8) + if any(b != 0 for b in bs[:q]): + return False + if r and (bs[q] & (0xFF << (8 - r))): + return False + return True + +decoded = base64.b64decode(sys.argv[1]) +difficulty = int(sys.argv[2]) +next_val = 0 + +while True: + h = hashlib.sha256(decoded + struct.pack("Q", next_val)).digest() + if validate_bit_zeros(h, difficulty): + break + next_val = (next_val + 1) & 0xFFFFFFFFFFFFFFFF + if next_val == 0: + raise ValueError("overflow") + +print(base64.b64encode(struct.pack("Q", next_val)).decode()) -- cgit v1.2.3