标签:
无需密码自动登录,系统用户名shiyanlou
本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面上的程序:
使用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
根据上面的提示,我们了解到两个信息:
90052.txt
这个文件开始;查看90052.txt
这个文档内容如下:
看到这句话的时候,你是不是觉得似曾相识?是的,在上一个挑战项目中也出现过这么一句话,区别在于上一次的题目是使用urllib
模块在网页上寻找关键字,这一次是在压缩包内寻找答案。
算法如下:
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
的返回结果可知,该图片的水平方向和垂直方向上每英寸长度上的像素分别为629
和95
;利用画图工具可将这段马赛克区域的坐标提取出来:
横坐标的范围是: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
分量:r
、g
、b
,并且由于灰色满足条件是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
中有一个属性usemap
为notisect
,关于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
这种格式的字符串是一种压缩形式,然后进行相应的解压就可以解决问题。
标签:
原文地址:http://www.cnblogs.com/stevenray/p/5429188.html