|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 | import sys |
3 | | -from z3 import BitVec, Solver, And, sat |
4 | 3 |
|
5 | 4 | def main(): |
6 | | - # 建立 8 個 32-bit BitVec 變數 |
7 | | - bvs = [BitVec(f'k{i}', 32) for i in range(8)] |
8 | | - solver = Solver() |
9 | | - |
10 | | - # 0 <= xi <= 255 |
11 | | - for x in bvs: |
12 | | - solver.add(And(x >= 0, x <= 255)) |
13 | | - |
14 | | - # 約束條件 |
15 | | - solver.add(bvs[0] ^ bvs[1] == 0x55) |
16 | | - solver.add(bvs[2] + bvs[3] == 200) |
17 | | - solver.add(bvs[4] * 3 == bvs[5]) |
18 | | - solver.add(bvs[6] - bvs[7] == 1) |
19 | | - solver.add(bvs[1] + bvs[2] - bvs[3] == 50) |
20 | | - solver.add(bvs[5] ^ bvs[6] == 0x2A) |
21 | | - |
22 | | - # 限制為可列印 ASCII 字元 (0x20–0x7e),且不等於換行符 |
23 | | - for x in bvs: |
24 | | - solver.add(And(x >= 0x20, x <= 0x7e, x != 0x0A)) |
25 | | - |
26 | | - # 求解並輸出 |
27 | | - if solver.check() == sat: |
28 | | - model = solver.model() |
29 | | - vals = [model[x].as_long() for x in bvs] |
30 | | - solution = bytes(vals) |
31 | | - # 如果需要十六進制或 ASCII 字串可以這樣: |
32 | | - hex_str = " ".join(f"{v:02x}" for v in vals) |
33 | | - ascii_str = solution.decode('ascii', errors='replace') |
34 | | - # 直接把原始 bytes 寫到 stdout |
35 | | - sys.stdout.buffer.write(solution) |
36 | | - # 以下兩行可選:印出 hex / ASCII 方便檢查 |
37 | | - # print("\nhex:", hex_str) |
38 | | - # print("ascii:", ascii_str) |
39 | | - else: |
| 5 | + sol = None |
| 6 | + |
| 7 | + for b3 in range(91, 127): |
| 8 | + b2 = 200 - b3 |
| 9 | + b1 = 2 * b3 - 150 |
| 10 | + if not (0x20 <= b1 <= 0x7e): |
| 11 | + continue |
| 12 | + b0 = b1 ^ 0x55 |
| 13 | + if not (0x20 <= b0 <= 0x7e): |
| 14 | + continue |
| 15 | + |
| 16 | + for b4 in range(0x20, 43): |
| 17 | + b5 = 3 * b4 |
| 18 | + if not (0x20 <= b5 <= 0x7e): |
| 19 | + continue |
| 20 | + |
| 21 | + b6 = b5 ^ 0x2A |
| 22 | + b7 = b6 - 1 |
| 23 | + if not (0x20 <= b6 <= 0x7e and 0x20 <= b7 <= 0x7e): |
| 24 | + continue |
| 25 | + |
| 26 | + if not (b2 + b3 == 200): continue |
| 27 | + if not (b1 + b2 - b3 == 50): continue |
| 28 | + if not (b6 - b7 == 1): continue |
| 29 | + |
| 30 | + sol = [b0, b1, b2, b3, b4, b5, b6, b7] |
| 31 | + break |
| 32 | + if sol is not None: |
| 33 | + break |
| 34 | + |
| 35 | + if sol is None: |
40 | 36 | sys.exit(1) |
41 | 37 |
|
| 38 | + data = bytes(sol) |
| 39 | + sys.stdout.buffer.write(data) |
| 40 | + |
42 | 41 | if __name__ == "__main__": |
43 | 42 | main() |
0 commit comments