碎纸机11
题目

文件

可以看出是把原图裁成等宽的50张图片,每张图片宽20像素
流程
1. 先开始打开图片二进制格式查看文件头发现有xmp元数据,以为隐藏了数据,使用了Metadata Extractor库查看元数据,发现除了文件大小有规律以外其余参数都是一致

java使用这个库的时候别忘记需要将他的依赖一起引入到pom文件中
2. 然后根据文件大小重新排序生成了图片,发现还是乱序依旧没有还原出正确的图片
3. 最后想自己手动拼接发现图片太多无从下手,最后无奈看了一下WriteUp,发现是通过r通道对相邻图片之间的像素查进行比对并调参。主要是对r通道中值部分进行比对,从而得到差值最小的图片组合(不明觉厉),代码如下。
import cv2
import os
import numpy
import copy
import itertools
import math
images = []
def judge(A, B):
diff = 0
for r in range(0, len(A)):
# diff += (A[r][len(A[0]) - 1][0] - B[r][0])[0]
# diff += (A[r][len(A[0]) - 1][1] - B[r][0])[1]
diff += (A[r][len(A[0]) - 1][2] - B[r][0])[2] ** 0.25
return diff
def combine(A, B):
final_matrix = numpy.zeros((len(A), len(A[0]) + len(B[0]), 3), numpy.uint8)
final_matrix[0:len(A), 0:len(A[0])] = A
final_matrix[0:len(A), len(A[0]):len(A[0]) + len(B[0])] = B
return final_matrix
if __name__ == "__main__":
f_images = os.listdir("./images")
for f_image in f_images:
images.append(
cv2.imread(
"images\\" + f_image
)
)
while len(images) > 1:
min_entropy = -1
to_combine = None
for i in range(1, len(images)):
entropy = judge(images[0], images[i])
if min_entropy == -1 or entropy < min_entropy:
min_entropy = entropy
to_combine = i
images[0] = combine(images[0], images[to_combine])
print(len(images), len(images[0][0]))
images.pop(to_combine)
cv2.imwrite("./result.png", images[0])
最后处理出来的图片效果如图:

4. 将opencv处理好的图片扔进ps中进行裁剪将其拼成一个完整的二维码

5. 发现虽然拼成完整二维码但依旧不能扫码,因为中间那个钟的背景颜色影响了二维码中间的像素块,使用ps自动调整亮度和对比度来使得二维码可用

6. 最后扫码得到flag
flag{You Can Repair A Picture From Splices Baesd On Entropy}
总结:
- 在使用java读取元数据的时候尝试过很多库,最后只有Metadata Extractor可用,同时导入依赖的时候注意该库还有依赖也要一起导入,具体版本查阅maven仓库
- 执行python脚本需要安装opencv但是直接安装是会失败的,需要先去opencv的官网下载压缩包,然后将压缩包里找到对应python版本的以.pyd为扩展名的文件,将这个文件放在本机安装的C:\Python310\Lib\site-packages下,最后再执行:
pip install opencv-python
即可安装成功!

浙公网安备 33010602011771号