python challeng 22 解题总结

python challenge 22网址:www.pythonchallenge.com/pc/hex/copper.html,查看网页源代码会发现一个提示:maybe white.gif would be more bright,于是打开和下载www.pythonchallenge.com/pc/hex/white.gif,发现这个gif是多帧的,差不多在图像的正中间有比黑色稍微亮一点的颜色……那些颜色出现在小键盘一样布局的3*3的9个位置上。然后一次当作方向向量描点处理.

源代码如下:

 

import Image, ImageSequence

img = Image.open("white.gif") # http://www.pythonchallenge.com/pc/hex/white.gif
out = Image.new("P", (125, 125))
pix = out.load()
pos = [25, 25]

for x in [list(f.getdata()).index(8) for f in ImageSequence.Iterator(img)]:
    if x == 19698:
        pos[0] -= 1
        pos[1] -= 1
    elif x == 19700:
        pos[1] -= 1
    elif x == 19702:
        pos[0] += 1
        pos[1] -= 1
    elif x == 20098:
        pos[0] -= 1
    elif x == 20100:
        pos = [pos[0] + 10, pos[1] + 10]
    elif x == 20102:
        pos[0] += 1
    elif x == 20498:
        pos[0] -= 1
        pos[1] += 1
    elif x == 20500:
        pos[1] += 1
    elif x == 20502:
        pos[0] += 1
        pos[1] += 1

    pix[pos[0], pos[1]] = 200

out.save("solution.png")

 

下一关的网址:www.pythonchallenge.com/pc/hex/bonus.html(用户名:butter,密码:fly)

 

阅读全文 »

python challeng 23 解题总结

python challenge 23网址:www.pythonchallenge.com/pc/hex/bonus.html,查看网页源代码会发现两个提示:(1)this is an undocumented module;(2)va gur snpr bs jung?。由第一个提示就能想到this这个模块,但是第二个提示是进行一些处理过的字符串,如果是使用linux或者unix,就会发现:

grep -i "va gur snpr bs" *
this.py:Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.

换成英文就是:

In the face of ambiguity, refuse the temptation to guess.

于是就得出答案,下一关的网址就是:www.pythonchallenge.com/pc/hex/ambiguity.html(用户名:butter,密码:fly)


阅读全文 »

python challeng 24 解题总结

python challenge 24网址: www.pythonchallenge.com/pc/hex/ambiguity.html ,查看网页源码会得出一个提示:from top to bottom,仔细一看图片:好复杂的一张maze图呀,于是试着下面的方式找到答案。 开始试着以白色为道路非白色为墙壁,用以前写过的A*算法找路径,结果没有路。 又仔细放大图片查看边缘,原来右上角和左下角各有一个黑色像素 这么说就是就是以白色为墙壁非白色为道路了,再次找路,找到。 又没有头绪了,开始猜想也许通路能组成图形字符,结果啥也看不出来。 参考攻略,原来是依次将路径间隔着取所在的像素的r值,存入文件中。 存成的文件是个zip,打开,里面有两个文件maze.jpg和mybroken.zip,其中maze.jpg 打开是个图片,上面有lake字样 == http://www.pythonchallenge.com/pc/hex/lake.html 而mybroken.zip打开里面有个mybroken.gif,不过无法打开,似乎没有用。 源代码如下: def level_24(): class Node: def __init__(self,parent,x,y,h): self.parent=parent self.x,self.y=x,y self.hv = (x 16) ^ y self.g,self.h=0,h def __repr__(self): return '(%d,%d)'%(self.x,self.y) def __eq__(self,other): return self.hv == other def __hash__(self): return self.hv class AStarTest: def __init__(self,map_max_x,map_max_y,map): self.openlist,self.closedlist=[],set() self.mapMaxX,self.mapMaxY=map_max_x,map_max_y print '%d %d'%(self.mapMaxX,self.mapMaxY) self.map=map def inCloseList(self,x,y): u"""检查(x,y)是否在closedlist中""" return (x 16) ^ y in self.closedlist def inOpenList(self,x,y): u"""检查(x,y)是否在openlist中""" for i,n in enumerate(self.openlist): if n.x==x and n.y==y: return i return -1 def showPath(self,l,showmark): u"""显示路径""" tm=[] # 用来保存从起点到终点的路径坐标列表 for i in l: tm.append((i.x,i.y)) if showmark: # 在新图中显示出路径来 f=PngImagePlugin.PngImageFile(r'd:maze.png') my=f.copy() draw=ImageDraw.Draw(my) draw.point(tm,showmark)# (0,0,255,255)) my.save(r'd:maze_showpath.png','png') # 将路径间隔着取像素的r值保存到zip文件中 f=PngImagePlugin.PngImageFile(r'd:maze.png') fo=open(r'd:maze.zip','wb') data=[] for i in tm[1::2]: # 从第二个像素开始间隔着取 r,dummy,dummy,dummy=f.getpixel(i) data.append(r) fo.write(''.join([chr(item) for item in data])) fo.close() def SubNode(self,node,to_x,to_y): u""" 返回节点node的有效子节点""" subList=[ (node.x,node.y-1), (node.x-1,node.y), (node.x+1,node.y), (node.x,node.y+1), ] for x,y in subList: if self.map[y][x] !='#': # 坐标值有效 if not self.inCloseList(x,y): # 不在closedlist中 item= Node(node,x,y,sqrt((x-to_x)*(x-to_x)+(y-to_y)*(y-to_y))*1.2) item.g=item.parent.g+1.0 yield item def getPath(self,from_x,from_y,to_x,to_y,show_mark=None): u"""获取两点间的路径 from_coord 起点 to_coord 终点 show_mark 用来显示路径的颜色 """ print "(%d,%d)- (%d,%d)"%(from_x,from_y,to_x,to_y) self.openlist.append(Node(None,from_x,from_y,0)) while self.openlist: # 重复如下的工作: # a) 寻找开启列表中F值最低的格子。我们称它为当前格。 minf,minidx,curCoord=1000000,-1,None # 假设当前最新f为1000000 for i,n in enumerate(self.openlist): if n.g+n.h minf: minf=n.g+n.h curCoord=n minidx=i # b) 把它切换到关闭列表。 del self.openlist[minidx] self.closedlist.add(curCoord) # c) 对相邻的8格中的每一个 for item in self.SubNode(curCoord,to_x,to_y): # 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。 # 记录这一格的F,G,和H值。 i=self.inOpenList(item.x,item.y) if i==-1: self.openlist.append(item) # 保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是你的路径。 if item.x==to_x and item.y==to_y: print "found %d,len(closedlist)=%d"%(item.g,len(self.closedlist)) l=[item] p=item.parent while p: l.append(p) p=p.parent l.reverse() self.showPath(l,show_mark) return True # 如果它已经在开启 ...

阅读全文 »

python challeng 25 解题总结

 python challenge 25网址:www.pythonchallenge.com/pc/hex/lake.html(用户名:butter,密码:fly)。查看网页源代码可以看到一个提示:can you see the waves。于是想到去看网址:www.pythonchallenge.com/pc/hex/lake1.wav,果然存在这个音频文件,看到关数以及拼板的数量,于是一直下载到lake25.wav.这是一个奇怪的帧率音频文件。让我们的波形编辑器打开它,看看它是什么样子。嗯,有一个明确的行为期3样本,而不是我们期望在所有的音频。也许它并不是在所有的音频,但一些其他形式的数据编码,说一个形象,一个拼图的一部分。如果我们除以3(3个字节,每个像素),我们得到完整的拼图3600。

源代码如下:

 

 

 

##	template = "http://butter:fly@www.pythonchallenge.com/pc/hex/lake%i.wav"
##	fname=r'd:25_lake%d.wav'
##	for i in range(1, 26):
##		urllib.urlretrieve(template % i,fname%i)
##	# 完成拼接
##	l=[]
##	for i in range(1,26):
##		f=wave.open(ur'd:25_lake%d.wav'%i,'rb')
##		l.append(f.readframes(f.getnframes()))
##		f.close()
##	im=Image.new('RGB',(300,300))
##	for i in range(25):
##		im.paste(Image.fromstring('RGB',(60,60),l[i]),( 60*(i%5),60*(i//5)))
##	im.show()

 

 

下一关网址:www.pythonchallenge.com/pc/hex/decent.html

阅读全文 »

python challenge 26解题总结

python challenge 26网址:www.pythonchallenge.com/pc/hex/decent.html(需要用户名和密码的话,用户名为butter,密码为fly),查看网页源代码以及图片会发现:

# be a man - apologize!
# 图中是抓耳挠腮的猴子,下面有句话 Hurry up, I'm missing the boat
# 网页注释中有 <!-- you've got his e-mail -->
# 联想到前面第19关解一个邮件里面的音频文件,当时没有记那个email地址
# 回去找,是 leopold.moz@pythonchallenge.com
# 发封邮件到这个地址,既然要道歉,就说sorry吧
# 得到如下输出
# 发件人    Leopold Mozart <leopold.moz@pythonchallenge.com>
# 发送至    keep.studying.everyday@gmail.com
# 日期    2010年1月5日 下午11:58
# 主题    Re: my broken zip Re: sorry
# 邮送域    mail-yw0-f121.google.com
#
# Never mind that.
#
# Have you found my broken zip?
#
# md5: bbb8b499a0eef99b52c7f13f4e78c24b
#
# Can you believe what one mistake can lead to?

# 这让我想到第24关的那个mybroken.zip
# 看来要想办法根据md5修复这个zip文件
# 用winrar修复失败
# 又没有思路了。。。
# 看攻略的解法:
# 信中的最后一句意思是你能相信错了一个字节就会出现这个吗?暗示你那个zip文件有一个字节错了。
# 所以修复方法是,枚举每个字节的所有可能值,然后算md5,直到与已知的正确md5值相同为止。
# 从修复好的zip文件里打开gif文件,里面显示 speed  ==> http://www.pythonchallenge.com/pc/hex/speed.html
# 地址不对
# 猜吧,发现正确的是speedboat ==> http://www.pythonchallenge.com/pc/hex/speedboat.html

源代码如下:

def level_26():
  data=open(ur'd:mybroken.zip','rb').read()
  for i in range(len(data)):
    for c in range(256):
      newdata=data[:i]+chr(c)+data[i+1:]
      if hashlib.md5(newdata).hexdigest()=='bbb8b499a0eef99b52c7f13f4e78c24b':
        open(ur'd:mybroken_repaired.zip','wb').write(newdata) # 修复好的文件打开里面的mybroken.gif, 图中显示 speed
        print 'repaired.'
        return

下一关网址:www.pythonchallenge.com/pc/hex/speedboat.html(用户名:butter,密码:fly)

 

阅读全文 »

python challenge 27 解题总结

这一关是参照别人的方法做的,方法如下: A picture showing an oar with a zigzag line. Title between the tables , clues did you say gif? and oh, and this is NOT a repeat of 14 . There s a link to bell [ that s level 28 ] but that s password protected; the login domain is the order matters . Trying zigzag.gif as suggested, I see that the GIF is interlaced, which is new. Is that significant? [ No, it s not. ] It s a greyscale image with 256 levels of grey in the pixels, no clear pattern: zig = get_image('hex/zigzag.gif') zigdata = zig.tostring() hex(zigdata[:20]) 'd7d0cb0cfe266c743b8b4842bd7fb0ad46aacf27207e8e' The reference to level 14 suggests that spiral order is not it (and if it were, the opening bytes d7 d0 cb don t suggest any file format). So what about zigzag order? I can t find any place to start that looks like the beginning of a file. What about the palette? It appears to have each colour in it once: len(zig.getcolors()) 256 palette = zig.palette.getdata()[1][::3] # 3 bytes per pixel, equal RGB hex(palette[:20]) '25e5a2883bd40929189c9470fe5b6a31f8d5dc0f' The values in the image data are the numbers of palette entries. What if we translate the image data by the palette, getting greyscale values? t = string.maketrans(''.join([chr(i) for i in range(256)]), palette) zigtrans = zigdata.translate(t) hex(zigtrans[:20]) 'd0cb0cfe266c743b8b4842bd7fb0ad46aacf27207e8ea4' Still nothing. Hang on, isn t that very similar to the original data? It s identical, except that it s missing the first byte. Is it identical all the way to the end? zigdata[1:] == zigtrans[:-1] False What if we gather up all the bytes which are different in the two strings? deltas = filter(lambda p: p[0] != p[1], zip(zigdata[1:], zigtrans[:-1])) diffs = [''.join([p[i] for p in deltas]) for i in range(2)] diffs[0][:20] 'BZh91AY SYxe0xaaYFx00x17x9ax11x80@' diffs[1][:20] '99bd5182f289530415450437200495e44e9bd5a8' On the one side, a bzip2-compressed datastream, on the other, what? I don't recognize it. bz = bz2.BZ2Decompressor().decompress(diffs[0]) len(bz) 70644 bz[:100] '../ring/bell.html del assert repeat raise or class is exec return except print return switch from ex' It s a bunch of Python keywords plus ../ring/bell.html . Let s see how many and what they are. keywords = bz.split(' ') keys = {} for k in keywords: keys[k] = 1 ... keys.keys() ['and', 'elif', 'is', 'global', 'in', 'if', 'from', 'raise', 'for', 'except', 'switch', 'finally', 'print', 'import', 'pass', 'repeat', 'return', 'exec', 'else', 'assert', 'not', 'class', '../ring/bell.html', 'yield', 'try', 'while', 'continue', 'del', 'break', 'or', 'def', 'lambda'] len(keywords) 12000 len(keys.keys()) 32 12000 / 32 375 Are we meant to apply the same technique to this datastream? But if so, where s the table? Does this datastream code for an image? (I tried several plausible ideas, but it looks like random noise each time.) Finally, in desperation, I tried every possible pair of keywords as username and password: auth_handler = ...

阅读全文 »

python challenge 28解题总结

python challenge 28网址:www.pythonchallenge.com/pc/ring/bell.html用户名是repeat 密码是 switch

  • 图片是瀑布,湖,丛林,图片上面似乎覆盖着很多长短不一的竖条
  • many pairs ring-ring
  • 提示 RING-RING-RING say it out loud
  • 再次失去思路
  • 一个攻略说,传说中ring-ring-ring 反复读会变成green
  • 另一个则说,会变成grin
  • 先看grin  ==> http://www.pythonchallenge.com/pc/ring/grin.html
  • 网页上提示 you are not happy - you are feeling sick.
  • 再看green ==> http://www.pythonchallenge.com/pc/ring/green.html
  • 网页上提示 yes! green!
  • 解码图片上短竖条中的g值

源代码:

 

def level_28():
	im=PngImagePlugin.PngImageFile(ur'd:bell.png')
	l=[]
	for y in range(im.size[1]):
		for x in range(im.size[0]):
			l.append(im.getpixel((x,y))[1])
	print l[:10]
	paris=[(l[i],l[i+1]) for i in range(0,len(l),2)] # 根据"my paris" 将像素两两分为一组
	# 可以看出基本上每个paris内两像素之差都为42
	print paris[:10]

	diffs=[abs(i[0]-i[1]) for i in paris] # 计算两两像素之差的绝对值
	print diffs[:10]

	d=[x for x in diffs if x!=42] # 过滤掉差值等于42的
	print d

	s=''.join([chr(x) for x in d])  # 剩下的差值转为字符
	print s # 输出 whodunnit().split()[0] ?

	# 到此就有些让我奇怪了,whodunnit是到结尾才知道谋杀犯的侦探小说的意思,怎么会联想到Python发明人Guido Van Rossum ?
	# 难道是发音像 who done it 谁做了这些
	print 'Guido Van Rossum'.split()[0] # 输出 guido  ==> http://www.pythonchallenge.com/pc/ring/guido.html

	# 从官方wiki看到获取所有像素的g值的更好方法是
##	im=Image.open(ur'd:bell.png')
##	green=im.split()[1]
##	greendata=green.getdata()

 

下一关的网址:www.pythonchallenge.com/pc/ring/guido.html用户名是repeat 密码是 switch

 

阅读全文 »

python challenge 29解题总结

python challenge 29网址:www.pythonchallenge.com/pc/ring/guido.html用户名是repeat 密码是 switch

查看网页源代码会发现提示silence!
发现网页源码后面后很多行长短不一的空格行
用每行空格的数量组成列表
转成字符串,是BZh打头
用bz2解压字符串,得到 yankeedoodle

源代码如下:

 

def level_29():
	auth=urllib2.HTTPBasicAuthHandler()
	auth.add_password('the order matters','www.pythonchallenge.com','repeat','switch')
	openr=urllib2.build_opener(auth)
	r=openr.open('http://www.pythonchallenge.com/pc/ring/guido.html')
	data=r.read().split('n') # 读取网页内容
	print len(data)
	sdata=[x for x in data if x.strip()==u''] # 过滤掉非空格行
	print len(sdata)
	s=''.join([chr(len(x)) for x in sdata]) # 把每行空格数转成字符
	print s # 看到是BZh打头的
	rslt=bz2.decompress(s) # 用bz2解压之
	print rslt

下一关的网址:www.pythonchallenge.com/pc/ring/yankeedoodle.html用户名是repeat 密码是 switch

阅读全文 »

python challenge 30解题总结

python challenge 30网址:www.pythonchallenge.com/pc/ring/yankeedoodle.html用户名是repeat 密码是 switch )。


  • 网页注释提示 <!-- while you look at the csv file -->
  • 下载 http://www.pythonchallenge.com/pc/ring/yankeedoodle.csv
  • 打开一看是逗号分割的,每行七个小于1的浮点数,总共有900多行
  • 基本思路是:将浮点数的总数(7367)做因式分解,得到53和139
  • 然后以此做为宽和高,用浮点数与256的乘积作为灰度值画成图片,
  • 调整方向后得到公式
  • 根据公式对浮点数3个一组操作,将结果转换为字符,得到下一关的名称。

源代码:

def level_30():
	f=open(ur'd:yankeedoodle.csv')
	data=' '.join(f.read().splitlines())
	f.close()
	fields=data.split(', ') # 注意是逗号加空格!如果只是空格,则后面拼message时只会得到乱码。
	print len(fields)

	n=len(fields) # 输出 7367

	# 因式分解之
	def factor(n):
		"Adapted from http://www.math.utah.edu/~carlson/notes/python.pdf"
		d = 2
		factors = []
		while not n % d:
			factors.append(d)
			n /= d
		d = 3
		while n > 1 and d * d <= n:
			if not n % d:
				factors.append(d)
				n /= d
			else:
				d += 2
		if n > 1:
			factors.append(n)
		return factors

	print factor(n) # 输出 [53,139],也就是说 53*139=7367

##	im=Image.new('L',(53,139))
##	idata=[chr(int(float(x)*256)) for x in fields]
##	im.fromstring(''.join(idata))
	im=Image.new('F',(53,139)) # 'F'表示直接使用浮点数
	im.putdata(map(float,fields),256)
	im=im.transpose(Image.FLIP_LEFT_RIGHT) # 左右翻转
	im=im.transpose(Image.ROTATE_90) # 旋转90度
	im.show() # 能看到公式 n=str(x[i])[5]+str(x[i+1])[5]+str(x[i+2])[6]

	nlist=[]
	for i in range(0,n-2,3):
		n=chr(int(fields[i][5]+fields[i+1][5]+fields[i+2][6]))
		nlist.append(n)
	print ''.join(nlist)

下一关网址:www.pythonchallenge.com/pc/ring/grandpa.html用户名是repeat 密码是 switch )。

阅读全文 »

python challenge 31解题总结

python challenge 31网址: www.pythonchallenge.com/pc/ring/grandpa.html ( 用户名是repeat 密码是 switch) 点击岛礁图片 要求用户名和密码,uri是"island : country" 网页注释中提示 !-- short break, this ***REALLY*** has nothing to do with Python -- 先猜猜哪个岛礁是哪里? google 礁石 形状像性器官,找到 http://www.szvipp.com/ctrip/thalland/thallandscenici.html 再google 拉迈海滩之南 性器官 找到 http://www.successfultravel.com.hk/travel_info/koh_samui.htm 原来是泰国(thailand)的苏梅岛(koh samui),这里有两块岩石分别很像男女性器官,分别叫做叫 祖父石 (Hin Ta) 和祖母石 (Hin Yai) 用 kohsamui 和 thailand 做用户名密码,进入 http://www.pythonchallenge.com/pc/rock/grandpa.html 网页显示 That was too easy. You are still on 31... UFOs? 没思路啦 看攻略。。。。。和分形图有关 网页中的图像名为 mandelbrot.gif google 得知 mandelbrot 是法国数学家和分形理论家,其发现了著名的 mandelbrot集合 定义  曼德布洛特集合(Mandelbrot set)是在复平面上组成分形的点的集合。Mandelbrot集合可以用复二次多项式f(z)=z^2+c来定义。 其中c是一个复参数。对于每一个c,从z=0开始对f(z)进行迭代 序列 (0, f(0), f(f(0)), f(f(f(0))), .......)的值或者延伸到无限大,或者只停留在有限半径的圆盘内。 曼德布洛特集合就是使以上序列不延伸至无限大的所有c点的集合。 从数学上来讲,曼德布洛特集合是一个复数的集合。一个给定的复数c或者属于曼德布洛特集合M,或者不是。 根据网页注释中的提示 left="0.34" top="0.57" width="0.036" height="0.027" 将上面的数字作为分形函数的参数,攻略上说参数“top”实际上应该是“bottom” 自己按照给出的参数画出同样的分形图 下面的分形函数 mandelbrot 直接抄袭自官方攻略 源代码: def level_31(): url = 'http://kohsamui:thailand@www.pythonchallenge.com/pc/rock/mandelbrot.gif' ufos = Image.open(StringIO(urllib.urlopen(url).read())) 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 xrange(size[1] - 1, -1, -1): for x in xrange(size[0]): c = complex(left + x * xstep, bottom + y * ystep) z = 0+0j for i in xrange(max): z = z * z + c if abs(z) 2: break yield i # 因式分解之 def factor(n): "Adapted from http://www.math.utah.edu/~carlson/notes/python.pdf" d = 2 factors = [] while not n % d: factors.append(d) n /= d d = 3 while n 1 and d * d = n: if not n % d: factors.append(d) n /= d else: d += 2 if n 1: factors.append(n) return factors mandel = ufos.copy() # 直接使用原图的类型、大小和调色板 mandel.putdata(list(mandelbrot())) mandel.show() # 自己画出的图像看上去和给出的图一样 # 通过比较像素确定自己画的图和给出的图的差异 differences = [(a - b) for a, b in zip(ufos.getdata(), mandel.getdata()) if a != b] print len(differences) # 输出 1679,说明实际上有1679处不同 print set(differences) # 输出set([-16, 16]),说明实际上所有差异都是16或者-16 # 调用level30里面用过的因式分解函数 print factor(len(differences)) # 输出 [23, 73] ,说明可以解析为23×73的图像 # 构造 23×73的图像,放大10倍后显示 plot=Image.new('L',(23,73)) plot.putdata([(i 16) and 255 or 0 for i in differences]) # 是-16则设为255,否则设为0 plot.resize((230, 730)).show() # 显示一幅奇怪的图像 # google得知 上面显示的图是由位于美国波多里格的Arecibo天文台的目前全球最大的射电望远镜 # 发射到外太空以期与外星人沟通的无线电信号。Arecibo天文台的射电望远镜口径350米,就是007《黄金眼》 # 中出现的那个超大的湖水下的大碗(又想起了里面的漂亮MM ^_^)。 # 信号含义见 http://zh.wikipedia.org/wiki/%E9%98%BF%E9%9B%B7%E8%A5%BF%E5%8D%9A%E4%BF%A1%E6%81%AF # 下一关的key就是 arecibo == http://www.pythonchallenge.com/pc/rock/arecibo.html 下一关网址: www.pythonchallenge.com/pc/rock/arecibo.html (用户名是kohsamui ,密码是thailand ) ...

阅读全文 »