前面關卡的結題報告在這裡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 zfzfp = 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') breakprint(''.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 Imageimg = 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 Imageimg = 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