html_doc = r"""pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp
"""
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]]))