起始: pythonchallenge通关

尝试python很久了, 一开始checkio 仅仅是为了游戏, 好吧只不过是为了升级的愚蠢的快感

貌似对任何升级类的游戏不管什么内容都没有免疫力..#28

过了很久很久对checkio厌倦后发现这个又沉迷.

确实不错的东西. 简单记录下过程

获得技能无数这才是关键. 很多都是由答案推出来的过程, 或直接搜的答案

http://www.pythonchallenge.com/

 

0.

http://www.pythonchallenge.com/pc/def/0.html

显然图中提示2的28次方, 后html源码里的提示.

得到下个链接

http://www.pythonchallenge.com/pc/def/274877906944.html

访问后定位到

http://www.pythonchallenge.com/pc/def/map.html

从此一个大坑为你展开大门..

 

1.

http://www.pythonchallenge.com/pc/def/map.html

K --> N

O --> Q

E --> G

显然字母游戏,每个往后挪了2个, 姑且以为Y --> A Z-->B 吧.

查看网页源代码得到需要翻译的文本

"g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."

if __name__ == '__main__':
	text = '''g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq 
	ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q 
	ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() 
	gq pcamkkclbcb. lmu ynnjw ml rfc spj.'''
	outtext = ''
	for i in text:
		if str.isalpha(i):
			n = ord(i)
			if i >= 'y':
				n = ord(i) + 2 - 26
			else:
				n = ord(i) + 2
			outtext += chr(n)
		else:
			outtext += i
	print(outtext)

得到结果:

i hope you didnt translate it by hand. thats what computers
are for. doing it in by hand is inefficient and that's
why this text is so long. using string.maketrans()
is recommended. now apply on the url.

同规则 url中的map 会转成 ocr 得到新的url

http://www.pythonchallenge.com/pc/def/ocr.html

再看译文中的提示string.maketrans()

查查文档,并更新代码

import string

if __name__ == '__main__':
	text = '''g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq 
	ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q 
	ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() 
	gq pcamkkclbcb. lmu ynnjw ml rfc spj.'''

	t = str.maketrans(string.ascii_lowercase, string.ascii_lowercase[2:] + string.ascii_lowercase[0:2])
	out = text.translate(t) 
	print(out)

得到同样的结果

PS: get新技能  str.maketrans, text.translate

 

2.

http://www.pythonchallenge.com/pc/def/ocr.html

明显的提示你查看源码并获得提示

find rare characters in the mess below:

然后一段乱七八糟的字符.

 

if __name__ == '__main__':
        text = ''' .... ''' 
	s = {}
	for i in text:
		n = s.get(i, 0) + 1
		s[i] = n
	l = list(s.values())
	l.sort()
	print(l)

	slist = []
	for i in text:
		if s[i] == 1:
			slist += [i]
	print(slist)

得到答案equality

即第三关

http://www.pythonchallenge.com/pc/def/equality.html

回顾头来, 源代码写的太丑, 看了下标准写法

http://wiki.pythonchallenge.com/index.php?title=Level2:Main_Page

不过没发现太好的标准写法院里差不多, 就不纠结了

 

3.

http://www.pythonchallenge.com/pc/def/equality.html

同样得到提示:

One small letter, surrounded by EXACTLY three big bodyguards on
each of its sides.

再加上标题, re, 明显是py的正则库 re

import re

if __name__ == '__main__':
	text = ''' ... '''
	out = re.findall("[a-z][A-Z]{3}([a-z]{1})[A-Z]{3}[a-z]", text)
	print("".join(out))

得到答案 linkedlist

第四关

http://www.pythonchallenge.com/pc/def/linkedlist.html

通用回过头看下参考解法

http://wiki.pythonchallenge.com/index.php?title=Level3:Main_Page

对于正则这东西, 永远都一知半解所以也就不研究过深继续下一个

 

4

http://www.pythonchallenge.com/pc/def/linkedlist.html

访问会提示,html换成php 所以得到真正正确的4关url

http://www.pythonchallenge.com/pc/def/linkedlist.php

 

提示:

linkedlist.php?nothing=12345 和

urllib may help. DON'T TRY ALL NOTHINGS, since it will never
end. 400 times is more than enough.

访问

http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345

会得到一个新的nothing值

and the next nothing is 44827

import urllib.request
import re

if __name__ == '__main__':
	nothing = '12345'
	url = 'http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing='
	for i in range(0, 400):
		f = urllib.request.urlopen(url + nothing)
		s = f.read(-1)
		nothing = "".join(re.findall("[0-9]{1,}", s.decode()))
		print(s.decode())

一直打印的过程中会有提示

http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=16044

Yes. Divide by two and keep going.

停止程序, 新的值设成8022 继续重新跑.

到了

http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=82682

又给提示

There maybe misleading numbers in the text. One example is 82683. Look only for the next nothing and the next nothing is 63579

奇怪我第一次跑的时候就直接得到的答案这会儿各种奇怪的提示 囧...

继续代入, 重新跑

最终得到答案peak.html

得到5关

http://www.pythonchallenge.com/pc/def/peak.html

整理下新技能:

urllib.request.urlopen

 

5

http://www.pythonchallenge.com/pc/def/peak.html

有2个提示

banner.p,  title的peak

这关开始小脑袋已经驾驭不住, 只能各种googel,

pickle是python的序列化库

http://www.pythonchallenge.com/pc/def/banner.p的内容解出来

import urllib.request
import pickle

if __name__ == '__main__':
	f = urllib.request.urlopen("http://www.pythonchallenge.com/pc/def/banner.p")
	s = pickle.load(f)
	print(s)

会得到一个list对象.再按顺序把字符打出来

	for x in s:
		text = ""
		for y in x:
			for z in range(0, y[1]):
				text += y[0]
		print(text)

得到提示 channel

测试结果得到6关

 

6

http://www.pythonchallenge.com/pc/def/channel.html

切到源码页第一行得到提示 zip

访问http://www.pythonchallenge.com/pc/def/channel.zip 

会得到一个压缩包channel.zip   解压后会发现n个文件

里面有个readme

welcome to my zipped list.

hint1: start from 90052
hint2: answer is inside the zip

明目张胆的hint是必须要牢牢记住的.打开90052

发现是和4关一样的套路

import re

if __name__ == '__main__':
	path = "90052"
	while True:
		f = open("./channel/" + path + ".txt", "r")
		text = f.read(100)
		path = "".join(re.findall("[0-9]{1,}", text))
		print(text)
		if path == "":
			break

最终 得到提示 Collect the comments.

介于之前提示,答案在zip文件里. 所以收集zip文件的comments

import re
import zipfile

if __name__ == '__main__':
	path = "90052"
	ordfile = []
	while True:
		f = open("./channel/" + path + ".txt", "r")
		text = f.read(100)
		path = "".join(re.findall("[0-9]{1,}", text))
		print(text)
		if path == "":
			break
		ordfile += [path + ".txt"]

	z = zipfile.ZipFile("./channel.zip")
	print(ordfile)
	nextkey = ""
	for i in ordfile:
		nextkey += z.getinfo(i).comment.decode()
	print(nextkey)

得到下一关提示hockey

http://www.pythonchallenge.com/pc/def/hockey.html

访问之后发现得到新提示

it's in the air. look at the letters.

好吧, 这玩意云里雾里, 各种搜索之后发现, 其实是说的空气 oxygen

新技能: zipfile

7

http://www.pythonchallenge.com/pc/def/oxygen.html

进入后, 会得到一张图, 并且明显看出中间一条灰色的部分

看源代码也没有新的提示

那就看看灰色部分是神马东西吧

会引用的新的python库, PIL

python3 上叫 PILLOW 安装后, 搜点文档就可以使用

新技能: PilLow

from PIL import Image

if __name__ == '__main__':
	I = Image.open("oxygen.png")
	text = ""
	for i in range(0, 629, 7):
		pix = I.getpixel((i, 48))
		text += chr(pix[0])
	print(text)
	#smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]
	l = [105, 110, 116, 101, 103, 114, 105, 116, 121]
	text = ""
	for i in l:
		text += chr(i)
	print(text)

得到提示 integrity

http://www.pythonchallenge.com/pc/def/integrity.html

 

8

http://www.pythonchallenge.com/pc/def/integrity.html

第八关, 一组数组, 一个不知什么格式的username和password

BZ开头

新技能:bz2

import bz2

if __name__ == '__main__':
	print(bz2.decompress(b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084') )
	print(bz2.decompress(b'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08') )

得到 huge/file 点击入9关

http://www.pythonchallenge.com/pc/return/good.html

咦? 9关? 那些数组是干嘛用的.... 不知道 继续往下

留坑..-----------

袄..其实那些数组是可点区域 囧.. 安心到下关.

--------

 

9

http://www.pythonchallenge.com/pc/return/good.html

huge, file

给了个提示

first+second=?

嗯.....

伟大的googel告诉了我答案, 把这些点连起来就是一个画

from PIL import ImageDraw 
from PIL import Image

if __name__ == '__main__':
	first = [146,399,163,403,170,393,169,391,166,386,170,381,170,371,170,355,169,346,167,335,170,329,170,320,170,
310,171,301,173,290,178,289,182,287,188,286,190,286,192,291,194,296,195,305,194,307,191,312,190,316,
190,321,192,331,193,338,196,341,197,346,199,352,198,360,197,366,197,373,196,380,197,383,196,387,192,
389,191,392,190,396,189,400,194,401,201,402,208,403,213,402,216,401,219,397,219,393,216,390,215,385,
215,379,213,373,213,365,212,360,210,353,210,347,212,338,213,329,214,319,215,311,215,306,216,296,218,
290,221,283,225,282,233,284,238,287,243,290,250,291,255,294,261,293,265,291,271,291,273,289,278,287,
279,285,281,280,284,278,284,276,287,277,289,283,291,286,294,291,296,295,299,300,301,304,304,320,305,
327,306,332,307,341,306,349,303,354,301,364,301,371,297,375,292,384,291,386,302,393,324,391,333,387,
328,375,329,367,329,353,330,341,331,328,336,319,338,310,341,304,341,285,341,278,343,269,344,262,346,
259,346,251,349,259,349,264,349,273,349,280,349,288,349,295,349,298,354,293,356,286,354,279,352,268,
352,257,351,249,350,234,351,211,352,197,354,185,353,171,351,154,348,147,342,137,339,132,330,122,327,
120,314,116,304,117,293,118,284,118,281,122,275,128,265,129,257,131,244,133,239,134,228,136,221,137,
214,138,209,135,201,132,192,130,184,131,175,129,170,131,159,134,157,134,160,130,170,125,176,114,176,
102,173,103,172,108,171,111,163,115,156,116,149,117,142,116,136,115,129,115,124,115,120,115,115,117,
113,120,109,122,102,122,100,121,95,121,89,115,87,110,82,109,84,118,89,123,93,129,100,130,108,132,110,
133,110,136,107,138,105,140,95,138,86,141,79,149,77,155,81,162,90,165,97,167,99,171,109,171,107,161,
111,156,113,170,115,185,118,208,117,223,121,239,128,251,133,259,136,266,139,276,143,290,148,310,151,
332,155,348,156,353,153,366,149,379,147,394,146,399]
	second = [156,141,165,135,169,131,176,130,187,134,191,140,191,146,186,150,179,155,175,157,168,157,163,157,159,
157,158,164,159,175,159,181,157,191,154,197,153,205,153,210,152,212,147,215,146,218,143,220,132,220,
125,217,119,209,116,196,115,185,114,172,114,167,112,161,109,165,107,170,99,171,97,167,89,164,81,162,
77,155,81,148,87,140,96,138,105,141,110,136,111,126,113,129,118,117,128,114,137,115,146,114,155,115,
158,121,157,128,156,134,157,136,156,136]

	new_image = Image.new('RGB', (640,480))
	draw = ImageDraw.Draw(new_image) 

	draw.line(first, fill='#fff')
	draw.line(second, fill='#fff')  
	new_image.save("next.jpg")

得出一个牛的图片 牛? cow?

http://www.pythonchallenge.com/pc/return/cow.html

点进去后告诉你是公的.bull?

得到第十关

 

10

http://www.pythonchallenge.com/pc/return/bull.html

len(a[30]) = ?

有提示

a = [1, 11, 21, 1211, 111221,

喔... 这个....

往下不废话, 因为都是googel的. 囧...

规律是

1

1一个1   11

2个1      21

一个2一个1        1211

 

...

if __name__ == '__main__':
	text = "1"
	index = 1
	while index < 32:
		index += 1
		tmp = ""
		a = ""
		b = 0
		for i in text:
			if a == "":
				a = i
				b = 1
			elif a == i:
				b += 1
			else:
				tmp += str(b) + a
				a = i
				b = 1
		tmp += str(b) + a

		print(index, len(tmp), tmp)
		text = tmp

所以得到答案5808

 

11

http://www.pythonchallenge.com/pc/return/5808.html

呀..阴深恐怖的图是干嘛的...

仔细看挺模糊,又重影的样子 又根据title odd even奇偶?

分离出来

from PIL import Image

if __name__ == '__main__':
	I = Image.open("cave.jpg")

	i1 = Image.new("RGB", (320,240))
	i2 = Image.new("RGB", (320,240))

	for i in range(0, 320):
		for j in range(0, 240):
			p1 = I.getpixel((i * 2, j * 2))
			i1.putpixel((i,j), p1)
			p2 = I.getpixel((i * 2 + 1, j * 2 + 1))
			i2.putpixel((i,j), p2)
	i1.save("i1.jpg")
	i2.save("i2.jpg")

模糊的看出evil字样.. 但是图太模糊.. 喔.. 难道用错了.. 好吧其实都挺模糊

 

12

http://www.pythonchallenge.com/pc/return/evil.html

按提示...

http://www.pythonchallenge.com/pc/return/evil1.jpg

http://www.pythonchallenge.com/pc/return/evil2.jpg

http://www.pythonchallenge.com/pc/return/evil3.jpg

http://www.pythonchallenge.com/pc/return/evil4.jpg 用ie打开, 得到提示

Bert is evil! go back!

http://www.pythonchallenge.com/pc/return/evil2.gfx

 

得到evil2.gfx文件

伟大的googel告诉我们开头的第一张图提示你这东西要分5份......

if __name__ == '__main__':
	f = open("evil2.gfx", "rb")
	a = f.read(-1)

	for i in range(0, 5):  
	    f = open('level12.'  + str(i) + ".jpg", 'wb')  
	    f.write(a[i::5])  
	    f.close()

得到5张图,

内容分别是 dis pro  port ional ity

得到下关

http://www.pythonchallenge.com/pc/return/disproportional.html

 

13

http://www.pythonchallenge.com/pc/return/disproportional.html

点击链接到

http://www.pythonchallenge.com/pc/phonebook.php

新技能: xmlrpc

import xmlrpc.client

if __name__ == '__main__':

	proxy = xmlrpc.client.ServerProxy("http://www.pythonchallenge.com/pc/phonebook.php")
	print(proxy)
	print(proxy.system.listMethods())
	print(proxy.phone("Bert"))

得到提示555-ITALY

各种尝试之后得

http://www.pythonchallenge.com/pc/return/ITALY.html

 

14

http://www.pythonchallenge.com/pc/return/italy.html

 

甜甜圈, 及提示<!-- remember: 100*100 = (100+99+99+98) + (... -->

按提示把100X100的图片wire.png 重新摆

 

from PIL import Image

if __name__ == '__main__':
	y = Image.new("RGB", (100,100))
	wire = Image.open("wire.png")
	print(wire)
	cursor = 0
	direct = [(1,0),(0,1),(-1,0),(0, -1)] 
	px, py, z = -1, 0, 0
	for i in range(200):
		d = direct[i % 4]
		for j in range(100 - (i+1) //2):
			px += d[0]
			py += d[1]
			y.putpixel((px,py), wire.getpixel((z,0)))
			z += 1

	y.save("what.jpg")

得到一张猫的图片(上面是googel抄的代码, 实在摆不明白)

进入http://www.pythonchallenge.com/pc/return/cat.html 得到提示

and its name is uzi. you'll hear from him later.

进入第15关

 

15

http://www.pythonchallenge.com/pc/return/uzi.html

有2个提示

<!-- he ain't the youngest, he is the second -->

<!-- todo: buy flowers for tomorrow -->

看日期, 明天是什么日子?  貌似是闰年, 1XX6年,

百度结果 1756年—奥地利作曲家莫扎特诞辰(1791年逝世)。 喔...

(以上推理来着googel)

 

16

http://www.pythonchallenge.com/pc/return/mozart.html

一张图和提示

let me get this straight

from PIL import Image

if __name__ == '__main__':
	# p = Image.open("mozart.gif")
	# t = p.resize((640 * 8, 480))
	# t.save("1.gif")

	im=Image.open("mozart.gif")

	def straighten(line): # 找到第一个粉红色像素,然后以它为开头,左对齐
	    i=0
	    while line[i]!=195:
	        i+=1
	    return line[i:]+line[:i]

	for h in range(im.size[1]):
	    line=[im.getpixel((w,h)) for w in range(im.size[0])]
	    line=straighten(line)
	    [im.putpixel((w,h),line[w]) for w in range(im.size[0])]

	im.save('16.gif')

以上抄来的代码, 不知道咋推理出来的.. 得到新图提示有

romance

 

17

http://www.pythonchallenge.com/pc/return/romance.html

提示是 一张第四关的图和cookie

重新跑过去第四关, 查cookie看

得到提示 nothing 换成 busynothong

按提示 一步步跳页面并同时看cookie

bzh91....

似曾相识.bz2库

import urllib.request
import urllib.parse
import re
import bz2

if __name__ == '__main__':
    nothing = "12345"
    url = 'http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing='
    info = ""
    for i in range(0, 4000):
        f = urllib.request.urlopen(url + nothing)
        s = f.read(-1).decode('utf_8')
        nothing = "".join(re.findall("[0-9]{2,}", s))

        print(i, s)
        text = f.getheader('Set-Cookie')
        t = re.findall("info=(.+?);", text)
        info += t[0] 
        if nothing == "":
            break
    print(info)

得到一串bz...  但都是百分号开头的, 好理解是urlencode,

中间有个插曲, 上面代码得到的info内容里是有一个+号的.

虽然找到相关函数urllib.parse.unquote_plus, 但没想出怎么正确使用, 

最后还是把+号手动改成%20, 然后才能得到争取结果, 不然一直报出无效数据

    info = "BZh91AY%26SY%94%3A%E2I%00%00%21%19%80P%81%11%00%AFg%9E%A0%20%00hE%3DM%B5%23%D0%D4%D1%E2%8D%06%A9%FA%26S%D4%D3%21%A1%EAi7h%9B%9A%2B%BF%60%22%C5WX%E1%ADL%80%E8V%3C%C6%A8%DBH%2632%18%A8x%01%08%21%8DS%0B%C8%AF%96KO%CA2%B0%F1%BD%1Du%A0%86%05%92s%B0%92%C4Bc%F1w%24S%85%09%09C%AE%24%90"
    #print(info)
    #out = urllib.parse.unquote(''.join(info))
    #print(out)
    #out = urllib.parse.unquote_plus("".join(info))
    out = urllib.parse.unquote_to_bytes(info)
    print(out)
    t = bz2.BZ2Decompressor().decompress(out)
    print(t)

得到提示

b'is it the 26th already? call his father and inform him that "the flowers are on their way". he\'ll understand.'

有点抓狂, 这个关到底要牵扯多少东西啊..

联想到15关, mozart的爸爸?

googel得知是Leopold

call? 联想到13关

    proxy = xmlrpc.client.ServerProxy("http://www.pythonchallenge.com/pc/phonebook.php")
    print(proxy)
    print(proxy.system.listMethods())
    print(proxy.phone("Leopold"))

得到提示

555-VIOLIN

 

继续..

http://www.pythonchallenge.com/pc/return/violin.html

起初输入大写,结果显示页面不存在改成小写后能打开页面得到提示

no! i mean yes! but ../stuff/violin.php.

进入

http://www.pythonchallenge.com/pc/stuff/violin.php

 

进去后, 一张图片, title是

it's me. what do you want?

啊啊啊啊啊啊啊啊啊啊啊! 闹哪样!!!!!!!!

我也不知道要干嘛

记得之前的提示

the flowers are on their way

带cookie访问

    next = 'http://www.pythonchallenge.com/pc/stuff/violin.php'

    cookie = http.cookiejar.CookieJar();
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie));
    urllib.request.install_opener(opener)

    request = urllib.request.Request(next)
    request.add_header('Cookie','info=the flowers are on their way')
    f = urllib.request.urlopen(request)
    print(f.read(-1))

新技能: 带cookie访问url

得到提示:

oh well, don't you dare to forget the balloons.

尝试:http://www.pythonchallenge.com/pc/return/balloons.html

 

18

http://www.pythonchallenge.com/pc/return/balloons.html

2个提示:

can you tell the difference?

it is more obvious that what you might think

按照提示, 我首先是把2部分图相减的, 但没得到什么有用的

googel告诉我 左边图,比右边亮.访问

http://www.pythonchallenge.com/pc/return/brightness.html

囧....

得到提示

maybe consider deltas.gz

访问

http://www.pythonchallenge.com/pc/return/deltas.gz

得到一个gz包.

里面有个txt文件

89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00   89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00
02 8a 00 00 00 c8 08 02 00 00 00 e0 19 57 95 00 00 00   02 8a 00 00 00 c8 08 02 00 00 00 e0 19 57 95 00 00 00
09 70 48 59 73 00 00 0b 13 00 00 0b 13 01 00 9a 9c 18   09 70 48 59 73 00 00 0b 13 00 00 0b 13 01 00 9a 9c 18
00 00 00 07 74 49 4d 45 07 d5 05 07 0c 18 32 98 c6 a0   00 00 00 07 74 49 4d 45 07 d5 05 07 0c 18 32 98 c6 a0
48 00 00 00 1d 74 45 58 74 43 6f 6d 6d 65 6e 74 00 43   48 00 00 00 1d 74 45 58 74 43 6f 6d 6d 65 6e 74 00 43
72 65 61 74 65 64 20 77 69 74 68 20 54 68 65 20 47 49   72 65 61 74 65 64 20 77 69 74 68 20 54 68 65 20 47 49
4d 50 ef 64 25 6e 00 00 20 00 49 44 41 54 78 da ec bd   4d 50 ef 64 25 6e 00 00 20 00 49 44 41 54 78 da ec bd
57 93 9c 47 92 25 7a 3c c4 a7 53 55 96 42 01 20 9b 6c   57 93 9c 47 92 25 7a 3c c4 a7 53 55 96 42 01 20 9b 6c
31 b3 63 bb 4f fb ff 1f ee d3 bd 2f d7 ae d9 8e d8 e9   31 b3 63 bb 4f fb ff 1f ee d3 bd 2f d7 ae d9 8e d8 e9
ee 69 92 0d 5d ba b2 52 7d 22 22 fc 3e 78 e6 c7 6a 28   ee 69 92 0d 5d ba b2 52 7d 22 22 fc 3e 78 e6 c7 6a 28
42 16 0a d8 38 06 a3 91 00 58 55 f9 89 70 f7 e3 c7 8f   42 16 0a d8 38 06 a3 91 00 58 55 f9 89 70 f7 e3 c7 8f
03 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   03 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11   11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
9f 0f 14 2f 41 44 44 44 c4 87 41 41 19 d8 04 a9 81 01   9f 0f 14 2f 41 44 44 44 c4 87 41 41 19 d8 04 a9 81 01 ...

(新技能, 但貌似用处不大, 除非哪天被机器人劫持.. 囧...)传说中 每个png图的文件头都是

89 50 4E 47 0D 0A 1A 0A

搜整个文件, 有4个以这个开头的, 难道是4个png图? 囧..

多方尝试,包裹googel,baidu, 由答案推出过程如下

首先这个文件明显是2大部分, 左右各一个

先用代码把这2部分分出来

	f = open("delta.txt")
	buf = f.read(-1)

        lines = buf.split('\n')
	pairs = [(l[:53], l[56:]) for l in lines]
	columns = ['\n'.join([p[i] for p in pairs]) for i in range(2)]

得到 2个部分

columns[0],columns[1]

用代码写到文件然后用比较工具比较,再加上一些诡异的推理得出

2边相同部分 是一个png头开头的, 少的部分,和多的部分各个都是由新的png头开头

所以猜测,这3部分都是一张图

新技能  difflib

	column_diffs = list(difflib.Differ().compare(columns[0].splitlines(), columns[1].splitlines()))
	pngs = [''.join(filter(lambda l: l[0] == d, column_diffs)) for d in " -+"]

得到pngs 这东西是3部分.

再用2进制方式写进文件

	for i in range(0, len(pngs)):
		png_l = re.findall("[a-z0-9]{2}", "".join(pngs[i]))
		f = open("18out" + str(i+1) + ".png", "wb")
		for j in range(0, len(png_l)):
			f.write(struct.pack("=B", int(png_l[j], 16)))

得到3个图片并得到提示

../hex/bin.html, fly, butter

一个是url, 另2个是登陆名和密码

 

19

http://www.pythonchallenge.com/pc/hex/bin.html

butter, fly

得到提示:

It is so much easier for you, youngsters.
Maybe my computer is out of order.
I have a real work to do and I must know what's inside!

--===============1295515792==
Content-type: audio/x-wav; name="indian.wav"
Content-transfer-encoding: base64

UklGRvyzAQBXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YdizAQBABkAMQAtAAEADQAJA
BEAEQAJAAkAGQAVABUAEQApAC0AJQAhAD0APQANADUAFQAVAD0AEQA5ADUAGQAlAAj8PQAVABkAE
QAJACUAFQAQ/CkAKQAg/BEAMQAo/AEABQANABEAAPw1ADEAOPwZADkAHPwBADj8OQAhABT8IQARA
AD8FQAQ/Dz8AQA8/BEAGQAQ/DkAIQBA/B0AMQAU/BEAOPwo/DkAMPw1AC0AFPwhAC0AIQA0/AD8J
Pwo/Cz8IPwc/AT8HPwE/DkACPwdAD0AOPwNAB0APPw8/B0AEQAk/CD8FPwo/DUADPww/DUALPwZA
DkAMPwI/DkAGQA8/DT8IPwFACEAEPwo/Cj8OPwRACD8BPwI/BT8CQAg/BT4LPwNAAEADQAdACj8L
...

猜测, 那堆base64码其实是一个wav文件

import base64

if __name__ == '__main__':
	text = '''
UklGRvyzAQBXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YdizAQBABkAMQAtAAEADQAJA
...
'''
	s = base64.b64decode(text)
	f = open("c19.wav", "wb")
	f.write(s)
	f.close()

得到音频, 再放播放器播放,听到sorry的声音

访问

http://www.pythonchallenge.com/pc/hex/sorry.html

得到提示

- "what are you apologizing for?"

靠!!!!!!!!!!!!!!!!!! 啊啊啊!!!!!!!!!!!!!!

再看原格式, 是一个邮件格式.

发邮件难道?

我用自己邮箱发过去,得到回复

Never mind that.
Have you found my broken zip?
md5: bbb8b499a0eef99b52c7f13f4e78c24b
Can you believe what one mistake can lead to?

这.. 又云里雾里

	iw = wave.open('c19.wav', 'rb')

	params=iw.getparams()

	iw2 = wave.open('india2.wav','wb')
	iw2.setparams(params)

	for i in range(iw.getnframes()):
		iw2.writeframes(iw.readframes(1)[::-1])

 

 据说, 查看wav文件的data部分, 可以发现有多余的部分, 然后经过某某处理得到新音频听到声音再唱歌, 念叨的是 

you are an idiot!

...........

.....

20

http://www.pythonchallenge.com/pc/hex/idiot.html

转入之后

只有一行提示

but inspecting it carefully is allowed.

import http.client
import base64
import re
import zipfile
import zlib

def get_range(page, base, limit):
	conn = http.client.HTTPConnection('www.pythonchallenge.com')
	strBasic = 'Basic ' + base64.b64encode(b'butter:fly').decode()
	strRange = 'bytes=' + str(base) + '-' + str(limit)  + '/' + str(500)
	headers = {'Authorization': strBasic, 'Range': strRange}
	conn.request('GET', page, '', headers)
	return conn.getresponse()

def next_range(base):
	r = get_range('/pc/hex/unreal.jpg', base, 2123456789)
	print(base)
	print(r.read())
	rge = r.getheader('Content-Range')
	print(rge)
	if not rge:
		return 0
	t = re.findall("-([0-9]{1,})", rge)
	if not t:
		return 0
	return int(t[0])

if __name__ == '__main__':
	next = 30203
	while True:
		next = next_range(next) + 1
		if next == 1:
			break

	r = get_range('/pc/hex/unreal.jpg', 2123456789, pow(2,31))
	print(r.read()[::-1])
	print ('invader'[::-1])
	print(r.getheaders())

	r1 = get_range('/pc/hex/unreal.jpg', 2123456743, '')
	print(r1.read())

	data = get_range('/pc/hex/unreal.jpg', 1152983631, '').read()
	print(data)
	f = open('1.zip', 'wb')
	f.write(data)
	f.close()

完全是抄的.

一步步执行才明白提示中的含义

大体是这样,

打开图片的时候,会有http头信息, 包含range

不断尝试新range,然后带http头访问地址会得到新的range和头

最终会得到一段pk开头的2进制

pk开头的2进制 是zip格式, 存成zip文件打开得到21关

 

21关

打开上一个关得到zip包 有2个文件

readme.txt

package.pack

-----------------------

readme.txt

 

Yes! This is really level 21 in here. 
And yes, After you solve it, you'll be in level 22!

Now for the level:

* We used to play this game when we were kids
* When I had no idea what to do, I looked backwards.

 

显然这是提示, 名堂在pack文件里到但看不出...

用2进制方式打开pack文件看到头2个字节是78 9c

据说这是用zlib压缩过才会有这个头

发现是多次压缩过的..

import zlib
import bz2

if __name__ == '__main__':
	f = open('package.pack', "rb").read()
	while f[0:2] == b'\x78\x9c':
		f = zlib.decompress(f)
	print(f)

然后居然得到bz开头的2禁制串... 又是个压缩. 稍稍整理下

import zlib
import bz2

if __name__ == '__main__':
	f = open('package.pack', "rb").read()

	while True:
		if f[0:2] == b'\x78\x9c':
			f = zlib.decompress(f)
		elif f[0:2] == b'BZ':
			f = bz2.decompress(f)
		else:
			break
	print(f)

最终得到一个2进制串..

b'\x80\x8d\x96\xcb\xb5r\xa7\x00\x06Xz\xdafO\x19\xe...

还记得提示里,

When I had no idea what to do, I looked backwards.

看结尾居然是

b'\x78\x9c

反转过来继续...

import zlib
import bz2

if __name__ == '__main__':
	f = open('package.pack', "rb").read()

	while True:
		if f[0:2] == b'\x78\x9c':
			f = zlib.decompress(f)
		elif f[0:2] == b'BZ':
			f = bz2.decompress(f)
		elif f[-1:-3:-1] == b'\x78\x9c':
			f = zlib.decompress(f[::-1])
		elif f[-1:-3:-1] == b'BZ':
			f = bz2.decompress(f[::-1])
		else:
			break
	print(f)

得到新提示

b'sgol ruoy ta kool'

反过来看就是look at your logs

其实一直没明白log是啥意思, 后来googel得知是解压的顺序, 我用了四个分支, 那就用4个符号分别替代

再观察结果,做些加工

import zlib
import bz2

if __name__ == '__main__':
	f = open('package.pack', "rb").read()
	logs = []
	while True:
		if f[0:2] == b'\x78\x9c':
			f = zlib.decompress(f)
			logs += ['*']
		elif f[0:2] == b'BZ':
			f = bz2.decompress(f)
			logs += ['+']
		elif f[-1:-3:-1] == b'\x78\x9c':
			f = zlib.decompress(f[::-1])
			logs += ['x']
		elif f[-1:-3:-1] == b'BZ':
			f = bz2.decompress(f[::-1])
			logs += [' ']
		else:
			break
	print(f[::-1])
	print(logs)
	print(len(logs)) #
	print(''.join(logs).replace('x','\n').replace('*',' '))

得到答案 copper

 

22

http://www.pythonchallenge.com/pc/hex/copper.html

提示:-- or maybe white.gif would be more bright-->

访问http://www.pythonchallenge.com/pc/hex/white.gif

一张黑图? 喔...

实在看不出啥, 下下来查看信息, 说这gif又133帧...

抄的答案, 对图片实在无爱.

新技能: gif的处理

from PIL import Image
from PIL import ImageDraw 
from PIL import ImageSequence 

if __name__ == '__main__':
	im = Image.open('white.gif')
	path = [i.getbbox()[0:2] for i in ImageSequence.Iterator(im)]
	joy3 = Image.new(im.mode, (200,200), 0)
	letter = 0
	pos = (30,30)
	for p in path:
		if p == (100,100): letter += 1; pos = (letter * 30,) * 2
		else: pos = (pos[0] + p[0] - 100, pos[1] + p[1] - 100)
		joy3.putpixel(pos, 255)
	joy3.save('joy3.gif')

得到答案: bonus

 

23

http://www.pythonchallenge.com/pc/hex/bonus.html

这关才是云里雾里, 给你个提示

<!-- 	it can't find it. this is an undocumented module. -->

然后this 是一个python的库.. 囧...

import this

s = 'va gur snpr bs jung?'
print("".join([this.d.get(c, c) for c in s]))

这是this.py的内容

#http://svn.python.org/projects/python/trunk/Lib/this.py

s = """Gur Mra bs Clguba, ol Gvz Crgref

Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""

d = {}
for c in (65, 97):
    for i in range(26):
        d[chr(i+c)] = chr((i+13) % 26 + c)

print "".join([d.get(c, c) for c in s])

得到答案 ambiguity

 

24

http://www.pythonchallenge.com/pc/hex/ambiguity.html

一个迷宫

from top to bottom

不会让我走迷宫吧.. 虽然之前写过走迷宫算法 .. 可是这...

像素级别方大后看到清楚的迷宫, 但是哪个是墙哪个是路.... 喔...

我觉得白的是路!!!!!!!!!!!!!!!!!! 试试

不试了, 直接跳过去找标准答案

(找出迷宫路线后, 每个点的rgb中的r值存起来, 最后能成一个zip包, 关键提示还是pk开头的2进制留,以此判断)

from PIL import Image
import struct

def search(maze, tree):
    dirs = [(0,1), (0,-1), (1,0), (-1,0)]
    wall = (255,) * 4
    w,h = maze.size
    maze.putpixel((1,h-1), wall) # Wall off exit
    maze.putpixel((w-2,0), wall) # Wall off entrance
    queue = [(1, h-2)]           # Start at exit
    tree[queue[0]] = 'exit'
    while queue:
        pos = queue.pop(0)
        for d in dirs:
            new_pos = (pos[0] + d[0], pos[1] + d[1])
            if not tree.get(new_pos) and maze.getpixel(new_pos) != wall:
                tree[new_pos] = pos
                queue.append(new_pos)

if __name__ == '__main__':
	maze = Image.open('maze.png')
	tree = {}
	search(maze, tree)
	w = maze.size[0]
	tree[(w-2,1)]
	path = bytearray()
	pos = (w-2,1)

	#print(tree)

	l = []

	while pos != 'exit': 
		print(pos)
		t = maze.getpixel(pos)[0]
		s = struct.pack("=B", t)
		path += s
		pos = tree[pos]

	mazezip = path[::2]
	f = open("maze.zip", 'wb')
	f.write(mazezip)
	f.close()

其实整个过程中最让我郁闷的倒不是抄写代码..

是, 再众多py2.7版本实现的答案中, 写出最后的maze.zip之后, 发现这个格式是错的.

找了很久的办法

还是对py3的 byte 和 int 还有 str 相互转化还是有点无从下手的感觉

首先str.encode()  是可以转换成byte的.

那int怎么处理呢.. 我一直用 s = struct.pack("=B", t) 来处理的, 没有其他的方法

众多py2.7的解决方案里 直接把像素值改成"".join 再写到文件,没有任何问题

但py3里走不通, ..

不管怎样得到新的zip包, 解压得到2个图

得到提示:maze.jpg 和 mybroken.zip, maze.jpg写着lake

mybroken.zip里显示一张图, 但解压会校验失败 怎么办呢??????

19关有封邮件

Never mind that.
Have you found my broken zip?
md5: bbb8b499a0eef99b52c7f13f4e78c24b
Can you believe what one mistake can lead to?

估计是这个?  标准的修复代码

import hashlib
broken = open('mybroken.zip', 'rb').read()

for i in range(len(broken)):
	for j in range(256):
		repaired = broken[:i] + struct.pack("=B", j) + broken[i+1:]
		if hashlib.md5(repaired).hexdigest() == 'bbb8b499a0eef99b52c7f13f4e78c24b':
			open('unbroken.zip','wb').write(repaired)

然后可以得出来新图..

但是上段代码为什么能管用呢.. 提示里说是一个错误会导致错误的zip包. 线索是那段md5值,

然后代码是把每个字节都用(0-255)值替换一遍看md5对不对... 囧..虽然方法挺笨无所谓了.

得到新的压缩包, 得到新图上面写着 speed

lake, speed 2个线索

 

25

http://www.pythonchallenge.com/pc/hex/lake.html

有提示:

imagine how they sound

<!-- can you see the waves? -->

喔?  有声音?...

喔.. http://www.pythonchallenge.com/pc/hex/lake1.wav  --- 25

我觉得是把这些全合起来...

先把文件下到本地好调试

因为访问链接需要之前的密码 butter fly 所以需要带用户信息链接如下:

import wave
import io
import urllib.request
import http.client
import base64

if __name__ == '__main__':
	wavelist = []
	conn = http.client.HTTPConnection('www.pythonchallenge.com')
	strBasic = 'Basic ' + base64.b64encode(b'butter:fly').decode()
	headers = {'Authorization': strBasic}

	for i in range(1, 26):
		page = '/pc/hex/lake' + str(i) + '.wav'
		conn.request('GET', page, '', headers)
		open('c25wave' + str(i) + ".wav", 'wb').write(conn.getresponse().read())

得到25个视频文件之后, 想连起来 后来想即便连起来也不过是这些杂音的延长...

想起进入页面时候是一个拼图 25张碎片...

喔...

先打开一个wav看看信息

import wave
import io
import urllib.request
import http.client
import base64

if __name__ == '__main__':
	wa1 = wave.open('c25wave1.wav')
	buf = wa1.readframes(wa1.getnframes())
	print(len(buf))
	print(buf)

得到长度10800的buf,

b'\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x

看出个每3个字节 都是一样的

联想到10800 = 60X60X3

输出成图片试试

import wave
import io
import urllib.request
import http.client
import base64
from PIL import Image

if __name__ == '__main__':

	imlist = []
	for i in range(1, 26):
		p = "c25wave{0}.wav".format(i)
		wa1 = wave.open(p)
		buf = wa1.readframes(wa1.getnframes())
		imlist += [Image.frombytes('RGB', (60,60), buf)]

	c25 = Image.new('RGB', (300, 300))
	idex = 0
	for i in range(0, 5):
		for j in range(0, 5):
			c25.paste(imlist[idex],(60 * j, 60 * i))
			idex = idex + 1

	c25.save('c25.jpg')

得到完整图片, 提示 decent.

这关还有点意思... 好吧其实是推理简单...

 

26

http://www.pythonchallenge.com/pc/hex/decent.html

得到的提示有

be a man - apologize!

<!-- you've got his e-mail -->

Hurry up, I'm missing the boat

Join us at the IRC: irc.freenode.net #pythonchallenge

前2条得到md5,和一张写有speed的图...

speed + boat

 

27

http://www.pythonchallenge.com/pc/hex/speedboat.html

有提示 <!-- oh, and this is NOT a repeat of 14 -->

<!-- did you say gif? -->

得到图http://www.pythonchallenge.com/pc/hex/zigzag.gif

和一个http://www.pythonchallenge.com/pc/ring/bell.html链接

但需要密码和用户名之前的密码用户名统统无效...

看看图.. 用2进制方式打开看到..

from PIL import Image
import struct
import bz2

if __name__ == '__main__':
	im = Image.open('zigzag.gif')
	buff = im.tobytes()
	palette = im.palette.getdata()

	Karr = bytearray()
	Varr = bytearray()
	aaa = palette[1][::3]
	for i in range(0, 256):
		Karr += struct.pack("=B", i)

	t = bytearray.maketrans(Karr, aaa)
	zigtrans = buff.translate(t)
	deltas = filter(lambda p: p[0] != p[1], zip(buff[1:], zigtrans[:-1]))
	#diffs = [''.join([p[i] for p in deltas]) for i in range(2)]

	d1 = b''
	d2 = b''
	for i in deltas:
		d1 += struct.pack("=B",i[0])
		d2 += struct.pack("=B",i[1])
	texts = bz2.BZ2Decompressor().decompress(d1).decode().split(" ")
	print(texts)

	im2 = Image.new('1', im.size, 0)
	im2.putdata([p[0] == p[1] for p in zip(buff[1:], zigtrans[:-1])])
	im2.save('zigclue.png')

抄的代码, 云里雾里各种不爽

答案是repeat 和 switch 这些非py关键字

好像这关是唯一我无法由答案正常推出过程来的囧..

下关

 

28

http://www.pythonchallenge.com/pc/ring/bell.html

和图中绿色通道相关.

无脑堆代码

from PIL import Image
img = Image.open('bell.png')
img.load()
r,g,b = img.split()

gdata = list(g.getdata())
newlist = [(gdata[i]-gdata[i+1]) for i in range(0,len(gdata),2)]
s = ''
for i in newlist:
    if i != -42 and i!=42:
        s+=chr(abs(i))
print(s)

得到值 whodunnit().split()[0] ?

百度whodunnit,  谁是真凶?  好凶残的翻译

Guido van Rossum py创始人

 

29

http://www.pythonchallenge.com/pc/ring/guido.html

提示有whoisit.jpg, silence

还有一堆空白

import wave
import io
import urllib.request
import http.client
import base64
import struct
import bz2

if __name__ == '__main__':
	conn = http.client.HTTPConnection('www.pythonchallenge.com')
	strBasic = 'Basic ' + base64.b64encode(b'repeat:switch').decode()
	headers = {'Authorization': strBasic}
	page = 'pc/ring/guido.html'
	conn.request('GET', page, '', headers)
	text = conn.getresponse().read(-1)
	print(text)
	#没有内容,但是有\n 继续...
	l = text.decode().split('\n')
	# print(l)
	# for i in l:
	# 	print(chr(len(i)))
	#发现bzh91.... 这下好办了..
	l = l[12:]
	s = bytearray()
	for i in l:
		s += struct.pack("=B", len(i))

	print(bz2.BZ2Decompressor().decompress(s))

得到提示b"Isn't it clear? I am yankeedoodle!"

 

30

http://www.pythonchallenge.com/pc/ring/yankeedoodle.html

relax you are on 30

有提示 <!-- while you look at the csv file -->

html换成csv 得到一个csv文件

打开全是小于1的数字

喔.. 小于1可以理解..

总共是7367个数...

53 X 139 ...

一张图?

from PIL import Image
import struct

if __name__ == '__main__':
	f = open('yankeedoodle.csv','r')
	l = f.read().split(',')
	print(l)
	buff = []
	for i in l :
		buff += [float(i)]

	print(buff)
	for i in range(len(buff)):
		buff[i] = int(buff[i] * 256)

	im = Image.new('L', (53, 139))
	im.putdata(buff) 

	im.save('c30.png')

乱拼凑出来,

	message = ''
	for i in range(0, len(buff)//3 ):

		a = str(int(buff[i * 3] * 100000))
		b = str(int(buff[i * 3 + 1] * 100000))
		c = str(int(buff[i * 3 + 2] * 100000))

		#print(a,b,c)
		message += (chr(int(a[3]+b[3]+c[4])))
	print(message[0:300])

得到 There is lots of room here for a long message, but we only need very littke space to say "look at grandpa"

答案"grandpa"?

 

31

http://www.pythonchallenge.com/pc/ring/grandpa.html

提示 Where am I?

点击图,需要用户名密码

提示 岛, 国家

这图.. 鬼才知道.. 囧..

泰国, 苏梅岛?

kohsamui / thailand

进到

http://www.pythonchallenge.com/pc/rock/grandpa.html

提示 mandelbrot 传说中的分形

<window left="0.34" top="0.57" width="0.036" height="0.027"/>
<option iterations="128"/>

虽然知道这些参数 也知道分形是什么东西.. 不过...

想象不出要干嘛..

找参考答案

from PIL import Image

def mandelbrot(left=0.34, bottom=0.57, width=0.036, height=0.027, max=128, size=(640, 480)):
	xstep = width / size[0]
	ystep = height / size[1]
	for y in range(size[1] - 1, -1, -1):
		for x in range(size[0]):
			c = complex(left + x * xstep, bottom + y * ystep)
			z = 0+0j
			for i in range(max):
				z = z * z + c
				if abs(z) > 2:
					break
			yield i

if __name__ == '__main__':
	ufos = Image.open("mandelbrot.gif")
	mandel = ufos.copy()
	mandel.putdata(list(mandelbrot())[0:640*480])
	mandel.save("1.gif")

mandelbrot是分形函数  分形理论时候上学的时候读过, 但不确定具体是什么样的

新高级技能: 分形. py分形画法

(ps: 不确定, 难道所有分形都可以这样画出来? )

不管怎样得到一张图了, 然后与原图比较

	im = Image.open("1.gif")
	differences = [(a - b) for a, b in zip(ufos.getdata(), im.getdata()) if a != b]
	print(len(differences))
	print(differences)
	print(set((differences)))
	# 1679 =  23 * 73

	plot = Image.new('L', (23, 73))
	plot.putdata([(i < 16) and 255 or 0 for i in differences])
	plot.resize((23, 73))
	plot.save("2.gif")

得到一个图, 一个奇怪的图.. 搜了好久才发现原来是这个

http://en.wikipedia.org/wiki/Arecibo_message

Arecibo应该是下个关

 

32

http://www.pythonchallenge.com/pc/rock/arecibo.html

得到一张图, 上面写的 Fill in the blanks

观察就会发现左,上的数字分别是该放下连续格子的个数

看源码页游warmup.txt 的提示,

进到http://www.pythonchallenge.com/pc/rock/warmup.txt

有一串提示数字

# Dimensions
9 9

# Horizontal
2 1 2
1 3 1
5

7
9
3

2 3 2
2 3 2
2 3 2

# Vertical
2 1 3
1 2 3
3

8
9
8

3
1 2 3
2 1 3

估摸着, 按这个顺序重新摆原页的红点, 得到一个向上箭头.悲剧的blog 不会传图 囧..

进到这里

http://www.pythonchallenge.com/pc/rock/up.html

就是刚刚拼成的图.

http://www.pythonchallenge.com/pc/rock/up.txt让你解决更大的囧..

32X32 顿时无语... 靠...

不想写代码解决这个怎么办....

那就googel跳过吧..囧..据说是一条蛇, 蟒蛇? python? 囧才知道python是这个意思..

到了http://www.pythonchallenge.com/pc/rock/python.html

有提示

Congrats! You made it through to the smiling python.

"Free" as in "Free speech", not as in "free...

googel "Free" as in "Free speech"的结果

https://www.gnu.org/philosophy/free-sw.en.html

有一段free software的定义

“Free software” means software that respects users' freedom and community. Roughly, it means that the users have the freedom to run, copy, distribute, study, change and improve the software. Thus, “free software” is a matter of liberty, not price. To understand the concept, you should think of “free” as in “free speech,” not as in “free beer”.

得到相关提示beer

终于到了33关

 

33

http://www.pythonchallenge.com/pc/rock/beer.html

有提示

If you are blinded by the light,
remove its power, with its might.
Then from the ashes, fair and square,
another truth at you will glare.

把图片里的光去掉?

原码页有提示, beer1.jpg  好吧按照之前的思路, 点beer2.jpg, 果然有提示no png, 把jpg换成png得到新图

然后呢....

观察图片,

其实可以发现整个图只是用66个颜色来组成.. 联系到33关, 所以肯定和33有关..

只能想到这了, 剩下的就靠googel了.. 得到33个新图片

得到提示 gremlins, 一开始我得到的提示是snilmerg 反写的囧...

if __name__ == '__main__':
	im = Image.open("beer2.png")
	print(im)

	l = im.getdata()
	colors = im.getcolors()
	# 66个值

	for idx in range(65, -1, -2):
		print(idx)
		s = []
		t = []
		for i in l:
			if colors[idx][1] != i and colors[idx - 1][1] != i:
				s += [i]
				t += [0]
			else:
				if i==colors[idx][1]: 
					t += [1]
				else:
					t += [0]

		l = s
		n = int(math.sqrt(len(t))) 
		newim = Image.new("1",(n,n))
		print(n)
		print(len(t))
		print(t)
		newim.putdata(t) 
		newim.save("c33{0}.png".format(idx))

 

End

http://www.pythonchallenge.com/pc/rock/gremlins.html

 

回头整理下,得到的技能.

 

 

 

posted on 2014-01-13 18:16  快乐的大猪  阅读(639)  评论(0)    收藏  举报

导航