PythonChallenge过关斩将录-0~10关

说明: http://www.pythonchallenge.com/

pythonchallenge是在学习openstack的时候,介绍python语言时推荐的一个游戏解密网站,自己看了一下,有些问题还是很有难度的,有时候在家里搞搞,有时候午休时间在公司搞搞,记录自己过关斩将的历程~~仅供娱乐。


0. 第0关 http://www.pythonchallenge.com/pc/def/0.html

其实我没注意到这个2^38, 第一眼看到提示语,说试试修改url,于是我把0改成1,访问:http://www.pythonchallenge.com/pc/def/1.html,网页提示: 2**38 is much much larger.

   OK,用python计算2**38 =274877906944

   访问http://www.pythonchallenge.com/pc/def/274877906944.html 进入第1关


1. 第1关:http://www.pythonchallenge.com/pc/def/map.html


一眼看出来K-L-M, O-P-Q, E-F-G,每个字母后面第二个字母,写段代码,将这行紫色的字母都换成后面第二个字母。
#-------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:      Administrator
#
# Created:     17/09/2015
# Copyright:   (c) Administrator 2015
# Licence:     <your licence>
#-------------------------------------------------------------------------------
import string


def main():
    in_characters = "abcdefghijklmnopqrstuvwxyz"
    out_characters = "cdefghijklmnopqrstuvwxyzab"
    transtab = string.maketrans(in_characters, out_characters)
    print "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.".translate(transtab)
    pass


if __name__ == '__main__':
    main()
输出结果:

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上,下一关地址就是:http://www.pythonchallenge.com/pc/def/ocr.html

2. 第二关:http://www.pythonchallenge.com/pc/def/ocr.html

第一感觉是看橙色的提示,说是在page source里,右击页面,查看页面源代码, 看到下面这段隐藏文字:


说找到这堆符号中,少有的字母,python一下:
import string

def main():    a = """%%$@_$^__#)^)&!_+]!*@&^}@[@%]()%+$&[(_@%+%$*^@$^!+]!&_#)_*}{}}!}_]$[%}@[{_@#_^{*@##&{#&{&)*%(]{{([*}@[@&]+!!*{)!}{%+{))])[!^})+)$]#{*+^((@^@}$[**$&^{$!@#$%)!@(&...下面省略,太长了"""    for c in a:

        if c in string.ascii_letters:

            print c,

    print ""

    pass


if __name__ == '__main__':   
   main()

输出结果:

e q u a l i t y

试试http://www.pythonchallenge.com/pc/def/equality.html 进入第三关

3. 第3关:http://www.pythonchallenge.com/pc/def/equality.html


好吧, 这个题目完全是考我可怜的英语水平啊,surrounded by EXACTLY three big bodyguards on each of its sides, 再看看蜡烛,我想应该是一个小写字母,左边和右边都正好有3个大写字母,不多不少。
那字符串在哪里呢?从第2关的经验猜,查看页面源代码,可以看到这样的隐藏字符串:

直接上python:
import string

import sys


def main():

    a="""kAewtloYgcFQaJNhHVGxXDiQmzjfcpYbzxlWrVcqsmUbCunkfxZWDZjUZMiGqhRRiUvGmYmvnJIHEmbT

MUKLECKdCthezSYBpIElRnZugFAxDRtQPpyeCBgBfaRVvvguRXLvkAdLOeCKxsDUvBBCwdpMMWmuELeGENihrpCLhujoBqPRDPvfzcwadMMMbkmkzCCzoTPfbRlzBqMblmxTxNniNoCufprWXxgHZpldkoLCrHJq。。。下面省略,太TM长了"""

    lines = a.splitlines()


    c = 80

    r = 1250

    arr = []


    for i in range(0, r):

        for j in range(3, c-3):

            count = 0

            m = lines[i][j]


            if m in string.ascii_lowercase:

                for l in range(j - 3, j + 4):

                    if lines[i][l] in string.ascii_uppercase:

                        count = count + 1

                    if j - 4 >= 0:

                        if lines[i][j-4] in string.ascii_uppercase:

                            count = count + 1

                    if j + 4 < c:

                        if lines[i][j+4] in string.ascii_uppercase:

                            count = count + 1


            if count==6:

                arr.append(m)

    print ''.join(arr)


    pass


if __name__ == '__main__':   
    main()

输出结果:

linkedlist
访问http://www.pythonchallenge.com/pc/def/linkedlist.html,提示linkedlist.php, 访问http://www.pythonchallenge.com/pc/def/linkedlist.php,进入第四关

4. 第4关http://www.pythonchallenge.com/pc/def/linkedlist.php

这个图片是个超链接,url是http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345,  返回 and the next nothing is 44827,继续访问http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=44827 ,继续返回 and the next nothing is 45439,好吧,我很傻的next好多次。。。受不了了,继续查看页面源代码


很明显了,用urlib去访问差不多400次?

上python:
import urllib2

def main():
    resp = urllib2.urlopen("http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=63579").read()
    t = 0
    while True:
        print t
        t = t+1
        print resp
        if t >= 400:
            break
        if resp.startswith("<font color=red>Your hands are getting tired </font>and the next nothing is "):
            resp = resp.replace("<font color=red>Your hands are getting tired </font>and the next nothing is ", "")
            resp = urllib2.urlopen("http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="+resp).read()
        elif resp.startswith("and the next nothing is "):
            resp = resp.replace("and the next nothing is ", "")
            resp = urllib2.urlopen("http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="+resp).read()
        else:
            print resp
            break



if __name__ == '__main__':
    main()
执行了109次,输出结果:

108

and the next nothing is 66831

109

peak.htmlpeak.html
 访问url: http://www.pythonchallenge.com/pc/def/peak.html,进入第五关

5. 第5关:http://www.pythonchallenge.com/pc/def/peak.html

看不懂。。。继续看页面源代码:

<html>

<head>

<title>peak hell</title>

<link rel="stylesheet" type="text/css" href="../style.css">

</head>

<body>

<center>

<img src="peakhell.jpg"/>

<br><font color="#c0c0ff">

pronounce it

<br>

<peakhell src="banner.p"/>

</body>

</html>

<!-- peak hell sounds familiar ? -->
有个banner.p,点一下看到下面的东西:

这么乱七八糟的,不过自己看一眼,p0,p1,p2,p3这些是不是很眼熟?非常典型的pickle.dumps(一个列表)的结果哈
啥也不说了,上python

import pickle

import urllib2

def main():

    a = urllib2.urlopen("http://www.pythonchallenge.com/pc/def/banner.p").readlines()

    data = pickle.loads(''.join(a))

    for r in data:

        result = ''

        for s in r:

            result = result + s[0]*s[1]

        print result


if __name__ == '__main__':   
    main()
输出结果:
下一关:http://www.pythonchallenge.com/pc/def/channel.html


6. 第6关:http://www.pythonchallenge.com/pc/def/channel.html

我承认一开始我的点偏了。。。就关注paypal的图标了,点了,就跳到paypal的页面。。。。哎。。。。

继续查看页面源代码,最上面有个这样的:
试试www.pythonchallenge.com/pc/def/channel.zip, 真的下载到一个zip文件!额,我居然不知道拉链就是zip的意思。。。。
解压缩,看到一堆数字文本文件,先看看readme.txt吧,里面提示:
welcome to my zipped list.


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

打开90052.txt文件,里面提示下一数字,答案就在zip文件中。。。兴奋了,高潮了,和第4关不是一样吗?
解压缩出来,上python:
def main():
    f = open("D:/channel/90052.txt")
    while True:
        content = f.read()

        if content.startswith("Next nothing is "):
            content = content.replace("Next nothing is ","")
            print content
            f = open("D:/channel/%s.txt" % content)
        else:
            break

    pass
输出结果太长,最后几行是:

68628

6782446145
打开46145.txt文件。提示:Collect the comments.
不行了。。hold不住啊,collect the comments是什么意思?zip文件中没有注释啊,我还把所有文件内容都爬了一遍,也没发现什么有价值的注释。

绝望了,放弃吧。。。偶然之间,在我的24寸显示器上,发现7zip界面上:(所以啊,程序员必须要有个大显示器!)
懂了,懂了,按照刚刚的文件顺序,把注释弄出来!
上python:
def test():
    f = open("D:/files.txt")
    z = zipfile.ZipFile("D:/channel.zip")
    comment_map = {}
    for filename in z.namelist():
        comment_map[filename] = z.getinfo(filename).comment
    arr = []
    for fn in f.readlines():
        fn = fn.replace("\n","")
        fn = fn+".txt"
        arr.append(comment_map[fn])
    print ''.join(arr)

输出结果:


yeah, 访问http://www.pythonchallenge.com/pc/def/hockey.html,提示 it's in the air. look at the letters.
我擦,咋这么多弯弯绕呢。。。在空气中,看看字母,hockey是由oxygen字母组成的,空气中。。。氧气~~

访问http://www.pythonchallenge.com/pc/def/oxygen.html,终于进入第7关

7. 第7关:http://www.pythonchallenge.com/pc/def/oxygen.html

 就这个图片,页面源代码也没什么营养,继续研究这个图片吧
一条小溪。。。中间这么明显一条灰带子~~是不是灰度值?

把文件下载下来,图片像素是629*95,大概41~55像素开始是这个灰色带子,用python读取第45行像素,输出结果
 上python:
from PIL import Image


def main():

    img = Image.open("D:/temp/oxygen.png")

    width = img.size[0]

    mark = -1

    for i in range(0,width):

        pix = img.getpixel((i,45))

        if mark != pix[0]:  #第一次发现很多像素都是一样的,然后去重,去重后当成是ascii码输出

            mark = pix[0]

            print chr(mark),

    pass


if __name__ == '__main__':    main()

输出结果:

s m a r t   g u y ,   y o u   m a d e   i t .   t h e   n e x t   l e v e l   i s   [ 1 0 5 ,   1 0 ,   1 6 ,   1 0 1 ,   1 0 3 ,   1 4 ,   1 0 5 ,   1 6 ,   1 2 1 ] { v } z ? ~ s r o d h k a e b ^ R X U

但是~~中括号里的是什么玩意?10,16这些也不是什么可见字符的ascii码啊,后面那串看上去像乱码的是什么鬼?仔细看图,那个灰色带子不是从左边到右边一直有的,所以最后的乱码应该是图片本身,忽略它。

中括号里是什么呢?猜猜看吧。。。
猜想一,105,101这些是ascii码,10,16这些是前面这些字母中的序号? 结果是:i,meguimy或者i aeg iay 一看就不对。。。
猜想二,105,101这些是ascii码,10,16这些是标准字母表中的字符位置?结果是ijpegnipy,一看也不像啊。。
都不对。。。蛋碎~~
额。。是我的代码有问题,我把连续重复的数字去掉了,10有可能是110,有可能是100。。。16有只能是116(因为166>128),那这个数组应该是:
[105,100,116,101,103,114,105,116,121] 或者 [105,110,116,101,103,114,105,116,121], 这两个数组分别是:idtegrity和integrity, 显然第二个是对的!

8. 第8关:http://www.pythonchallenge.com/pc/def/integrity.html


中间这个蜜蜂可点击,会弹出来用户名和密码,

这一关应该就是猜用户名和密码了?提示语是inflate,  解压缩?

继续查看页面源代码,一串数字,一串乱码:
上面coords看上去坐标的缩写,下面的BZh91A看上去像某种压缩算法,我知道bz2,gz等等很多算法,那个坐标的话到底是什么东西的坐标呢?烦不了了,先搜一下BZh9是什么吧。。。结果一百度。。。居然直接搜到了红黑联盟里这道题目的解法,而且直接在预览页上就有提示un是username,pw是password。。。蛋碎,眼瞎啊。。

不装X了,既然看到了就用了哦

import bz2

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'


def main():

       #username = bz2.decompress(un.decode("utf-8"))

        username=bz2.decompress(un)

        password=bz2.decompress(pw)

        print(username,password)


if __name__ == '__main__':   
       main()

输出结果:
('huge', 'file'),用户名huge, 密码file

9. 第9关:http://www.pythonchallenge.com/pc/return/good.html

一张图片,全是黑点,title是connect the dots,  把这些黑点连起来吗? 看看页面源代码吧,看到一大堆数字加上一小堆数字。。。first+second是啥意思是啊?

是数组相加吗?数组的数字个数也不相等啊,况且加完了以后得到一个大数组又能干嘛呢?这些数字显然不是ascii码了, 出题目的人应该是说英语的,也不可能用到unicode码,显示其他国家语言吧。。
再想想这个网页的title叫connect the dots,把点连接起来,那这些数字会不会是坐标?如果是平面坐标,first是横坐标?second是纵坐标?但是数量不一致啊,怎么组合成坐标?如果是相邻两个数字是一对坐标,第一个数组有442个数字,第二个数组有112个数字,都是偶数个,试试看吧。。
import wx
from wx.lib import plot

def makeCoords():
    data1 = [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]
    f = lambda A, n=2: [A[i:i+n] for i in range (0,len(A), n)]
    coords = f(data1)
    return coords

class MyFrame(wx.Frame):
    def __init__(self):
        self.frame1 = wx.Frame(None, title="wx.lib.plot", id=-1, size=(600, 400))
        self.panel1 = wx.Panel(self.frame1)
        
        if wx.VERSION[1] < 7:
            plotter = plot.PlotCanvas(self.panel1, size=(600, 400))
        else:    
            plotter = plot.PlotCanvas(self.panel1)
            plotter.SetInitialSize(size=(600, 400))
        plotter.SetEnableZoom(True)
        
        data = makeCoords()
        line = plot.PolyLine(data, colour='red', width=1)
        gc = plot.PlotGraphics([line], '', '', '')
        plotter.Draw(gc, xAxis=(0,600), yAxis=(0,400))
        
        self.frame1.Show(True)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    f = MyFrame()
    app.MainLoop()
输出结果:

额。。。我可以说我一眼就看出来是个倒过来的牛吗?
把数组换成第二个数组,结果是:

我勒个去。。这是什么?牛头? 我可以说这像个diao吗?

英文中牛的单词:cow,cattle,bull,一个个试过去,http://www.pythonchallenge.com/pc/return/bull.html是正确的,额。。其实cow的时候就提示公牛。。

看到下面这个牛的图。

问a数组的第31个元素的长度是多少?鼠标移到站的牛上,发现是个超链接,点击,看到这个:
a = [1, 11, 21, 1211, 111221,
显然就是问1,11,21,这样下去第31个数字的长度是多少了,这有什么规律?考公务员的同学可能非常熟悉这种题目,俺真的不晓得啊。。。百度一下,呵呵,发现百度作业居然有答案:http://www.zybang.com/question/cc2fd60fb68ca696ac3ae50fa976c7de.html
就是每个数字描述前面一个数字的组成,知道这个规律,上python:

def calculate(n):    a=[]

    a.append("1")

    for i in range(1, n):

        s=""

        temp_num = a[i-1][0]

        num_cnt = 1

        has_changed = False

        for j in range(1, len(a[i-1])):

            temp = a[i-1][j]

            if temp_num != temp:

                s=s+str(num_cnt)

                s=s+str(temp_num)

                temp_num = temp

                num_cnt = 1

            else:

                num_cnt += 1

        s=s+str(num_cnt)

        s=s+str(temp_num)

        a.append(s)

        print len(s),


def main():

    calculate(31)


if __name__ == '__main__':    main()
输出结果:

2 2 4 6 6 8 10 14 20 26 34 46 62 78 102 134 176 226 302 408 528 678 904 1182 1540 2012 2606 3410 4462 5808



---未完待续---

没有更多推荐了,返回首页