[Level 27]

Title: between the tables
圖片鏈向的地址即是下一關(guān)的url,但是需要用戶名和密碼。從源碼提示did you say gif?下載到zigzag.gif。查看了圖片的各屬性,沒有頭緒。
或許我們先要知道什么是 [palette] [p1],嗯,[調(diào)色板] [p2],或者[更詳細(xì)的調(diào)色板] [p3]。
[p1]: https://en.wikipedia.org/wiki/Palette_(computing)
[p2]: https://zh.wikipedia.org/wiki/BMP#.E8.B0.83.E8.89.B2.E6.9D.BF
[p3]: http://www.360doc.com/content/10/0928/15/2790922_57060786.shtml
調(diào)色板相當(dāng)于建立了顏色索引,我們要把它們還原顏色。
from PIL import Image
img = Image.open('zigzag.gif')
data = img.tobytes()
p = img.getpalette()[::3]
table = bytes.maketrans(bytes([i for i in range(256)]),bytes(p))
trans = data.translate(table)
對齊轉(zhuǎn)換前后的數(shù)據(jù),找出不同:
zipped = list(zip(data[1:],trans[:-1]))
indices = [i for i,p in enumerate(zipped) if p[0]!=p[1]]
new = Image.new(img.mode,img.size)
color = [255,]*len(data)
for i in indices:
color[i] = 0
new.putdata(color)
new.show()
顯示:

not 和 word,中間有一把鑰匙-key。然而并不是下一關(guān)的鑰匙?!安煌苯M成的信息呢?
import bz2
import keyword
diff = [p[0] for p in zipped if p[0]!=p[1]]
text = bz2.decompress(bytes(diff)).decode()
print(set(i for i in text.split() if not keyword.iskeyword(i)))
打印出:
{'switch', 'repeat', 'exec', 'print', '../ring/bell.html'}
repeat 和 switch 才是用戶名和密碼,[Level 28]
小結(jié)
或者這樣找diff:
diff = list(filter(lambda p: p[0] != p[1], zipped))
- [
Image.getpalette()] [s1] 返回調(diào)色板列表數(shù)據(jù)。 - [
enumerate(iterable, start=0)] [s2] 將可迭代對象做成索引序列。 - [
zip()] [s3] 接受可迭代對象,將對應(yīng)的元素打包再組成新的可迭代對象。 - [
keyword.iskeyword(s)] [s4] 判斷s是否是 python 關(guān)鍵字。在python3中,exec和print不再是關(guān)鍵字。
[s1]: https://pillow.readthedocs.io/en/4.0.x/reference/Image.html#PIL.Image.Image.getpalette
[s2]: https://docs.python.org/3/library/functions.html#enumerate
[s3]: https://docs.python.org/3/library/functions.html#zip
[s4]: https://docs.python.org/3/library/keyword.html#keyword.iskeyword