码迷,mamicode.com
首页 > 编程语言 > 详细

PythonChallenge_3

时间:2016-04-25 06:43:35      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:

PythonChallenge_3

一、实验说明

1. 环境登录

无需密码自动登录,系统用户名shiyanlou

2. 环境介绍

本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面上的程序:

  1. LX终端(LXTerminal): Linux命令行终端,打开后会进入Bash环境,可以使用Linux命令
  2. Firefox:浏览器,可以用在需要前端界面的课程里,只需要打开环境里写的HTML/JS页面即可
  3. GVim:非常好用的编辑器,最简单的用法可以参考课程Vim编辑器

3. 环境使用

使用GVim编辑器输入实验所需的代码及文件,使用LX终端(LXTerminal)运行所需命令进行操作。

完成实验后可以点击桌面上方的“实验截图”保存并分享实验结果到微博,向好友展示自己的学习进度。实验楼提供后台系统截图,可以真实有效证明您已经完成了实验。

实验记录页面可以在“我的主页”中查看,其中含有每次实验的截图及笔记,以及每次实验的有效学习时间(指的是在实验桌面内操作的时间,如果没有操作,系统会记录为发呆时间)。这些都是您学习的真实性证明。

二、课程介绍

本次PythonChallenge系列一共有11个项目,持续更新中~~~,每个项目课程里面会详细讲解3个pythonchallenge通关题目以及不同解决方案,课后习题里面布置一个任务题,该题目会在下一个项目中被揭开面纱。

本系列题目属于在线闯关题,由于实验楼暂时不提供访问外网,因此请各位验证答案的时候烦劳点击自己的浏览器访问网页以验证答案。

所有题目和参考的解决方案版权归PythonChallenge官网,课程编写属于实验楼原创,欢迎在问答区积极提问,小编会积极解答,也欢迎在评论区吐槽~

三、实验回顾

在上一个项目课中,我们学到了很多知识,比如:re模块中的一些函数,urllib模块的使用以及函数reduce。记性不算太差的你们估计还记得在上一次的课程中小编有留给大家一个课后作业,不知道你们完成的怎样呢?

不管是否得到答案,让小编带着你一起解决这个问题吧!

四、作业题解析

技术分享

问题:请访问挑战题链接查看源代码,找到通往下一个网址的链接。(提示:与zip有关)

小编脑洞:

首先查看源代码:

技术分享

经过这几次题目的摸索,我们知道一般答案都是隐藏在注释里面的(<!-- -->的内容)。首先第一个注释是单词zip,第二个注释稍微比较长,大致的意思是:下面的内容与谜语本身无关,只希望大家能够给pythonchallenge这个项目提供一点资助。那么,第二个注释就没有什么作用。再看第一个注释,只有一个单词zip,那么答案就是zip了,因此修改链接为:http://www.pythonchallenge.com/pc/def/zip.html。得到这样的结果:

技术分享

意思是:找到了zip,那么zip应该就隐藏在源代码中:

技术分享

源码中并没有给予什么信息,那么是不是zip指的是zip压缩包呢?再次返回修改原链接,将html换成zip,结果真是一个压缩包,关于这个压缩包,已经上传至实验楼环境,因此输入以下命令下载文件并查看压缩包内容:

$ wget http://labfile.oss.aliyuncs.com/courses/411/channel.zip
$ unzip -l channel.zip

文件内容如下:

技术分享

一共有910个文件,大多数文件的命名都是数字型,解压并查看说明文档readme.txt

$ unzip channel.zip  
$ vi readme.txt

技术分享

根据上面的提示,我们了解到两个信息:

  1. 循环是从90052.txt这个文件开始;
  2. 答案就隐藏在zip压缩包文件夹的内容中。

查看90052.txt这个文档内容如下:

技术分享

看到这句话的时候,你是不是觉得似曾相识?是的,在上一个挑战项目中也出现过这么一句话,区别在于上一次的题目是使用urllib模块在网页上寻找关键字,这一次是在压缩包内寻找答案。

算法如下:

  1. 设置初识起点,进入循环,使用正则表达式匹配文件内容中的数字;
  2. 将文件内容中的数字作为下一个被打开的文件名;
  3. 循环条件是找到不是以数字结尾的文件并打印结果
import re

findnothing = re.compile(r‘Next nothing is (\d+)‘).match
seed =‘90052‘
while True:
    fname = seed + ‘.txt‘
    text = open(fname, ‘r‘).read()
    m = findnothing(text)
    if m:
        seed = m.group(1)
    else:
        print text
        break

打印结果如下:

技术分享

意思是让我们收集注释。

关于注释,每一个文件都有它的描述信息,可以通过输入命令查看压缩包内的文件的描述信息:

unzip -l channel.zip

技术分享

上图给出每个文件的四个信息,比如reame.txt文件,它的注释信息就是*,该文件的大小为84字节,该文件的最后修改时间是2005-04-28,文件名为readme.txt。将这些注释信息连接起来就可以看看结果能不能告诉我们信息。

Python中有一个关于收集压缩包信息的模块zipfile,该模块的详细说明文档见官方文档。 该模块中有一个类需要我们了解——zipfile.ZipFile。该模块主要用于读写zip类型的文件。该类里面有一个函数getinfo(name)用于返回压缩文件中命名为name的文件信息,由于本次示例里面需要用到文件信息里面的解释部分,因此直接调用zipfile.ZipFile.getinfo(name).comment就可以返回name文件的注释。

因此修改代码如下:

import zipfile, re
findnothing = re.compile(r"Next nothing is (\d+)").match
comments = []  # 收集注释信息的列表
z = zipfile.ZipFile("channel.zip", "r")  # 读取压缩包文件
seed = "90052"
while True:
    fname = seed + ".txt"
    comments.append(z.getinfo(fname).comment)
    guts = z.read(fname)
    m = findnothing(guts)
    if m:
        seed = m.group(1)
    else:
        break
print "".join(comments)  # 打印所有注释信息

技术分享

那么答案应该就是hockey了,转到该链接:

技术分享

然后提示让我们看一下字母,并且提示该单词指的是存在于空气中。上面组成HOCKEY的图中恰好是由字母O C Y G E N组成,也就是单词空气——oxygen

因此来到下一题

五、第七个挑战题

技术分享

问题:根据这副图片找到通往下一个链接的单词。

小编脑洞:

然而这一次源代码中并没有提供额外的信息,那么只能看图,仔细观察上图,发现这个图并不完整,图的中间被一条不同深度的灰度长条给掩盖,那么信息很可能就隐藏在这里面。那么图像处理中我们知道每一个图片都是由无数个像素值组成,实际上就是一个像素构成的矩阵,那么答案很可能与这些像素值有关。关于这个问题的具体思路,有兴趣的朋友可以看一下我的博客

首先下载用于处理图像的Image模块,然后下载本题所需要处理到的图片oxygen.png

$ sudo apt-get install python-imaging
$ wget http://labfile.oss.aliyuncs.com/courses/411/oxygen.png

输入以下代码观察图片的大小:

import Image
img = Image.open(‘oxygen.png‘)  
img.size

技术分享

img.size的返回结果可知,该图片的水平方向和垂直方向上每英寸长度上的像素分别为62995;利用画图工具可将这段马赛克区域的坐标提取出来:

横坐标的范围是:0-609,纵坐标的范围是:43-53

然后利用Image模块里面的函数getpixel获得这一区域的像素数据:

# 列表表达式
data = [img.getpixel((i, j)) for i in range(0, 609) for j in range(43, 53)]
print data

观察打印的结果,你会发现输出的像素列表是一个4元组,其中元组的前三个元素分别对应相应的RGB分量:rgb,并且由于灰色满足条件是r=g=b,且观察到元组每重复7次变化一次,那么如何将这些输出结果与答案联系?

一般情况下,答案的链接都是英文字母,那么可以尝试把这些数值转化为经过函数chr将这些ASCII码转换为相应的英文字母。

# 先选取印第45行的所有像素信息
row = [chr(img.getpixel((i, 43))[0]) for i in range(0, 609, 7)]
"".join(row)

技术分享

上图给的那句话的意思是下一关的答案是[105,110,116,101,103,114,,105,116,121]。好说,将这些ASCII码转为字母,并连接成字符串:

技术分享

通往下一关的单词是integrity,因此转到下一关链接

七、第八个挑战题

技术分享

问题:找到消失的链接

小编脑洞:找到消失的链接?那么通关口应该不是简单的单词替换而是一个超链接,看看源代码是否有我们需要的信息:

技术分享,我们注意到在center/img中有一个属性usemapnotisect,关于notisect的描述在\map\area下面有描述,也就是说这是interity这个图里面的链接,关于coords的内容是图片的某一区域,该区域指向一个链接@href=‘../return/good/html‘点击图片弹出如下对话框(更多关于img标签的usemap属性介绍请查看文档):

技术分享

也就是说我们需要在原网页中找到用户名和密码才能登陆该身份验证。

再次观察源代码中的注释部分,发现:

技术分享

如果把un(username)后面的字符串解释为用户名,那么pw(password)里面的字符串就是密码。

那么这些字符串应该如何解码呢?仔细观察字符串的组成形式,无论是用户名还是密码都是BZ开头的字符串,后来了解到BZ开始的字符串实际上是被bz2压缩后的一种格式,那么如何解压呢?首先导入该模块,然后输入dir(bz2)查看bz2模块的函数:

技术分享

compress压缩函数,那么decompress就是解压函数,继续查看函数用法:

技术分享

由于我们的字符串比较少,因此可以使用函数decompress(data)解压数据:

import bz2
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‘
bz2.decompress(un)
bz2.decompress(pw)

技术分享

得到用户名为huge,密码为file,其实这个问题很简单,只要了解到BZ这种格式的字符串是一种压缩形式,然后进行相应的解压就可以解决问题。

八、任务

技术分享

问题:请把点连接起来,题目链接(提示:源代码,源代码!)。

PythonChallenge_3

标签:

原文地址:http://www.cnblogs.com/stevenray/p/5429188.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!