Ross Wan's World!

Python, Ajax, PHP and Linux.

Posts Tagged ‘the python challenge’

The Python Challenge Lv.10

Posted by Ross Wan 于 2011/09/08

Lv.10

利用第8关的账号和密码进入第10关, 显示是一张黄牛的图片, bull? 图片下面是一个 Python 语句:

len(a[30]) = ?

将鼠标放在牛的身上, 原来是一个链接, 点击打开, 显示一个未完的列表:

a = [1, 11, 21, 1211, 111221,

看来这题的题目就是根据那个未完的列表提示, 推测 a[30] 的长度.

再看看那个未完的列表有什么规律:

a[0] = ‘1’
a[1] = ’11’ 每两个字符拆分理解为: 1个’1′ 等于 a[0]
a[2] = ’21’ 每两个拆分理解为: 1个’2′ 等于 a[1]
a[3] = ‘1211’ 每两个拆分理解为: 1个’2′ + 2个’1′ 等于 a[2]
a[4] = ‘111221’ 第两个字符拆分理解为: 1个’1′ + 1个’2′ + 2个’1′ 等于 a[3]

规律出来了, 剩下的可以交给 Python :)

import re

def repl(match_obj):
    return '%s%s' % (len(match_obj.group()), match_obj.groups()[0])

if __name__ == '__main__':
    a = '1'
    reg = re.compile(r'(\d)\1*')
    for i in range(30):
        a = reg.sub(repl, a)
    print('a[30] = %s\n' % a)
    print('len(a[30]) = %d' % len(a))

可知, len(a[30]) 的答案是5808. 下一关的网址就是: http://www.pythonchallenge.com/pc/return/5808.html

Have fun~~

Advertisements

Posted in Python | Tagged: , , , | Leave a Comment »

The Python Challenge Lv.9

Posted by Ross Wan 于 2011/09/07

Lv.9

利用第8关得到的账号和密码成功进入第9关, 显示一幅河岸的图片, 图片上有若干黑点, 网页没有其它文字提示. 再看看网页的标题, “connect the dots”???难道是将图片上的黑点连接起来?

先别帮着动手, 看看网页的源代码吧, 毕竟以往的经验说明提示经常出现在网页源代码里:) 果然, 网页源代码的注释里出现两组数字—-first 和 second, 而且提示 “first+second”. 再回看标题”connect the dots”, 难道是将这些数字代表的坐标点连接起来?? 利用 PIL 的 ImageDraw 进行画图:

from PIL import Image, ImageDraw

first_points = (    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,310,171,301,173,290,178,289,182,287,188,286,190,286,192,291,194,296,195,305,194,307,191,312,190,316,190,321,192,331,193,338,196,341,197,346,199,352,198,360,197,366,197,373,196,380,197,383,196,387,192,389,191,392,190,396,189,400,194,401,201,402,208,403,213,402,216,401,219,397,219,393,216,390,215,385,215,379,213,373,213,365,212,360,210,353,210,347,212,338,213,329,214,319,215,311,215,306,216,296,218,290,221,283,225,282,233,284,238,287,243,290,250,291,255,294,261,293,265,291,271,291,273,289,278,287,279,285,281,280,284,278,284,276,287,277,289,283,291,286,294,291,296,295,299,300,301,304,304,320,305,327,306,332,307,341,306,349,303,354,301,364,301,371,297,375,292,384,291,386,302,393,324,391,333,387,328,375,329,367,329,353,330,341,331,328,336,319,338,310,341,304,341,285,341,278,343,269,344,262,346,259,346,251,349,259,349,264,349,273,349,280,349,288,349,295,349,298,354,293,356,286,354,279,352,268,352,257,351,249,350,234,351,211,352,197,354,185,353,171,351,154,348,147,342,137,339,132,330,122,327,120,314,116,304,117,293,118,284,118,281,122,275,128,265,129,257,131,244,133,239,134,228,136,221,137,214,138,209,135,201,132,192,130,184,131,175,129,170,131,159,134,157,134,160,130,170,125,176,114,176,102,173,103,172,108,171,111,163,115,156,116,149,117,142,116,136,115,129,115,124,115,120,115,115,117,113,120,109,122,102,122,100,121,95,121,89,115,87,110,82,109,84,118,89,123,93,129,100,130,108,132,110,133,110,136,107,138,105,140,95,138,86,141,79,149,77,155,81,162,90,165,97,167,99,171,109,171,107,161,111,156,113,170,115,185,118,208,117,223,121,239,128,251,133,259,136,266,139,276,143,290,148,310,151,332,155,348,156,353,153,366,149,379,147,394,146,399
)
second_points = (    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,157,158,164,159,175,159,181,157,191,154,197,153,205,153,210,152,212,147,215,146,218,143,220,132,220,125,217,119,209,116,196,115,185,114,172,114,167,112,161,109,165,107,170,99,171,97,167,89,164,81,162,77,155,81,148,87,140,96,138,105,141,110,136,111,126,113,129,118,117,128,114,137,115,146,114,155,115,158,121,157,128,156,134,157,136,156,136
)

if __name__ == '__main__':
    img = Image.new('RGBA', (500,500))
    draw = ImageDraw.Draw(img)
    draw.polygon(first_points)
    draw.polygon(second_points)
    img.save('good_ok.jpg')

打开生成的图片 good_ok.jpg, 明显看到那些点连接起来是一头牛, cow? 于是尝试打开http://www.pythonchallenge.com/pc/return/cow.html,显示:

hmm. it’s a male.

呵呵,原来是头公牛—-bull, 于是成功得到下一关的网址: http://www.pythonchallenge.com/pc/return/bull.html

Have fun~~

Posted in Python | Tagged: , , , | 1 Comment »

The Python Challenge Lv.8

Posted by Ross Wan 于 2011/09/01

Lv.8

一打开第8关的网页, 显示的是一张蜜蜂辛勤(Working hard)采花图片, 将鼠标放在蜜蜂上, 发现蜜蜂的区域是一个链接: http://www.pythonchallenge.com/pc/return/good.html
打开那链接,发觉是需账号认证才能打开的. 用户名是和密码是什么呢? 将网页退后到第8关的网页, 查看其源代码, 发现了二行特别的注释:

un: 'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw: 'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'

看来, 将上面的注释解密就行了. 留意那两行注释, 都是以”BZh91AY&SY”开头的,还有图片是蜜蜂?Bee?猜想是不是用 bz2 加密的呢? 立即试试:

import bz2

if __name__ == '__main__':
    un = b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
    pw = b'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'
    print('Username: %s' % bz2.decompress(un).decode('ascii'))
    print('Password: %s' % bz2.decompress(pw).decode('ascii'))

通往下一关: http://www.pythonchallenge.com/pc/return/good.html 的用户名是huge, 密码是file.

Have fun:)

Posted in Python | Tagged: , , | 2 Comments »

The Python Challenge Lv.7

Posted by Ross Wan 于 2011/08/31

Lv.7


打开网页,显示的是一张河岸的图片, 特别的是, 图片中央有一细条”灰色带”.将图片另存为”oxygen.png”, 用图片编辑器打开, 放大到最大的倍数.可以看到,那色带是一长方形的灰度色带(left: 0px, top: 43px, right: 607px, bottom: 51px), 它又是由大小为7px * 9px的小长方形灰度块(除了第1块是 5px * 9px)组成的. 灰度的值是0~255, 正好跟 Ascii 相对应, 思路出来了, 下面交给 Python 来处理:

from PIL import Image

if __name__ == '__main__':
    img = Image.open('oxygen.png')
    for p in range(4, 607, 7):
        print(chr(int(sum(img.getpixel((p,43))[:3])/3)), end='')
    print()


注意, 处理图片需要用到 PIL 库, Python 3的 Windows 编译版可以到以下网址下载: http://www.lfd.uci.edu/~gohlke/pythonlibs/#pil


运行结果:

smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]


可知要对 “[105, 110, 116, 101, 103, 114, 105, 116, 121]”进行映射就得到答案了;现将上面的代码改写,一次性的得到答案:)

from PIL import Image
import re

if __name__ == '__main__':
    img = Image.open('oxygen.png')
    map_string = ''.join(map(lambda p: chr(int(sum(img.getpixel((p, 43))[:3])/3)), range(4, 607, 7)))
    #print(map_string)
    print('\nKey Words: ', end='')
    for i in re.finditer(r'\d+', map_string):
        print(chr(int(i.group())), end='')
    else:
        print()


显示结果:

Key Words: integrity

可知下一关的网址是: http://www.pythonchallenge.com/pc/def/integrity.html

Have fun :)

Posted in Python | Tagged: , , , | Leave a Comment »

The Python Challenge Lv.6

Posted by Ross Wan 于 2011/08/25

Lv.6

打开第6关的网页,显示的是一张裤拉链的图片,”拉链”???第一时间,猜想到的是 Python 的 zip 内建方法、zipfile 内建模块,还有就是 zip 格式的文件。

查看网页的源文件,没什么可疑,尝试将网址最后的“html”改为“zip”,下载到“channel.zip”这个压缩文件 :) 用 7-zip 解压缩,发现里面有910个文本文件,一个 readme.txt 文件:

welcome to my zipped list.

hint1: start from 90052
hint2: answer is inside the zip

其它文件的内容大致如下:

Next nothing is xxxxx

这有点像第4关。先验证下那些文件的内容是否一致,是否有一个特殊的(或者答案就直接在那文件里呢):

import re, os

if __name__ == '__main__':
    for filename in os.listdir('channel'):
        filepath = os.path.join('channel', filename)
        if os.path.isfile(filepath) and re.match(r'^\d+\.txt', filename):
            f = open(filepath)
            content = f.read()
            f.close()
            if not re.match(r'^Next nothing is \d+', content):
                print('File: %s\nContent: %s' % (filename, content))

显示如下内容:

File: 46145.txt
Content: Collect the comments.

发现 “46145.txt”文件的内容是不一样的。“注释”?再用 z-zip 打开 channel.zip 这个压缩文件,查看其注释栏,的确压缩包里的部分文件是带注释的。再结合 readme.txt 文件的提示,将注释按顺序打印出来:

#!bin/python3
# coding=utf8

import re, zipfile

if __name__ == '__main__':
    target = '90052'
    z = zipfile.ZipFile('channel.zip')
    while 1:
        target_file = '%s.txt' % target
        print(z.getinfo(target_file).comment.decode('ascii'), end='')
        f = z.open(target_file)
        match_obj = re.match(r'^Next nothing is (\d+)',f.read().decode('ascii'))
        f.close()
        if match_obj:
            target = match_obj.groups()[0]
        else:
            break
    z.close()

显示如下图案:

****************************************************************
****************************************************************
**                                                            **
**   OO    OO    XX      YYYY    GG    GG  EEEEEE NN      NN  **
**   OO    OO  XXXXXX   YYYYYY   GG   GG   EEEEEE  NN    NN   **
**   OO    OO XXX  XXX YYY   YY  GG GG     EE       NN  NN    **
**   OOOOOOOO XX    XX YY        GGG       EEEEE     NNNN     **
**   OOOOOOOO XX    XX YY        GGG       EEEEE      NN      **
**   OO    OO XXX  XXX YYY   YY  GG GG     EE         NN      **
**   OO    OO  XXXXXX   YYYYYY   GG   GG   EEEEEE     NN      **
**   OO    OO    XX      YYYY    GG    GG  EEEEEE     NN      **
**                                                            **
****************************************************************
 **************************************************************

显而易见,下一关的网址正是:http://www.pythonchallenge.com/pc/def/hockey.html

且慢,别高兴太早~~~打开上面的网址,显示:

it’s in the air. look at the letters.

“这仍然是个谜,注意那些字母”,原来谜还未解完呢,留意“HOCKEY”各由什么字母组成——oxygey。答案终于出来了: http://www.pythonchallenge.com/pc/def/oxygen.html

Have fun :)

Posted in Python | Tagged: , , | Leave a Comment »

The Python Challenge Lv.5

Posted by Ross Wan 于 2011/08/24

Lv.5

打开第5关的网页,显示的是一个山丘的图片,提示”pronounce it”???完全没有头绪.再看看网页的源代码,发现一个”可疑”的标签:

<peakhell src=”banner.p”/>

下载到 banner.p 这个文件,用文本编辑器打开,又是一堆字符,似有似无规律的字符.再看看网页源代码里的一行注释:

<!– peak hell sounds familiar ? –>

peak hell 的发音似什么?完全没有头绪……最后,Google到一点提示,确是无奈之举:< 原来关键是 pickle,它的发音跟 ‘peak hell’ 有点相似.真是晕倒~~~既然有这个关键的提示,下面就容易得多了:

import pickle

if __name__ == '__main__':
    f = open('banner.p', 'rb')
    obj = pickle.load(f)
    print('Objcet type: %s\n\n' %type(obj))
    print(obj)
    f.close()

首先,取得的对象是一个 list,而list的元素是由二元表列组成,而且,二元表列的第一个元素是” “或者”#”,第二个元素是数字.可猜测这是一个打印列表:

import pickle

if __name__ == '__main__':
    f = open('banner.p', 'rb')
    obj = pickle.load(f)
    f.close()
    new_file = open('new_file.txt', 'w')
    for line in obj:
        new_file.write(''.join([x*y for x,y in line]))
        new_file.write('\n')
    new_file.close()

上面的代码会将打印的字符写入 “new_file.txt” 这个文件里,不直接显示在系统 console 里主要是因为因某些 console 会自动断行,而显示不到最终的结果.

用编辑器打开(记得关闭编辑器的自动换行),会出现一个漂亮的图形,结果显而易见:

                                                                                              
              #####                                                                      #####
               ####                                                                       ####
               ####                                                                       ####
               ####                                                                       ####
               ####                                                                       ####
               ####                                                                       ####
               ####                                                                       ####
               ####                                                                       ####
      ###      ####   ###         ###       #####   ###    #####   ###          ###       ####
   ###   ##    #### #######     ##  ###      #### #######   #### #######     ###  ###     ####
  ###     ###  #####    ####   ###   ####    #####    ####  #####    ####   ###     ###   ####
 ###           ####     ####   ###    ###    ####     ####  ####     ####  ###      ####  ####
 ###           ####     ####          ###    ####     ####  ####     ####  ###       ###  ####
####           ####     ####     ##   ###    ####     ####  ####     #### ####       ###  ####
####           ####     ####   ##########    ####     ####  ####     #### ##############  ####
####           ####     ####  ###    ####    ####     ####  ####     #### ####            ####
####           ####     #### ####     ###    ####     ####  ####     #### ####            ####
 ###           ####     #### ####     ###    ####     ####  ####     ####  ###            ####
  ###      ##  ####     ####  ###    ####    ####     ####  ####     ####   ###      ##   ####
   ###    ##   ####     ####   ###########   ####     ####  ####     ####    ###    ##    ####
      ###     ######    #####    ##    #### ######    ###########    #####      ###      ######

可见,下一关的网址是: http://www.pythonchallenge.com/pc/def/channel.html

Have fun :)

Posted in Python, Uncategorized | Tagged: , , | Leave a Comment »

The Python Challenge Lv.4

Posted by Ross Wan 于 2011/08/22

Lv.4

打开第4关的网址,得到如下内容:

linkedlist.php

将网址改为 http://www.pythonchallenge.com/pc/def/linkedlist.php, 再打开,终于进入到第4关,看到一张”木偶锯木”的图片,点击它,进入到 http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345 页面显示:

and the next nothing is 44827

根据页面提示,将网址最后的nothing参数改为 44827, 打开http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=44827, 又得到提示:

and the next nothing is 45439

再改网址的nothing参数吧, http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=45439,这次终于得到稍有不同的提示了:

Your hands are getting tired and the next nothing is 94485

这算是安慰的说话吗?想一想,这样重复又重复的工作,不正是程序应做的事情吗?!

#!bin/python3
# coding=utf8

import re, urllib.request

if __name__ == '__main__':
    nothing = '94485'
    while 1:
        response = urllib.request.urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s' % nothing)
        content = response.read().decode('ascii')
        response.close()
        print(content)
        match_obj = re.match(r'^and the next nothing is (\d+)', content)
        if match_obj:
            nothing = match_obj.groups()[0]
        else:
            break

经过若干次抓取页面之后停住了,提示:

and the next nothing is 16044
Yes. Divide by two and keep going.

意思就是除2再继续,晕~~将上面脚本的 nothing 改为’8022’再次运行.不久,页面又停住了:

and the next nothing is 82682
There maybe misleading numbers in the
text. One example is 82683. Look only for the next nothing and the next nothing
is 63579

提示错误,要从63579再次运行,再次晕倒.那再将上面的脚本中的nothing改为’63579′

再次运行…

and the next nothing is 66831

peak.html

皇天不负有心人,都不知运行多长时间了,终于显示下一关的关键字,真是想哭呀~~~Lv.5:http://www.pythonchallenge.com/pc/def/peak.html

Have fun :~?

Posted in Python | Tagged: , , , | 1 Comment »

The Python Challenge Lv.3

Posted by Ross Wan 于 2011/08/20

Lv.3

One small letter, surrounded by EXACTLY three big bodyguards on each of its sides.

这关跟上一关一样,也是要解密网页源代码里的那一堆字符注释.根据上面的提示,要找出一些特殊的小写字母,它必须左右两边当且只有3个大字母,例如: bXXXaXXXc,字母a就符合要求.利用正则查找出这些字母来:

import re

if __name__ == '__main__':
    with open('mess.txt') as f:
        target_chars = []
        for line in f:
            target_chars.extend(re.findall(r'(?<=[^A-Z][A-Z]{3})[a-z](?=[A-Z]{3}[^A-Z])', '^'+line))
        target = ''.join(target_chars)
        print('Target characters: %s' % target)
        print('Next url: http://www.pythonchallenge.com/pc/def/%s.html' % target)
        f.close()

‘^’+line 在每行开头加上字符”^”(或者其它非大写字母),是为了让正则表达式匹配这个特殊情况,就是行字符串开头如这样:XXXaXXXb…,如果不在行开头加上一个非大写字符,上面的正则表达式是配置不到a字符的.

另外,在论坛区里,有人贴出这样的正则表达式:

r'([^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z]’

但它会漏掉一些应匹配的小写字符,例如: ‘aXXXbXXXcXXXd’, 上面的正则表达式只匹配到’b’,没有匹配到’c’!(虽然对于本关,它一样可以得出正确的结果 :<)

运行脚本,得到如下结果:

Target characters: linkedlist

Next url: http://www.pythonchallenge.com/pc/def/linkedlist.html

得到下一关的网址: http://www.pythonchallenge.com/pc/def/linkedlist.html

Have fun :>

Posted in Python, Uncategorized | Tagged: , , | Leave a Comment »

The Python Challenge Lv.2

Posted by Ross Wan 于 2011/08/19

Lv.2

recognize the characters. maybe they are in the book, but MAYBE they are in the page source.

上面是第2关的提示.看看这网页的源代码,就知道究竟什么回事.网面源码最后有一大段的注释,一堆的标点符号.提示说”recognize the characters”,就是说这堆标点符号里有有意义的字母,推理方向对了就行.下面是 Python 代码,用正则的方式查找字母出来:

import re

if __name__ == '__main__':
    with open('mess1.txt') as f:
        mess = f.read()
        f.close()
        target = ''.join(re.findall(r'[a-zA-Z0-9]', mess, re.S))
        print('Target characters: %s' % target)
        print('Next url: http://www.pythonchallenge.com/pc/def/%s.html' % target)

mess.txt 是那源代码标点符号注释复制下来保存的文件.下面是输出结果:

Target characters: equality
Next url: http://www.pythonchallenge.com/pc/def/equality.html

可见,下一关的网址就是 http://www.pythonchallenge.com/pc/def/equality.html


Have fun :)

Posted in Python | Tagged: , , , | Leave a Comment »

The Python Challenge Lv.1

Posted by Ross Wan 于 2011/08/18

Lv.1

根据图片:

K->M

O->Q

E->G

可以猜到规律,就是将字母右移2位进行影射解密.字符影射翻译,Python str本身就提供了这方法: translate.

import string

mess = “””g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr’q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj. “””

translation = mess.translate(str.maketrans(string.ascii_letters, string.ascii_lowercase[2:]+’ab’+string.ascii_uppercase[2:]+’AB’))

print(translation)

得到以下译文:

“i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that’s why this text is so long. using string.maketrans() is recommended. now apply on the url. “

根据译文的提示,对网页的 url 进行上面的字符影射翻译:

map -> ocr

得到下一关地址:

http://www.pythonchallenge.com/pc/def/ocr.html

Python 字符串提供的 translate 是相当方便的,假如不用这内置的方法,也是有很多办法解决的,毕竟这是有规律的字符影射:

for char in mess:
    print(ord(‘a’)<=ord(char)<=ord(‘z’) and chr((ord(char)+2-ord(‘a’))%26+ord(‘a’)) or char, end=”)

:) 这样这可以打印出上面的译文.

Have fun~~

Posted in Python, Uncategorized | Tagged: , , , | Leave a Comment »