Commited: 50+ воркшопів з ТОПами тестування: M.Bolton, G.Bahmutov, T.King, R.Desyatnikov, J.Bach. Лише за $40 на рік та економія $15 до 20 квітня
×Закрыть

Вызов на 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 следующего уровня.

Продолжение следует.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

👍НравитсяПонравилось0
В избранноеВ избранном0
Подписаться на автора
LinkedIn

Похожие статьи




Підписуйтесь: iTunes | Google Podcast | YouTube


2 комментария

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

-100 від мене"Звичайний" переклад спойлера дворічної давності.

неправда абсолютно. я решал сам, и соответсвенно описал процесс решения. в ходе решения использовались хинты с форума.потому у меня по многоим задачам приведено 2 решения: мое и “референсное” решение с вики.тем более на том блоге описаны решения только первых 10 уровней, я продожаю дальше, и опубликую 3 часть после прохождения очередных 5 уровней.

Пропоную прибрати дані пости вони суперечать проханню самого pythonchallenge.com і принципам чесного змагу. Набагато цікавіше розв’язувати задачку самостійно

я для этого убрал под кат все с главной страницы. кто захочет, тот читать не будет... предупреждение я написал.

-100 від мене «Звичайний» переклад спойлера дворічної давності.http://gumuz.looze.net/wordpre.../http://gumuz.looze.net/wordpre.../Пропоную прибрати дані пости вони суперечать проханню самого pythonchallenge.com і принципам чесного змагу:). Набагато цікавіше розв’язувати задачку самостійно:) P.S. я свого часу тормознув на 22 рівні.

Подписаться на комментарии