题干
解答
下载下来之后是一个名叫 file 的文件,用文本编辑器打开能看到 PNG 文件头和文件尾,用 pngcheck 读一遍没发现异常。
搜了下2018年“网鼎杯”题目“虚幻”的题解,发现是把图片拼成了汉信码。用 Python 的 PIL 库读出 file 文件各像素的 RGB 值可以发现它们总是取 0 或 255,那么就把图片的 RGB 通道分开,并且去掉白边(这里贴的图片为了易于查看放大了10倍):
G通道
R通道
B通道
根据 GBT 21049-2007,汉信码应该长这样:
观察可知应该将 RGB 通道分开得到的图片按 G, R, B 的顺序逐行拼接(拼接用的脚本是队友给的),拼完之后逆时针旋转 90 度,再把左下角的 7*7 的寻像标志旋转180度,似乎效果不错(这里贴的图片为了易于查看放大了10倍):
这张码扫不出来。然后因为题干提示要暴力修复,就写个脚本对图上 7*9 的空白区域(不是 7*10,因为寻像标志边上的格子本来就是空白的)进行随机填充,每个像素都有50%的概率被涂黑,如此生成了 1000 张图片,用中国编码手机客户端手动扫描(汉信码在线识别网站比赛时出错了…也许是提交的人太多了吧)发现一张也扫不出来,然后整个比赛过程中也没扫出来。
比赛结束后看网上别人的正确答案,得知需要把图像以右上到左下的对角线为轴作轴对称。轴对称后又随机填充生成了几张图片,大约有 50% 的图片可以扫描出 flag,结果如图:
处理图片用的脚本(包括轴对称)如下:
from PIL import Image
from random import randint
for k in range(5):
# 用到的三张图片就是上面说的 RGB 通道分开的图片(未放大10倍)
R = Image.open('solved_r.bmp')
G = Image.open('solved_g.bmp')
B = Ima