html_doc = r"""p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
p
""" from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc, 'html.parser') queue = [] ops = [] stack = [] for child in soup.select("code > *"): if child.name == 'a': queue.extend(list(child.children)) queue.append(child) for child in queue: if child.name == 'data': ops.append('data %s' % child['value']) elif child.name == 'cite': assert child.text == 'p' ops.append('p') elif child.name == 'a': if child['href'] == 'javascript:x()': ops.append('xor') else: raise TypeError("Invalid function name: \"%s\"" % child['href']) elif child.name == 'address': ops.append('address') elif child.name == 'ul': ops.append('multiply') elif child.name == 'dd': ops.append('add') elif child.name == 'sub': ops.append('subtract') elif child.name == 'em': ops.append('equal') elif child.name == 'b': ops.append('and') else: raise TypeError("Invalid operation name: \"%s\"" % child.name) ops = ops[::-1] while ops: op = ops.pop() if op.startswith('data'): stack.append(int(op.split('data ')[1])) elif op == 'p': stack.append('p') elif op == 'xor': a = stack.pop() b = stack.pop() if 'p' in str(a) or 'p' in str(b): stack.append('(%s ^ %s)' % (b, a)) else: stack.append(b ^ a) elif op == 'address': a = stack.pop() b = stack.pop() assert b == 'p' assert not 'p' in str(a) stack.append('p%s' % a) elif op == 'multiply': a = stack.pop() b = stack.pop() if 'p' in str(a) or 'p' in str(b): stack.append('(%s * %s)' % (b, a)) else: stack.append(b * a) elif op == 'add': a = stack.pop() b = stack.pop() if 'p' in str(a) or 'p' in str(b): stack.append('(%s + %s)' % (b, a)) else: stack.append(b + a) elif op == 'subtract': a = stack.pop() b = stack.pop() if 'p' in str(a) or 'p' in str(b): stack.append('(%s - %s)' % (b, a)) else: stack.append(b - a) elif op == 'equal': a = stack.pop() b = stack.pop() if 'p' in str(a) or 'p' in str(b): stack.append('(%s == %s)' % (b, a)) else: stack.append(int(b == a)) elif op == 'and': a = stack.pop() b = stack.pop() if 'p' in str(a) or 'p' in str(b): #stack.append('(%s and %s)' % (b, a)) stack.append('%s, %s' % (b, a)) else: stack.append(int(bool(int(b) & int(a)))) else: raise TypeError("Invalid operation name: \"%s\"" % child.name) assert len(stack) == 1 expr = stack[0] expr = f'[{expr}]' from z3 import * p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 = [BitVec(pp, 8) for pp in 'p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15'.split(',')] eqs = eval(expr) s = Solver() for eq in eqs: s.add(eq) assert s.check() == sat model = s.model() print(bytes([int(str(model[pp])) for pp in [p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15]]))