您的位置:首页 > 编程语言 > Python开发

Python Challenge(6--7关)——我的解题报告(running with python3.x)

2013-10-04 23:31 609 查看
前面关卡的结题报告在这里/article/9546268.html(第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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: