-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path26-decent.py
76 lines (60 loc) · 2.37 KB
/
26-decent.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of Python Challenge Solutions
# https://github.com/scorphus/PythonChallengeSolutions
# Licensed under the BSD-3-Clause license:
# https://opensource.org/licenses/BSD-3-Clause
# Copyright (c) 2018-2020, Pablo S. Blum de Aguiar <scorphus@gmail.com>
# http://www.pythonchallenge.com/pc/hex/decent.html
from auth import read_riddle
from etc import image_to_text
from importlib import import_module
from io import BytesIO
from PIL import Image
from wand.exceptions import BaseError as WandBaseError
from wand.image import Image as WandImage
import inspect
import zipfile
def get_ambiguity_data():
ambiguity = import_module("24-ambiguity")
return ambiguity.data
def extract_source(func):
"""Extracts source of func"""
source = inspect.getsource(func).splitlines()
indentation = len(source[0]) - len(source[0].lstrip())
return "\n".join(line[indentation:] for line in source)
def patch_update_crc():
"""Monkey-patches `ZipExtFile._update_crc` to bypass any bad CRC"""
update_crc_src = extract_source(zipfile.ZipExtFile._update_crc).replace(
"raise", "return #"
)
exec_globals = {"crc32": zipfile.crc32}
exec(compile(update_crc_src, "<string>", "exec"), exec_globals)
zipfile.ZipExtFile._update_crc = exec_globals["_update_crc"]
def extract_image(zip_data):
"""Extracts an image from a corrupt zip file inside `zip_data`"""
patch_update_crc()
with zipfile.ZipFile(BytesIO(zip_data)) as outer:
for name in outer.namelist():
try:
with zipfile.ZipFile(outer.open(name)) as inner, inner.open(
inner.namelist()[0]
) as img_file:
# Pillow couldn't read the corrupt gif, even with
# PIL.ImageFile.LOAD_TRUNCATED_IMAGES set to True
return WandImage(file=img_file)
except (zipfile.BadZipFile, WandBaseError):
pass
ambiguity_data = get_ambiguity_data()
image = extract_image(ambiguity_data)
image_data = image.export_pixels()
pil_image = Image.frombytes("RGBA", image.size, bytes(image_data))
print(image_to_text(pil_image, skip=3))
for line in read_riddle(
"http://www.pythonchallenge.com/pc/hex/decent.html"
).splitlines():
if not line:
break
if "<" in line:
continue
print(line.rsplit(maxsplit=1)[-1])