011. odd even

关卡地址#

解决方案:#

思路:#

这一关的提示比较干净,一切都需要从图片中提取分析。

把所有像素值提取到文本,以下为前4行前8列像素数据:

(0, 20, 0)(142, 180, 105)(0, 20, 0)(139, 177, 100)(0, 20, 0)(143, 180, 103)(0, 20, 0)(138, 175, 98)
(148, 186, 111)(0, 20, 0)(148, 186, 109)(0, 21, 0)(144, 181, 104)(0, 20, 0)(144, 181, 104)(0, 20, 0)
(0, 20, 0)(158, 195, 118)(0, 20, 0)(148, 185, 108)(0, 22, 0)(152, 189, 112)(0, 19, 0)(150, 184, 110)
(145, 182, 105)(0, 22, 0)(158, 195, 118)(0, 20, 0)(155, 189, 113)(0, 19, 0)(146, 180, 104)(0, 20, 0)

可以看出,绿色(0, x, 0)与彩色有规律的穿插着,绿色像素分布在偶数行偶数列和奇数行奇数列,彩色像素分布在偶数行奇数列和奇数行偶数列。

012. dealing evil

关卡地址#

解决方案:#

思路:#

这一关提示很隐晦,图片名称是evil1.jpg,那是不是还有evil2.jpg呢?

在浏览器输入evil2.jpg的地址,图片中的提示是:

not jpg - _.gfx

将jpg改为gfx会得到一个文件。

evil3.jpg得到的提示是:

no more evils…

如果你不死心,继续访问evil4.jpg,你会得到一个文本文件,内容如下:

Bert is evil! go back!

所以玄机都在evil2.gfx这个文件中。

直接查看其二进制文件:

  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 	
00000000: FF 89 47 89 FF D8 50 49 50 D8 FF 4E 46 4E FF E0    ..G..XPIPX.NFN.`
00000010: 47 38 47 E0 00 0D 37 0D 00 10 0A 61 0A 10 4A 1A    G8G`..7....a..J.
00000020: 40 1A 4A 46 0A 01 0A 46 49 00 F0 00 49 46 00 00    @.JF...FI.p.IF..
00000030: 00 46 00 00 E7 00 00 01 0D 00 0D 01 01 49 00 49    .F..g........I.I
00000040: 01 01 48 00 48 01 00 44 01 44 00 B4 52 00 52 B4    ..H.H..D.D.4R.R4
00000050: 00 00 00 00 00 B4 00 01 00 B4 00 01 04 01 00 00    .....4...4......
00000060: 90 02 40 00 FF 00 00 00 FF E1 00 05 00 E1

可以看出每五个字节类似“回文”,将其每隔五个字节连起来得到的输出是:

014. walk around

关卡地址#

解决方案:#

思路:#

这一关大图下面有个小图,查看源代码后发现是10000*1的图片显示为100*100

100 × 100 pixels (Natural: 10000 × 1 pixels)

同时还有一个提示:

remember: 100*100 = (100+99+99+98) + (…

结合标题,需要将10000*1的图片重新组合为100*100的图片,排列规律如下:

—————————————100-—————————————
|————————————98——————————————|
|   |   ................. |  |
|   |   ................. |  |
|   |   ................. |  |
98  96  ................. 97 99
|   |   ................. |  |
|   |   ................. |  |
|   |   ................. |  |
|   |   ................. |  |
| ——————————97————————————|  |
————————————99————————————————

如果一行一行排列像素会得到bit这个结果,然后得到如下提示:

you took the wrong curve.

016. let me get this straight

关卡地址#

解决方案:#

思路:#

图片每一行都有一条7个像素组成的像素块,两端是1个白色像素,中间是5个粉紫色像素,色值是(255,0,255)。由于图像模式是P,使用8位映射到调色板。

经测试,连续5个粉紫色像素的值是195。

根据标题:

让我直说吧

将这些像素块排成一列,就会得到下一关地址啦。

代码:#

import helper
path="../../Data/016"
helper.ensureDir(path)

# ================================
# 使用http认证,下载文件
import urllib.request
helper.installHTTPBasicAuthOpener("huge", "file")

gif="http://www.pythonchallenge.com/pc/return/mozart.gif"
(filename, headers)=urllib.request.urlretrieve(gif, path+"/mozart.gif")
# ================================

from PIL import Image
im=Image.open(filename)
px=im.load()

newIm=Image.new(im.mode, im.size)
newPx=newIm.load()

(w,h)=im.size
for y in range(h):
    for x in range(w):
        if px[x,y] == 195:
            for xx in range(w):
                newPx[xx,y]=px[(xx+x)%w,y]
            continue

im.close()
newIm.show()
newIm.close()
$path="../../Data/016"

. .\helper.ps1
New-Dir -Dir $path
$path=$(Resolve-Path $path).Path

$gif="http://www.pythonchallenge.com/pc/return/mozart.gif"
$filename=$path+"/mozart.gif"
Get-FileWithAuth -Url $gif -Filename $filename -Username "huge" -Password "file"

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$img=[System.Drawing.Image]::FromFile($filename)
$newImg=New-Object System.Drawing.Bitmap $img.Width,$img.Height
$color=[System.Drawing.Color]::FromArgb(255,0,255)

for ($y = 0; $y -lt $img.Height; $y++) {
    for ($x = 0; $x -lt $img.Width; $x++) {
        if ($img.GetPixel($x,$y) -eq $color) {
            for ($xx = 0; $xx -lt $img.Width; $xx++) {
                $newImg.SetPixel($xx,$y,$img.GetPixel(($xx+$x)%$img.Width,$y))
            }
            continue
        }
    }
}

$img.Dispose()

Show-Image -Title "Challenge016" -Image $newImg
$newImg.Dispose()
package main

import(
	"image"
)

func (c *Challenge) Challenge016() {
	path:="../../Data/016"
	EnsureDir(path)

	gif:="http://www.pythonchallenge.com/pc/return/mozart.gif"
	filename:=path+"/mozart.gif"
	DownloadWithBasicAuth(gif, filename, "huge", "file")

	im:=OpenImage(filename)

	newImg:=straightImage(im)

	giffile := path+"/mozart.go.gif"
	SaveImage(giffile, newImg, "gif")
	
	ShowImage(giffile)
}

func straightImage(im image.Image) *image.RGBA {
	bounds:=im.Bounds()
	newImg:=image.NewRGBA(bounds)
	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			r,g,b,_:=im.At(x,y).RGBA()
			if r==65535 && g==0 && b==65535 {
				for xx := bounds.Min.X; xx < bounds.Max.X; xx++ {
					newImg.Set(xx,y,im.At((xx+x)%bounds.Dx(),y))
				}
				continue
			}
		}
	}
	return newImg
}

最终结果: romance#

下一关地址#

017. eat?

关卡地址#

解决方案:#

思路:#

这一关图片中是曲奇饼干,左下角图片是不是有点熟悉?是第四关啦!

查看源代码并没有什么提示。

但是!根据cookie可以联想到什么?对!就是浏览器缓存。

通过浏览器开发者工具查看cookie后,可以得到如下提示:

you+should+have+followed+busynothing…

在第四关,我们请求的是:http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=

这里需要将nothing替换为busynothing,并且收集cookieinfo的值。

之后得到BZh91AY开头的经过url编码的字符串,是不是又有点熟悉?不熟悉的请回顾第八关

使用python在解码时会有小问题:

OSError: Invalid data stream

在解码前将+替换为%20可以解决该问题。

解码后得到提示:

is it the 26th already? call his father and inform him that “the flowers are on their way”. he’ll understand.

这句话信息量有点大,26号暗示第十五关call his father则暗示第十三关,Mozart的父亲是Leopold(注意L大写)。

给Leopold打电话之后得到:

555-VIOLIN

访问violin.html得到如下提示:

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

替换url之后访问,得到的是一张Leopold的照片,及:

it’s me. what do you want?

额。。。对,and inform him that “the flowers are on their way”

018. can you tell the difference?

关卡地址#

解决方案:#

思路:#

可以很明显的看出图片左右两部分的亮度不同,但还是看一下源代码的提示:

it is more obvious that what you might think

替换url为bright会提示:

ness

访问brightness仍然是相同的图片,再次查看源代码的提示:

maybe consider deltas.gz

下载解压后发现一个delta.txt文件,打开后前4行数据如下:

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

可以看出这是两个文件合并在一起的,结合标题,需要比较两者不同。

❤️ 如果这篇文章对你有帮助,欢迎赞助支持我继续维护 ❤️

☕ Support me ⚡ 爱发电赞助