This repository has been archived by the owner on Nov 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
generate.py
executable file
·94 lines (77 loc) · 3.96 KB
/
generate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
import hmac
import json
import io
import math
import os
import PIL.Image, PIL.ImageDraw, PIL.ImageFont
import random
import re
import sys
import subprocess
import tempfile
import xml.etree.ElementTree
PREFIX = "ugra_apply_now_for_senior_ai_researcher_"
SECRET = b"town-ludicrous-christian-promotion-rinse"
SALT_SIZE = 10
def get_flag():
user_id = sys.argv[1]
return PREFIX + hmac.new(SECRET, str(user_id).encode(), "sha256").hexdigest()[:SALT_SIZE]
def generate():
if len(sys.argv) < 3:
print("Usage: generate.py user_id target_dir", file=sys.stderr)
sys.exit(1)
user_id = sys.argv[1]
target_dir = sys.argv[2]
random.seed(hmac.new(SECRET, str(user_id).encode(), "sha256").digest())
flag = get_flag()
etalons_xml = xml.etree.ElementTree.parse(open(os.path.join("private", "etalons.svg")))
etalons = {}
for n, c in enumerate(etalons_xml.getroot().findall("{http://www.w3.org/2000/svg}path")):
if n % 4 == 0:
etalons[n // 4] = []
etalons[n // 4].append(c.attrib["d"])
font = PIL.ImageFont.load(os.path.join("private", "ter-u14b_iso-8859-1.pil"))
image = PIL.Image.new("RGB", (len(flag) * 8 + 1, 14))
freqs = [random.randint(20, 50) * 0.001 for _ in range(3)]
for x in range(image.size[0]):
for y in range(image.size[1]):
image.putpixel((x, y), tuple(int(127 + c * 127) for c in [math.sin(30 + freqs[0] * (2 * x + 3 * y)),
math.sin(40 + freqs[1] * (4 * x - 1 * y)),
math.sin(50 + freqs[2] * (5 * x - 8 * y))]))
text_image = PIL.Image.new("RGB", (len(flag) * 8 + 1, 14))
draw = PIL.ImageDraw.ImageDraw(text_image)
draw.text((1, -1), flag, font=font, fill=(255, 255, 255))
for x in range(image.size[0]):
for y in range(image.size[1]):
if text_image.getpixel((x, y)) == (255, 255, 255):
image.putpixel((x, y), tuple(255 - c for c in image.getpixel((x, y))))
image_io = io.BytesIO()
image.save(image_io, format="BMP")
data = image_io.getvalue()
with tempfile.TemporaryDirectory() as temp_dir:
with open(os.path.join(temp_dir, "1.svg"), "w") as svg:
R = re.compile("-?\d+\.\d+")
LINE_LENGTH = 89 # BMP size is known to be divisible by this number
svg.write(f"""<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="{28 * 3 * LINE_LENGTH}"
height="{28 * len(data) // LINE_LENGTH}">\n"""
"""<style>svg { fill: black; }
.p { stroke: white; fill: none; stroke-linecap: round; stroke-linejoin: round } </style>
<rect width="100%" height="100%" fill="black"/>\n""")
for n, ch in enumerate(data):
for dn, digit in enumerate(f"{ch:03d}"):
svg.write(f"""<g transform="translate({28 * 3 * (n % LINE_LENGTH)} {28 * (n // LINE_LENGTH)})
translate({28 * dn} 0) scale(0.8 0.8) translate(3 3)">""")
d = random.choice(etalons[int(digit)])
d = R.sub(lambda m: "%.6f" % (float(m.group(0)) + random.random() * 3 - 1.5), d)
svg.write(f'<path d="{d}" class="p" style="stroke-width:{random.randint(20, 45) * 0.1}px" />')
svg.write("</g>\n")
svg.write("</svg>")
# or probably: dbus-run-session inkscape -z -e ...
subprocess.check_call(["inkscape", "-z", "-e",
os.path.join(target_dir, "mnistry-data.png"), os.path.join(temp_dir, "1.svg")],
stdout=sys.stderr)
json.dump({"flags": [flag], "substitutions": {}, "urls": []}, sys.stdout)
if __name__ == "__main__":
generate()