[Python Challenge通关]第7关 smarty

oxygen

挑战地址,点我

分析

图片中间有一条灰色带,就像打了马赛克,右键查看网页源代码也没有任何提示信息。

那应该需要处理这条灰色的马赛克了,python 标准库中并没有处理图片的,需要用到第三方图像处理模块 pillow。

#!/usr/bin/env/ python3

import urllib.request
import io
from PIL import Image

# 从图片链接读取
url = 'http://www.pythonchallenge.com/pc/def/oxygen.png'
with urllib.request.urlopen(url) as f:
    im = Image.open(io.BytesIO(f.read()))
# 输出图片大小
print(im.size)

输出结果:

(629, 95)

图片宽 629,高 95。

灰色带大概在图片中间部位(可以找些软件确定下是否是中间),查看下对应的像素信息:

#!/usr/bin/env/ python3

import urllib.request
import io
from PIL import Image

url = 'http://www.pythonchallenge.com/pc/def/oxygen.png'

with urllib.request.urlopen(url) as f:
    im = Image.open(io.BytesIO(f.read()))

width, height = im.size

row = (height + 1) / 2

for col in range(width):
    pixel = im.getpixel((col, row))
    print(pixel)

输出结果:

(115, 115, 115, 255)
(115, 115, 115, 255)
(115, 115, 115, 255)
...省略
(93, 93, 93, 255)
(93, 93, 93, 255)
(119, 120, 78, 255)
(111, 112, 70, 255)
...省略

可以看到中间灰色带像素的 RGB 是相同的,先筛选灰色带,只打印 RGB 一个通道的值看下,有什么规律:

#!/usr/bin/env/ python3

import urllib.request
import io
from PIL import Image

url = 'http://www.pythonchallenge.com/pc/def/oxygen.png'

with urllib.request.urlopen(url) as f:
    im = Image.open(io.BytesIO(f.read()))

width, height = im.size

row = (height + 1) / 2

for col in range(width):
    pixel = im.getpixel((col, row))
    if pixel[0] != pixel[1]:
        continue
    print(pixel[0], end=" ")

输出结果:

115 115 115 115 115 109 109 109 109 109 109 109 97 97 97 97 97 97 97 114 114 114 114 114 114 114 116 116 116 116 116 116 116 32 32 32 32 32 32 32 103 103 103 103 103 103 103 117 117 117 117 117 117 117 121 121 121 121 121 121 121 44 44 44 44 44 44 44 32 32 32 32 32 32 32 121 121 121 121 121 121 121 111 111 111 111 111 111 111 117 117 117 117 117 117 117 32 32 32 32 32 32 32 109 109 109 109 109 109 109 97 97 97 97 97 97 97 100 100 100 100 100 100 100 101 101 101 101 101 101 101 32 32 32 32 32 32 32 105 105 105 105 105 105 105 116 116 116 116 116 116 116 46 46 46 46 46 46 46 32 32 32 32 32 32 32 116 116 116 116 116 116 116 104 104 104 104 104 104 104 101 101 101 101 101 101 101 32 32 32 32 32 32 32 110 110 110 110 110 110 110 101 101 101 101 101 101 101 120 120 120 120 120 120 120 116 116 116 116 116 116 116 32 32 32 32 32 32 32 108 108 108 108 108 108 108 101 101 101 101 101 101 101 118 118 118 118 118 118 118 101 101 101 101 101 101 101 108 108 108 108 108 108 108 32 32 32 32 32 32 32 105 105 105 105 105 105 105 115 115 115 115 115 115 115 32 32 32 32 32 32 32 91 91 91 91 91 91 91 49 49 49 49 49 49 49 48 48 48 48 48 48 48 53 53 53 53 53 53 53 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 49 49 49 49 49 49 49 48 48 48 48 48 48 48 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 49 49 49 49 49 49 49 54 54 54 54 54 54 54 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 48 48 48 48 48 48 48 49 49 49 49 49 49 49 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 48 48 48 48 48 48 48 51 51 51 51 51 51 51 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 49 49 49 49 49 49 49 52 52 52 52 52 52 52 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 48 48 48 48 48 48 48 53 53 53 53 53 53 53 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 49 49 49 49 49 49 49 54 54 54 54 54 54 54 44 44 44 44 44 44 44 32 32 32 32 32 32 32 49 49 49 49 49 49 49 50 50 50 50 50 50 50 49 49 49 49 49 49 49 93 93 93 93 93 93 93 93

可以看到像素值按照一定规律重复着,第一组 115 重复了 5 次,中间都重复了 7 次,最后的 93 重复了 8 次。

这些数字如果和 ASCII 码关联起来,115 -> s, 109 -> m, 97 -> a,也许会组成有意义的字符。

按照上面的规律,可以每隔 7 个字符取一个数字:

#!/usr/bin/env/ python3

import urllib.request
import io
from PIL import Image

url = 'http://www.pythonchallenge.com/pc/def/oxygen.png'

with urllib.request.urlopen(url) as f:
    im = Image.open(io.BytesIO(f.read()))

width, height = im.size

row = (height + 1) / 2

for col in range(width):
    pixel = im.getpixel((col, row))
    if pixel[0] != pixel[1]:
        continue
    if col % 7 == 0:
        print(chr(pixel[0]), end="")

输出内容:

smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]

果然就是这样的规律,按照提示,需要把 [105, 110, 116, 101, 103, 114, 105, 116, 121] 再转换成 ASCII 码。

#!/usr/bin/env/ python3
level = [105, 110, 116, 101, 103, 114, 105, 116, 121]

for l in level:
    print(chr(l), end="")

输出内容:

integrity

integrity 替换 url 得到下一关真正的入口了 http://www.pythonchallenge.com/pc/def/integrity.html

参考资源:

  1. PIL.image 参考
  2. io.BytesIO 参考
  3. ASCII 参考

你可能感兴趣的:([Python Challenge通关]第7关 smarty)