前面关卡的结题报告在这里http://blog.csdn.net/richytang/article/details/12257467(第4-5关)
第6关:http://www.pythonchallenge.com/pc/def/channel.html
这关的名字叫:now there are the pairs。关内只有一张图片,是拉链。源代码里只有第一行是有用的信息。一个注释,是zip。
这关真是让我开始的时候毫无头绪。后来在网上了解到,注释放在第一行,让你用zip替换url中的html。于是我们便获得了一个channel.zip的压缩包...(感觉智商瞬间不够了)。好了,下载下来那个zip文件了,我们先看一下文件内容是什么吧:一堆数字.txt的文件+一个readme文件。read给了两个暗示,一个是从90052开始;另一个是:答案在zip里。那么第一个暗示的文件看一下,发现时类似之前的一关的东西:next nothing is xxxx。第二个暗示,会不会是使用zipfile模块的意思?(这里明显不是指python的zip函数)。别着急像那关那样先做下去,我们先看一下zip模块是什么吧。
zip模块主要用来做zip格式的压缩、解压缩和处理的。简单地说,就是讲zip文件作为一个文件处理就好,管它是不是zip。不过这些信息显然没法更进一步地帮助我们,我们还是先按照那关那样做下去:
nothing = '90052'
while True:
try:
fp = open('channel/'+nothing+'.txt','r')
text = fp.read()
nothing = text.split()[-1]
print(nothing)
fp.close()
except FileNotFoundError:
print(text,'you need to try manually',sep = '\n')
break
最后一个输出是:Collect the comments。这是什么?
详查了一下python3的zipfile模块。发现我们处理的这个文件要用ZipFile这个类。这个类都有些什么呢?help一下:
>>> import zipfile
>>> help(zipfile.ZipFile)
Help on class ZipFile in module zipfile:
class ZipFile(builtins.object)
| Class with methods to open, read, write, close, list zip files.
|
| z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False)
|
| file: Either the path to the file, or a file-like object.
| If it is a path, the file will be opened and closed by ZipFile.
| mode: The mode can be either read "r", write "w" or append "a".
......//省略
Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| comment
| The comment text associated with the ZIP file.
瞧,终于看到了想找的东西了(这个过程都是泪啊)。那么怎么获得这个comment呢?
>>> help(zipfile.ZipFile.getinfo)
Help on function getinfo in module zipfile:
getinfo(self, name)
Return the instance of ZipInfo given 'name'.
name是文件名。那么对每一个文件调用一次就可以了。当然,要按照nothing的顺序调。下面就是代码了:
import zipfile as zf
zfp = zf.ZipFile('channel.zip')
nothing = '90052'
li = []
while True:
try:
fp = zfp.open(nothing+'.txt','r')
text = fp.read().decode()
nothing = text.split()[-1]
li.append(zfp.getinfo(nothing+'.txt').comment.decode())
fp.close()
except KeyError:
print('It"s time to check manually',sep = '\n')
break
print(''.join(li))
上面的代码值得一说的地方除了zipfile本身的一些函数(这些help就可以了),就是decode()函数。这个函数是讲二进制(即python的bytes类型)转换成str类型。默认参数是'utf-8',可不给。这与py2k是有极大的不同的,编码与解码也是python3的一个高级话题。
运行结果一目了然,hockey。把url替换一下成:http://www.pythonchallenge.com/pc/def/hockey.html。跳转给出的是让你看看字母。再一看,输出中,每个字母一个个小字母组成的,是oxygen。篇幅问题,这里不给出结果图了。那么下一关,进入!
第7关:http://www.pythonchallenge.com/pc/def/oxygen.html
靠,这关...题目:自作聪明的人。关卡只有一个图片,源代码中没有任何提示。图片上有点文章,一个灰条:
看来只能处理图片了。先用GIMP查看这个图片。得到一些很有用的信息:
整张图片是629x95的像素;那条灰色带是y方向43-53,x方向0-609。
然后查了一下python第三方处理图片的库(特别是针对py3k的)。网上给出PIL的比较多。去官网,看到PIL更新到支持python2.x就不更新了。后来还是找到了牛人们编译的支持python3.3.2版本的PIL的exe文件,链接https://pypi.python.org/pypi?name=Pillow&version=2.2.1&:action=files。老规矩,导入包之后,help一下,发现open函数会有用。还有一点,这条线的y方向的该值是一样的(颜色相同)。那么我们在y方向用getpixel()方法的43-53之间随便一条采样试试:
from PIL import Image
img = Image.open('oxygen.png')
data = [img.getpixel((i,43)) for i in range(0,609)]
print(data)
输出结果我们看到了一些端倪:每一个像素点是一个四元组,前三个值是相同的,最后一个是255。后来才知道这是RGBA模式,不管了。还有一点是我很久才发现的,每七个是一个循环,假设单拿出R值看,每七个会有一个不同(应了这关的数:第7关)。那么就按照7个一处理,并且只取四元组中的第一个值。得到了一堆不同的数值。这时候另外一个提示,ascii码是255个,那个正好与这些RGBA的值岂不是完美对应?那就将这些值当做ascii码处理,并合并成字符串:
from PIL import Image
img = Image.open('oxygen.png')
data = [chr(img.getpixel((i,50))[0]) for i in range(0,609,7)]
print(''.join(data))
输出是:
smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]
那么我们接近答案了。在最后把这些ascii转化一下:
source = [105, 110, 116, 101, 103, 114, 105, 116, 121]
print(''.join([chr(i) for i in source]))
答案是integrity。好了,恐怖的一关终于结束了。第7关就这么难,那么以后不敢想象啊...
下一关的链接:http://www.pythonchallenge.com/pc/def/integrity.html