Вызов на Python-игры (продолжение)
Внимание! Прежде чем читать дальше, я настоятельно рекомендую всем попытаться справится с задачами самостоятельно. Опыт и полученное вами удовольствие будут несравненно выше.
Уровень 5.
Этот уровень сначала меня озадачил предложением произнести «peak hell». Проделав данную малоосмысленную операцию несколько раз, я призадумался, что бы это могло быть.
Как всегда, подсказка была получена после чтения исходника страницы. В нем нашлась очень интересная строка:
<peakhell xsrc="banner.p" mce_src="banner.p"/>Скачав данный р-файлик и внимательно его изучив я понял что должно напоминать выражение «peak hell» — «pickle» модуль Python для сериализации объектов.
Для загрузки из файла понадобилась одна маленькая программа.
import pickle
# Открываем файлик для чтения
text = open('banner.p','r')
# Загружаем объект
obj = pickle.load(text)
# Смотрим что получилось
print(dir(obj))После изучения стало понятно, что мы имеем дело со списком, состоящим из 23 списков, которые в свою очередь состоят из пар символ:цифра, причем цифра показывает сколько раз необходимо печатать символ.
Для вывода на экран я воспользовался следующей конструкцией.
for lines in obj: line = [ch * count for ch, count in lines] print "".join(line)Получился в итоге красивый баннер, показывающий URL следующего уровня.
Уровень 6.
Этот уровень встретил красивой картинкой змейки (по-английски zipper) и подсказкой в исходном тексте «<— zip —> ».
Заменив в URL страницы расширение на zip, я скачал интересный файлик, содержащий помимо прочего следующий readme:
welcome to my zipped list. hint1: start from 90052 hint2: answer is inside the zipФайл под номером 90052 опять начинал «цепочку» отсылок к другим файлам, как уже было в задаче на 4 уровне.
Пришлось опять писать программу, на этот раз, используя zipfile. Тут возникла проблема. Я опять ожидал увидеть подсказку в содержимом файла, но пройдя все файлы до единого, я не нашел там ничего достойного внимания. Подумав, где еще может быть «спрятана» информация в архиве, я обратил внимание на hint2, натолкнувший меня на предположение, что надо искать в комментариях к каждому отдельному файлу, что оказалось верным.
import zipfile, re
# строим регулярное выражение для получения из файла цифр.
numbers=re.compile('[d]*$')
number="90052"
# открываем zip
zip = zipfile.ZipFile("channel.zip", "r")
while True:
# имя следующего файла
fn=number+".txt"
# получаем содержимое файла
filecontents = zip.read(fn)
# печатаем комментарий файла, который как раз и содержит нужную инфу
print zip.getinfo(fn).comment,
# берем следующее имя файла
match=numbers.findall(filecontents)
if len(match) > 1:
number="".join(match)
else:
breakЭта программа дает следующее слово «HOCKEY», которое приводит нас... на подсказку, советующую искать «в воздухе» и «посмотреть на буквы». Тут у меня опять возник ступор, так как я думал, что это уже следующий уровень, и принялся внимательно изучать буквы фразы-подсказки.
Но все оказалось проще, присмотревшись к буквам слова «HOCKEY» я увидел, что они состоят из других букв, которые и вывели на настоящую страницу уровня 7.
Уровень 7.
На этом уровне ничего кроме картинки с уродливой серой полоской обнаружено не было. Оставалось изучить ее. Открыв ее в текстовом редакторе, я посмотрел, что полоска состоит из серых квадратиков разной интенсивности, что и натолкнуло на мысль о том, что интенсивность серого цвета кодирует букву.
Поискав какую-нибудь библиотеку для работы с изображениями на Python я остановился на PIL.
Программа в результате оказалась очень простой:
import Image
# рисунок сохранен локально
im = Image.open('oxygen.png')
# от нулевого пиксела до 608, ширина квадрата 7 пикселов
xcoords = range(0, 608, 7)
result = []
# цикл по квадратикам
for x in xcoords:
# получаем интенсивность пикселейы и переводим ее в символ
result.append(chr(im.getpixel((x,50))[0]))
print ''.join(result)В результате получаем сообщение:smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]Его расшифровка уже совсем тривиальна:
result = [] for c in [105, 110, 116, 101, 103, 114, 105, 116, 121]: result.append(chr(c)) print ''.join(result)В результате получаем слово на следующий уровень.
Уровень 8.
«Поелозив» мышкой по странице, легко находим ссылку на форму. Но при щелчке по нему у нас спрашивают логин и пароль. Делать нечего, опять смотрим исходник страницы. Там в комментарии содержатся 2 строчки с очень «говорящими» называниям un и pw.
Как они зашифрованы — было не совсем ясно, но внимание привлек факт, что строки начинаются одинаково. Порывшись в google на предмет «BZh91», я быстро нашел что эти строки — сигнатура bz2 компрессора.
К счастью, модуль bz2 компрессии в стандартной библиотеке Python имеется. Что сделало программу очень примитивной (строки с «шифром» я сократил для наглядности).
import bz2 un = 'BZh91AY&SYAxafx82… pw = 'BZh91AY&SYx94$|x0ex00x00x00x81… print bz2.decompress(un) print bz2.decompress(pw)Это дало логин и пароль на следующий уровень.
Уровень 9.
На уровне 9 предложили соединить точки. Но только не те, которые на рисунке, а другие, с координатами, перечисленными в исходнике страницы.
Тут опять пришлось прибегнуть к помощи PIL, установленной на уровне 7.
Программа получилась в целом несложной (после сокращения массивов точек):
first = [146,399,163,403,170,393,169,391,166,386,170,381,170,371,170,355,169,346,167,335,170,329,170,320,170, …
second = [156,141,165,135,169,131,176,130,187,134,191,140,191,146,186,150,179,155,175,157,168,157,163,157,159, …
import Image, ImageDraw
img = Image.new('RGB', (640,480))
draw = ImageDraw.Draw(img)
draw.line(first)
draw.line(second)
img.show()После изучения картинки, и вспоминания курса английского языка, я получил URL следующего уровня.
Продолжение следует.

2 коментарі
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.