codeplus 7 彩蛋题汇总:
https://blog.csdn.net/weixin_42378324/article/details/106449375
题面:
初始二维码原图:https://github.com/dq116/codeplus-7/blob/master/QRcode.png
思路:将图像分成3*3,把定位块放回原位,枚举剩余方块的排列。
首先这个3*3,水平方向上容易看出来,竖直方向上一是凭感觉猜,而是plot画一下,根据坐标轴能看出来。
或者用程序跑出来,本文中便是这样方法,这张二维码长宽都是84,定位块最上面的线是的坐标是56,刚好2/3.
分成3*3后枚举剩余的6块全排列,调用zxing包,识别二维码。
注意1:如果没有zxing需要先pip一下,且zxing会调用一些java文件,所以系统中应该有java的jre/jdk
pip install zxing
6个方块的全排列有6!=720种可能
由于初始排列设置的问题,正确答案的位置是622,我82年的本子跑了774秒。。。
代码:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from itertools import permutations
import time
import zxing
#把b2放到b1
def change(b1,b2):
global img2
for i in range(b1[0],b1[1]):
begin=b1[2]
end=b1[3]
vertical_gap=b2[0]-b1[0]
horizontal_gap=b2[2]-b1[2]
for j in range(begin,end):
img2[i,j,:]=img[i + vertical_gap, j +horizontal_gap, :]
def decode_zxing(filename):
zx = zxing.BarCodeReader() # 调用条码读取包
zxdata = zx.decode(filename) # 图片解码
if zxdata and zxdata.parsed:
print(zxdata.parsed)
return True
return False
if __name__ == '__main__':
path=r'path\QRcode.png'
img=np.array(Image.open(path))
m,n,dims=img.shape
# print(m,n)
now=255#white
counter=0
num=3
pos_block=0
for i in range(m):
if img[i][0][0]==0 and now==255:#white turns to black
if counter == num:
pos_block=i
break
counter+=1
now=0
elif img[i][0][0]==255 and now==0:#black turns to white
now=255
# print(pos_block)
for i in range(pos_block,m):
begin=int(n*1/3)
end=int(n*2/3)
for j in range(begin,end):
temp=img[i-pos_block,j-begin,:].copy()
img[i - pos_block, j - begin, :]=img[i,j,:].copy()
img[i,j,:]=temp.copy()
begin=end
end=n
for j in range(begin, end):
temp = img[i - pos_block, j , :].copy()
img[i - pos_block, j , :] = img[i, j, :].copy()
img[i, j, :] = temp.copy()
# plt.imshow(img)
# plt.show()
# 两条竖线两条横线
r1 = int(1 / 3 * m)
r2 = int(2 / 3 * m)
c1 = int(1 / 3 * n)
c2 = int(2 / 3 * n)
b1 = [0, r1, c1, c2]
b2 = [r1, r2, 0, c1]
b3 = [r1, r2, c1, c2]
b4 = [r1, r2, c2, n]
b5 = [r2, m, c1, c2]
b6 = [r2, m, c2, n]
bs = [b1, b2, b3, b4, b5, b6]
img2=img.copy()
#正确的排列
# i = [5, 0, 4, 3, 1, 2]
full_permutation=list(permutations([0,1, 2, 3,4,5]))
counter=0
a = time.perf_counter()
for i in full_permutation:
print(i)
counter+=1
for j in range(6):
change(bs[j],bs[i[j]])
photo=Image.fromarray(img2)
save_path=r'path\QRcode2.png'
photo.save(save_path)
if decode_zxing(save_path):
print(counter)
print("time used:" + str(time.perf_counter()))
break
复原之后: