Украинское сообщество программистов

Вызов на Python-игры (продолжение)

cleg
Опубликовано 7.05.2007 в Статьи

Первая часть.

Внимание! Прежде чем читать дальше, я настоятельно рекомендую всем попытаться справится с задачами самостоятельно. Опыт и полученное вами удовольствие будут несравненно выше.

Уровень 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 следующего уровня.

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

Теги: ,

1 звезда2 звезды3 звезды4 звезды5 звезд (2 голосов, средний: 5 из 5)
Загрузка ... Загрузка ...
Распределение голосов

Понравилась статья? Подпишись на обновления по RSS/E-mail

Подписаться, не оставляя комментарий

Все комментарии (2) к “Вызов на Python-игры (продолжение)” RSS

  1. chervol

    -100 від мене

    “Звичайний” переклад спойлера дворічної давності.
    http://gumuz.looze.net/wordpress/index.php/archives/2005/05/09/python-challenge-solutions-part-1/
    http://gumuz.looze.net/wordpress/index.php/archives/2005/05/20/python-challenge-solutions-part-2/

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

    P.S. я свого часу тормознув на 22 рівні.

  2. cleg

    -100 від мене

    “Звичайний” переклад спойлера дворічної давності.

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

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

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

Оставить комментарий

Указать свой сайт могут только зарегистрированные пользователи. Регистрация или вход.

Архив

Добавить статью

Станьте автором нашего сайта!

Какие материалы подходят для публикации? — Такие.

Присылайте статьи на editors@developers.org.ua.

Подробнее.

Популярные теги

Все теги

Комментарии

Последние комментарии