简体   繁体   English

解决QR拼图的算法

[英]Algorithm to solve QR puzzle

I am building algorithm to automatically solve / rebuild QR code from number of tiles of equal size. 我正在建立算法,以从相等大小的图块数量自动解决/重建QR码。

My approach: 我的方法:

  1. Get one of 3 side squares : Position squares 获得3个侧方格之一:位置方格
  2. Get the width of outer black border somehow using ImageMagic 使用ImageMagic以某种方式获取外部黑色边框的宽度

在此处输入图片说明

Which for given example is 14px x 14px (UPDATE: it might be 13px by 13px) 对于给定的示例,它是14px x 14px (更新:可能是13px x 13px)

  1. Set it as a constant: BLOCK_SIZE 将其设置为常量:BLOCK_SIZE
  2. Start cycle matching VALID tiles and already compiled block of QR code 开始循环匹配VALID磁贴和已编译的QR码块

VALID is : unmatched AND not any of 3 corner tiles (big black squares) 有效为:无与伦比,也不是3个边角图块(大黑色正方形)中的任何一个

4.1. 4.1。 Render all possible combinations of already compiled qr block AND 1 random valid tile from until the match found 渲染所有已编译的qr块和1个随机有效图块的所有可能组合,直到找到匹配项

4.2 If match found (tile can be placed by one of sides of already compiled/combined block of QR code) then record match 4.2如果找到匹配项(可将其放置在已编译/组合的QR码块的一侧),则记录匹配项

4.3 Match conditions: 4.3比赛条件:

There are no BLACK areas which have width and height conform to this equation: 没有宽度和高度符合以下公式的黑色区域:

AREA_HEIGHT % BLOCK_SIZE  == 0  && AREA_WIDTH % BLOCK_SIZE  == 0

Now there are some implementation complications arise: 现在出现了一些实现方面的复杂性:

  1. How to implement algorithm which matches a tile to tile (OR already compiled/combined block of QR code)? 如何实现将图块与图块匹配的算法(或已编译/组合的QR码块)?

I think ImageMagic can solve it. 我认为ImageMagic可以解决它。 The goal is to get original QR code. 目的是获得原始QR码。

Example QR tiles in ZIP ZIP中的示例QR磁贴

UPDATE 更新

As I see the solution narrows down to make ImageMagick scan and find if two tiles can be put together without breaking rules of QR code. 如我所见,解决方案缩小了范围,可以进行ImageMagick扫描,并确定是否可以在不违反QR码规则的情况下将两个图块放在一起。 Algorithm should try to put 2 tiles side by side and scan border areas. 算法应尝试并排放置2个图块并扫描边界区域。 The trick is to measure width and height of black lines/blocks of joined tiles. 技巧是测量连接的图块的黑色线条/块的宽度和高度。 How to do it? 怎么做?

UPDATE2 更新2

Comparison if tiles match using 2 columns of width 1px is not enough in some cases. 在某些情况下,如果使用2个宽度为1px的列匹配图块是否匹配还不够。 For example, both algorithms will join this 2 tiles into: 例如,两种算法都将这2个图块合并为:

VALID 有效 **有效**

and

INVALID 无效 **无效**

As you seen in INVALID , there is part of 2nd tile (the one on the right) was removed as denoited by red arrows, but since comparison done by 1px - algorithm doesn't care abuot this case. 正如您在INVALID中所看到的那样,第二个磁贴的一部分(右侧的一个)已被删除,如红色箭头所示,但是由于比较是通过1px完成的,因此算法不支持这种情况。 Hance invalid QR. 取消无效的QR码。

UPDATE3 更新3

http://dropcanvas.com/6bl6v http://dropcanvas.com/6bl6v

Archive containing: 存档包含:

  • invalid join.png 无效的join.png

  • valid join.png 有效的join.png

  • src1.png src1.png

  • src2-invalid.png src2-invalid.png

  • src2-valid.png src2-valid.png

  • invalid.png invalid.png

If your algorith will join src1.png and src2-invalid.png it fails. 如果您的算法将加入src1.pngsrc2-invalid.png则它将失败。 It's about if joined tiles will produce valid QR in the end. 关于加入的图块最终是否会产生有效的QR。 I hope you got my point. 我希望你明白我的意思。

UPDATE4 更新4

I will accept an answer after I test and get correct solution. 经过测试并获得正确的解决方案后,我将接受答案。 It might take some time.... 可能需要一些时间。

UPDATE 5 : TESTING 更新5:测试

Everything seems correct with Mark's solution. 马克的解决方案似乎一切都是正确的。

I had a try at this as follows. 我尝试如下。

  1. Go through all PNGs and extract their North, East, South and West edges. 遍历所有PNG并提取其北,东,南和西边缘。 If any PNG has two white edges, tell user it is a corner-piece. 如果任何PNG具有两个白色边缘,请告诉用户它是一个角件。 If any PNG has one white edge, tell user it is an edge-piece. 如果任何PNG具有一个白色边缘,请告诉用户它是一个边缘件。

  2. Go through all edge pieces. 遍历所有边缘部分。 Convert each one into a PBM format file and strip the headers and new lines so that it will just be an 80 digit long string, each digit a zero or a one for black or white. 将每个转换为PBM格式的文​​件,并去除标题和换行符,以便它只是80位数长的字符串,每个位数为零或一个黑色或白色。 Calculate checksum of the string and then reverse the string to account for the image being flipped or rotated and then recalculate the checksum. 计算字符串的校验和,然后反转字符串以说明图像被翻转或旋转,然后重新计算校验和。 Print out the checksums and pipe into sort so that matching edges come out together. 打印出校验和并sort以使匹配的边在一起。

Here is the code: 这是代码:

#!/bin/bash

# Remove any edges generated in previous runs of this script
rm *_[NESW]*png 2> /dev/null
rm *_[NESW]*txt 2> /dev/null

DEBUG=1

# Process all PNGs
for f in *.png; do

   echo "Processing $f ..."

   # Get basename of image
   base=$(basename -s .png "$f")

   # Get width and height - not actually used at the moment
   read w h <<< $(identify -format "%w %h" "$f")
   [ $DEBUG -gt 0 ] && echo "   width:$w"
   [ $DEBUG -gt 0 ] && echo "   height:$h"

   # Extract North edge
   convert "$f" +repage -crop x1+0+0 +repage "${base}_N.png"
   [ $DEBUG -gt 0 ] && echo "   North edge extracted"

   # Extract East edge
   convert "$f" +repage -gravity east -crop 1x+0+0 -rotate 90 +repage "${base}_E.png"
   [ $DEBUG -gt 0 ] && echo "   East edge extracted"

   # Extract South edge
   convert "$f" +repage -gravity south -crop x1+0+0 +repage "${base}_S.png"
   [ $DEBUG -gt 0 ] && echo "   South edge extracted"

   # Extract West edge
   convert "$f" +repage -gravity west -crop 1x+0+0 -rotate 90 +repage "${base}_W.png"
   [ $DEBUG -gt 0 ] && echo "   West edge extracted"

   # Test if corner or edge piece
   n=0
   for edge in N E S W; do
      name="${base}_${edge}.png"
      min=$(identify -format "%[min]" "$name")
      if [ $min -gt 0 ]; then
         ((n++))
         e=$name
      fi
   done
   [ $n -eq 1 ] && echo "   $e is edge-piece"
   [ $n -eq 2 ] && echo "   $name is corner-piece"
done

EDITED FROM HERE ---
# Now convert all edges to text, forwards and backwards to allow rotation
for f in *_[NESW].png; do
   base=$(basename -s png "$f")
   # Convert to PBM format, remove 2 header lines and make into one line string
   str=$(convert "$f" -compress none pbm: | sed "1,2d" | tr -d "\n ")
   echo "$str:$f"
   str=$(rev <<< $str)
   echo "$str:$f (flipped)"
done | sort

Partial Output (to save space) 部分输出(以节省空间)

Processing 4555-18116-29.png ...
   width:80
   height:80
   North edge extracted
   East edge extracted
   South edge extracted
   West edge extracted
   4555-18116-29_S.png is edge-piece
Processing 5004-10810-17642.png ...
   width:80
   height:80
   North edge extracted
   East edge extracted
   South edge extracted
   West edge extracted
   5004-10810-17642_W.png is corner-piece
Processing 5167-27533-24066.png ...
   width:80
   height:80
   North edge extracted
   East edge extracted
   South edge extracted
   West edge extracted
Processing 5774-30645-16062.png ...
   width:80
   height:80
   North edge extracted
   East edge extracted
   South edge extracted
   West edge extracted
0a7bb6f610c0f1a6da4794ea7ae00f00:10297-13918-3702_W.png (flipped)
0a7bb6f610c0f1a6da4794ea7ae00f00:11976-7751-26756_E.png (flipped)   <-- this image is identical to the one above as the md5 checksum on the left is the same
0ce419e072c7ea5d14e3525d4afe150e:11976-7751-26756_W.png (flipped)
0ce419e072c7ea5d14e3525d4afe150e:13858-18007-13070_E.png (flipped)  <-- this image is identical to the one above as the md5 checksum on the left is the same
0ce419e072c7ea5d14e3525d4afe150e:20056-20936-29071_S.png
0ce419e072c7ea5d14e3525d4afe150e:24658-20374-23042_E.png (flipped)
0ce419e072c7ea5d14e3525d4afe150e:24658-20374-23042_S.png
0ce419e072c7ea5d14e3525d4afe150e:27206-10104-18226_N.png
0ce419e072c7ea5d14e3525d4afe150e:30261-16558-25650_N.png

Notes 笔记

Note that this assumes you have not tiled the images EXACTLY between the individual "fields" of the QR codes as identified by @YvesDaoust. 请注意,这假设您尚未像@YvesDaoust所标识的那样在QR码的各个“字段”之间精确地平铺图像。

Also, some parts of the code are redundant, as I was developing the algorithm at the same time as the code - I think the -rotates and +repages are unnecessary and things could be optimised more but there was no indicated need for speed in the question. 另外,代码的某些部分是多余的,因为我在与代码同时开发算法时-我认为-rotates+repages是不必要的,可以进行更多优化,但是在代码中没有显示速度需求题。 The North, East, South and West edges could be extracted in a single IM command too. 北,东,南和西边缘也可以在单个IM命令中提取。 The width and height that I obtained are unused so could be removed from the code. 我获得的宽度和高度尚未使用,因此可以从代码中删除。

Also, the md5 checksum is not really necessary, sort will place 0001110001010110 next to another string the same anyway without needing to checksum them. 另外,md5校验和不是必需的, sort0001110001010110放在另一个字符串旁边,无论如何都不需要校验和。

Per request, I am uploading the complete solution. 根据要求,我正在上载完整的解决方案。 I removed the md5 checksum stuff as it was unnecessary. 我删除了md5校验和,因为这是不必要的。 You will need to scroll right to see the filenames below: 您将需要向右滚动以查看以下文件名:

00000000000000000000000000000000000000000000000000000000000000000000000000000000:10297-13918-3702_N.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:10297-13918-3702_N.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:11976-7751-26756_N.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:11976-7751-26756_N.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:13858-18007-13070_N.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:13858-18007-13070_N.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:16369-21469-8252_E.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:16369-21469-8252_E.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:18056-16294-30425_S.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:18056-16294-30425_S.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:20021-11440-20836_S.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:20021-11440-20836_S.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:20056-20936-29071_W.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:20056-20936-29071_W.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:21875-14159-1067_E.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:21875-14159-1067_E.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:22806-3380-17484_W.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:22806-3380-17484_W.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:24426-18830-5627_E.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:24426-18830-5627_E.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:24658-20374-23042_N.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:24658-20374-23042_N.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:24658-20374-23042_W.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:24658-20374-23042_W.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:27206-10104-18226_S.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:27206-10104-18226_S.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:27206-10104-18226_W.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:27206-10104-18226_W.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:30261-16558-25650_W.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:30261-16558-25650_W.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:31250-3578-9750_E.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:31250-3578-9750_E.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:31250-3578-9750_N.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:31250-3578-9750_N.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:4555-18116-29_S.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:4555-18116-29_S.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:5004-10810-17642_E.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:5004-10810-17642_E.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000000000000000000:5004-10810-17642_S.png
00000000000000000000000000000000000000000000000000000000000000000000000000000000:5004-10810-17642_S.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000111111111111100:21875-14159-1067_S.png (flipped)
00000000000000000000000000000000000000000000000000000000000000000111111111111100:5004-10810-17642_N.png (flipped)
00000000000000000000000000000000000000000000000000000000000001111111111111111111:28824-13023-24184_W.png (flipped)
00000000000000000000000000000000000000000000000000000000000001111111111111111111:5774-30645-16062_E.png (flipped)
00000000000000000000000000000000000000000000000000000000000011111111111111111111:13789-10513-4721_E.png
00000000000000000000000000000000000000000000000000000000000011111111111111111111:32078-14314-1511_W.png
00000000000000000000000000000000000000000000000000000001111111111111000000000000:11976-7751-26756_W.png
00000000000000000000000000000000000000000000000000000001111111111111000000000000:13858-18007-13070_E.png
00000000000000000000000000000000000000000000000000000001111111111111000000000000:20056-20936-29071_S.png (flipped)
00000000000000000000000000000000000000000000000000000001111111111111000000000000:24658-20374-23042_E.png
00000000000000000000000000000000000000000000000000000001111111111111000000000000:24658-20374-23042_S.png (flipped)
00000000000000000000000000000000000000000000000000000001111111111111000000000000:27206-10104-18226_N.png (flipped)
00000000000000000000000000000000000000000000000000000001111111111111000000000000:30261-16558-25650_N.png (flipped)
00000000000000000000000000000000000000000000000000000001111111111111000000000000:31250-3578-9750_W.png
00000000000000000000000000000000000000000000000000000011111111111110000000000000:16369-21469-8252_N.png
00000000000000000000000000000000000000000000000000000011111111111110000000000000:18056-16294-30425_W.png (flipped)
00000000000000000000000000000000000000000000000000000011111111111110000000000000:27206-10104-18226_E.png (flipped)
00000000000000000000000000000000000000000000000000000011111111111110000000000000:31250-3578-9750_S.png
00000000000000000000000000000000000000000000001111111111111111111111111111111111:10297-13918-3702_S.png
00000000000000000000000000000000000000000000001111111111111111111111111111111111:28824-13023-24184_N.png
00000000000000000000000000000000000001111111111111111111111111000000000000000000:20021-11440-20836_N.png (flipped)
00000000000000000000000000000000000001111111111111111111111111000000000000000000:26507-21853-11958_S.png (flipped)
00000000000000000000000000000000000001111111111111111111111111111111111111100000:15816-4564-31665_W.png
00000000000000000000000000000000000001111111111111111111111111111111111111100000:17636-24599-1877_E.png
00000000000000000000000000000000000001111111111111111111111111111111111111111111:21875-14159-1067_W.png
00000000000000000000000000000000000001111111111111111111111111111111111111111111:26507-21853-11958_E.png
00000000000000000000000000000000000011111111111111111111111110000000000000000000:13789-10513-4721_S.png
00000000000000000000000000000000000011111111111111111111111110000000000000000000:17636-24599-1877_N.png
00000000000000000000000000000001111111111111000000000000000000000000001111111111:22161-18187-20222_W.png
00000000000000000000000000000001111111111111000000000000000000000000001111111111:28824-13023-24184_E.png
00000000000000000000000000000011111111111111111111111111111111111111100000000000:15816-4564-31665_E.png (flipped)
00000000000000000000000000000011111111111111111111111111111111111111100000000000:26507-21853-11958_W.png (flipped)
00000000000000000000000000000111111111111111111111111111111111111111000000000000:20056-20936-29071_N.png (flipped)
00000000000000000000000000000111111111111111111111111111111111111111000000000000:22806-3380-17484_S.png (flipped)
00000000000000000000000000001111111111111111111111111111111111111110000000000000:18056-16294-30425_E.png (flipped)
00000000000000000000000000001111111111111111111111111111111111111110000000000000:4555-18116-29_W.png (flipped)
00000000000000000000000000111111111111100000000000001111111111111000000000000011:16369-21469-8252_S.png (flipped)
00000000000000000000000000111111111111100000000000001111111111111000000000000011:24426-18830-5627_N.png (flipped)
00000000000000000000000001111111111111111111111111111111111111110000000000000000:10297-13918-3702_W.png (flipped)
00000000000000000000000001111111111111111111111111111111111111110000000000000000:11976-7751-26756_E.png (flipped)
00000000000000000000000111111111111100000000000001111111111111111111111111111111:13789-10513-4721_N.png
00000000000000000000000111111111111100000000000001111111111111111111111111111111:5774-30645-16062_S.png
00000000000000000000111111111111100000000000000000000000000111111111111100000000:15816-4564-31665_N.png
00000000000000000000111111111111100000000000000000000000000111111111111100000000:32078-14314-1511_S.png
00000000000000000000111111111111100000000000001111111111111111111111111100000000:13789-10513-4721_W.png (flipped)
00000000000000000000111111111111100000000000001111111111111111111111111100000000:22806-3380-17484_E.png (flipped)
00000000000000000001111111111111111111111111000000000000000000000000000000000000:13789-10513-4721_S.png (flipped)
00000000000000000001111111111111111111111111000000000000000000000000000000000000:17636-24599-1877_N.png (flipped)
00000000000000000011111111111100000000000000000000000000111111111111111111111111:22161-18187-20222_S.png
00000000000000000011111111111100000000000000000000000000111111111111111111111111:5167-27533-24066_N.png
00000000000000000011111111111111111111111110000000000000000000000000000000000000:20021-11440-20836_N.png
00000000000000000011111111111111111111111110000000000000000000000000000000000000:26507-21853-11958_S.png
00000000000000001111111111111111111111111111111111111110000000000000000000000000:10297-13918-3702_W.png
00000000000000001111111111111111111111111111111111111110000000000000000000000000:11976-7751-26756_E.png
00000000000001111111111111000000000000000000000000000000000000000000000000000000:16369-21469-8252_N.png (flipped)
00000000000001111111111111000000000000000000000000000000000000000000000000000000:18056-16294-30425_W.png
00000000000001111111111111000000000000000000000000000000000000000000000000000000:27206-10104-18226_E.png
00000000000001111111111111000000000000000000000000000000000000000000000000000000:31250-3578-9750_S.png (flipped)
00000000000001111111111111000000000000011111111111110000000000000111111111111111:21875-14159-1067_N.png (flipped)
00000000000001111111111111000000000000011111111111110000000000000111111111111111:24426-18830-5627_S.png (flipped)
00000000000001111111111111000000000000011111111111111111111111111111111111111100:20021-11440-20836_W.png
00000000000001111111111111000000000000011111111111111111111111111111111111111100:4555-18116-29_E.png
00000000000001111111111111111111111111111111111111110000000000000000000000000000:18056-16294-30425_E.png
00000000000001111111111111111111111111111111111111110000000000000000000000000000:4555-18116-29_W.png
00000000000001111111111111111111111111111111111111111111111111111111111111111100:20021-11440-20836_E.png
00000000000001111111111111111111111111111111111111111111111111111111111111111100:5004-10810-17642_W.png
00000000000011111111111110000000000000000000000000000000000000000000000000000000:11976-7751-26756_W.png (flipped)
00000000000011111111111110000000000000000000000000000000000000000000000000000000:13858-18007-13070_E.png (flipped)
00000000000011111111111110000000000000000000000000000000000000000000000000000000:20056-20936-29071_S.png
00000000000011111111111110000000000000000000000000000000000000000000000000000000:24658-20374-23042_E.png (flipped)
00000000000011111111111110000000000000000000000000000000000000000000000000000000:24658-20374-23042_S.png
00000000000011111111111110000000000000000000000000000000000000000000000000000000:27206-10104-18226_N.png
00000000000011111111111110000000000000000000000000000000000000000000000000000000:30261-16558-25650_N.png
00000000000011111111111110000000000000000000000000000000000000000000000000000000:31250-3578-9750_W.png (flipped)
00000000000011111111111110000000000000111111111111111111111111111111111111111000:22806-3380-17484_N.png
00000000000011111111111110000000000000111111111111111111111111111111111111111000:30261-16558-25650_S.png
00000000000011111111111111111111111111000000000000011111111111111111111111111111:10297-13918-3702_E.png (flipped)
00000000000011111111111111111111111111000000000000011111111111111111111111111111:13858-18007-13070_W.png (flipped)
00000000000011111111111111111111111111111111111111100000000000000000000000000000:20056-20936-29071_N.png
00000000000011111111111111111111111111111111111111100000000000000000000000000000:22806-3380-17484_S.png
00000000000111111111111100000000000000000000000000000000000000111111111111100000:17636-24599-1877_W.png
00000000000111111111111100000000000000000000000000000000000000111111111111100000:20056-20936-29071_E.png
00000000000111111111111100000000000001111111111111000000000000111111111111111111:13858-18007-13070_S.png (flipped)
00000000000111111111111100000000000001111111111111000000000000111111111111111111:22161-18187-20222_N.png (flipped)
00000000000111111111111111111111111111111111111111000000000000000000000000000000:15816-4564-31665_E.png
00000000000111111111111111111111111111111111111111000000000000000000000000000000:26507-21853-11958_W.png
00000000001111111111111000000000000000000000000000000000000001111111111111000000:30261-16558-25650_E.png (flipped)
00000000001111111111111000000000000000000000000000000000000001111111111111000000:5774-30645-16062_W.png (flipped)
00000000001111111111111000000000000000000000000001111111111111111111111111000000:17636-24599-1877_S.png
00000000001111111111111000000000000000000000000001111111111111111111111111000000:18056-16294-30425_N.png
00000000001111111111111000000000000011111111111110000000000001111111111111000000:11976-7751-26756_S.png
00000000001111111111111000000000000011111111111110000000000001111111111111000000:5774-30645-16062_N.png
00000000001111111111111000000000000011111111111111111111111110000000000000111111:16369-21469-8252_W.png (flipped)
00000000001111111111111000000000000011111111111111111111111110000000000000111111:22161-18187-20222_E.png (flipped)
00000000111111111111100000000000000000000000000111111111111100000000000000000000:15816-4564-31665_N.png (flipped)
00000000111111111111100000000000000000000000000111111111111100000000000000000000:32078-14314-1511_S.png (flipped)
00000000111111111111100000000000000000000000000111111111111111111111111110000000:15816-4564-31665_S.png (flipped)
00000000111111111111100000000000000000000000000111111111111111111111111110000000:4555-18116-29_N.png (flipped)
00000000111111111111100000000000001111111111111000000000000011111111111110000000:32078-14314-1511_E.png
00000000111111111111100000000000001111111111111000000000000011111111111110000000:5167-27533-24066_W.png
00000000111111111111111111111111110000000000000000000000000000000000000001111111:28824-13023-24184_S.png (flipped)
00000000111111111111111111111111110000000000000000000000000000000000000001111111:32078-14314-1511_N.png (flipped)
00000000111111111111111111111111110000000000000111111111111100000000000000000000:13789-10513-4721_W.png
00000000111111111111111111111111110000000000000111111111111100000000000000000000:22806-3380-17484_E.png
00000001111111111111000000000000011111111111110000000000000111111111111100000000:32078-14314-1511_E.png (flipped)
00000001111111111111000000000000011111111111110000000000000111111111111100000000:5167-27533-24066_W.png (flipped)
00000001111111111111111111111111100000000000000000000000000111111111111100000000:15816-4564-31665_S.png
00000001111111111111111111111111100000000000000000000000000111111111111100000000:4555-18116-29_N.png
00000011111111111110000000000000000000000000000000000000011111111111110000000000:30261-16558-25650_E.png
00000011111111111110000000000000000000000000000000000000011111111111110000000000:5774-30645-16062_W.png
00000011111111111110000000000001111111111111000000000000011111111111110000000000:11976-7751-26756_S.png (flipped)
00000011111111111110000000000001111111111111000000000000011111111111110000000000:5774-30645-16062_N.png (flipped)
00000011111111111111111111111110000000000000000000000000011111111111110000000000:17636-24599-1877_S.png (flipped)
00000011111111111111111111111110000000000000000000000000011111111111110000000000:18056-16294-30425_N.png (flipped)
00000111111111111100000000000000000000000000000000000000111111111111100000000000:17636-24599-1877_W.png (flipped)
00000111111111111100000000000000000000000000000000000000111111111111100000000000:20056-20936-29071_E.png (flipped)
00000111111111111111111111111100000000000001111111111111111111111111111111111111:26507-21853-11958_N.png
00000111111111111111111111111100000000000001111111111111111111111111111111111111:5167-27533-24066_S.png
00000111111111111111111111111111111111111110000000000000000000000000000000000000:15816-4564-31665_W.png (flipped)
00000111111111111111111111111111111111111110000000000000000000000000000000000000:17636-24599-1877_E.png (flipped)
00011111111111111111111111111111111111111100000000000001111111111111000000000000:22806-3380-17484_N.png (flipped)
00011111111111111111111111111111111111111100000000000001111111111111000000000000:30261-16558-25650_S.png (flipped)
00111111111111100000000000000000000000000000000000000000000000000000000000000000:21875-14159-1067_S.png
00111111111111100000000000000000000000000000000000000000000000000000000000000000:5004-10810-17642_N.png
00111111111111111111111111111111111111111000000000000011111111111110000000000000:20021-11440-20836_W.png (flipped)
00111111111111111111111111111111111111111000000000000011111111111110000000000000:4555-18116-29_E.png (flipped)
00111111111111111111111111111111111111111111111111111111111111111110000000000000:20021-11440-20836_E.png (flipped)
00111111111111111111111111111111111111111111111111111111111111111110000000000000:5004-10810-17642_W.png (flipped)
11000000000000011111111111110000000000000111111111111100000000000000000000000000:16369-21469-8252_S.png
11000000000000011111111111110000000000000111111111111100000000000000000000000000:24426-18830-5627_N.png
11111100000000000001111111111111111111111111000000000000011111111111110000000000:16369-21469-8252_W.png
11111100000000000001111111111111111111111111000000000000011111111111110000000000:22161-18187-20222_E.png
11111110000000000000000000000000000000000000001111111111111111111111111100000000:28824-13023-24184_S.png
11111110000000000000000000000000000000000000001111111111111111111111111100000000:32078-14314-1511_N.png
11111110000000000000000000000000011111111111111111111111111111111111111111111111:24426-18830-5627_W.png (flipped)
11111110000000000000000000000000011111111111111111111111111111111111111111111111:5167-27533-24066_E.png (flipped)
11111111110000000000000000000000000011111111111110000000000000000000000000000000:22161-18187-20222_W.png (flipped)
11111111110000000000000000000000000011111111111110000000000000000000000000000000:28824-13023-24184_E.png (flipped)
11111111111111100000000000001111111111111000000000000011111111111110000000000000:21875-14159-1067_N.png
11111111111111100000000000001111111111111000000000000011111111111110000000000000:24426-18830-5627_S.png
11111111111111111100000000000011111111111110000000000000111111111111100000000000:13858-18007-13070_S.png
11111111111111111100000000000011111111111110000000000000111111111111100000000000:22161-18187-20222_N.png
11111111111111111110000000000000000000000000000000000000000000000000000000000000:28824-13023-24184_W.png
11111111111111111110000000000000000000000000000000000000000000000000000000000000:5774-30645-16062_E.png
11111111111111111111000000000000000000000000000000000000000000000000000000000000:13789-10513-4721_E.png (flipped)
11111111111111111111000000000000000000000000000000000000000000000000000000000000:32078-14314-1511_W.png (flipped)
11111111111111111111111100000000000000000000000000111111111111000000000000000000:22161-18187-20222_S.png (flipped)
11111111111111111111111100000000000000000000000000111111111111000000000000000000:5167-27533-24066_N.png (flipped)
11111111111111111111111111111000000000000011111111111111111111111111000000000000:10297-13918-3702_E.png
11111111111111111111111111111000000000000011111111111111111111111111000000000000:13858-18007-13070_W.png
11111111111111111111111111111110000000000000111111111111100000000000000000000000:13789-10513-4721_N.png (flipped)
11111111111111111111111111111110000000000000111111111111100000000000000000000000:5774-30645-16062_S.png (flipped)
11111111111111111111111111111111110000000000000000000000000000000000000000000000:10297-13918-3702_S.png (flipped)
11111111111111111111111111111111110000000000000000000000000000000000000000000000:28824-13023-24184_N.png (flipped)
11111111111111111111111111111111111110000000000000111111111111111111111111100000:26507-21853-11958_N.png (flipped)
11111111111111111111111111111111111110000000000000111111111111111111111111100000:5167-27533-24066_S.png (flipped)
11111111111111111111111111111111111111111110000000000000000000000000000000000000:21875-14159-1067_W.png (flipped)
11111111111111111111111111111111111111111110000000000000000000000000000000000000:26507-21853-11958_E.png (flipped)
11111111111111111111111111111111111111111111111000000000000000000000000001111111:24426-18830-5627_W.png
11111111111111111111111111111111111111111111111000000000000000000000000001111111:5167-27533-24066_E.png

This one was easy, if one uses all the info available in the individual tile PNGs: 如果使用单个磁贴PNG中的所有可用信息,则此操作很简单:

QR码(解决方案)

The QR reader says: http://www.oracle.com/javaone/index.html QR阅读器说: http : //www.oracle.com/javaone/index.html

It took me less than 3 minutes to come up with the solution -- mainly because I had to type the respective command with one hand while being on the phone at the same time.... 我花了不到3分钟的时间才提出解决方案-主要是因为我必须同时在打电话时用一只手键入相应的命令....

How did you produce the tiles? 您是如何生产瓷砖的?

Update 更新资料

Now that @RCola has finally answered my question ( "How did you produce the tiles?" ), I'll reveal how I came up so fast with the correct QR code image. 现在,@ RCola终于回答了我的问题( “您是如何生产这些瓷砖的?” ),我将介绍如何快速使用正确的QR码图像。

I did not use an algorithm as he had asked for. 我没有使用他所要求的算法。 I used a "side-channel" attack, by-passing any need to think about such an algorithm. 我使用了“旁通道”攻击,绕过了考虑这种算法的任何需求。

This side-channel used an "information leak" which was contained in the tile images provided in @RCola's ZIP file. 该副渠道使用了“信息泄漏”,该泄漏包含在@RCola的ZIP文件中提供的切片图像中。 This info is leaked when running a simple identify command. 运行简单的identify命令时,此信息会泄漏。 Here I run it not as a 'simple' command, but -- to make the leaked information more obvious -- as a command that forces a specific output format: 在这里,我不是将其作为“简单”命令来运行,而是(为了使泄漏的信息更加明显)作为强制特定输出格式的命令来运行:

identify -format "%f :  %g\n" {1,2,3,4,5}*.png

  10297-13918-3702.png :  400x400+160+0
  11976-7751-26756.png :  400x400+80+0
  13789-10513-4721.png :  400x400+80+160
 13858-18007-13070.png :  400x400+240+0
  15816-4564-31665.png :  400x400+160+240
  16369-21469-8252.png :  400x400+320+80
  17636-24599-1877.png :  400x400+80+240
 18056-16294-30425.png :  400x400+80+320
 20021-11440-20836.png :  400x400+240+320
 20056-20936-29071.png :  400x400+0+240
  21875-14159-1067.png :  400x400+320+240
 22161-18187-20222.png :  400x400+240+80
  22806-3380-17484.png :  400x400+0+160
  24426-18830-5627.png :  400x400+320+160
 24658-20374-23042.png :  400x400+0+0
 26507-21853-11958.png :  400x400+240+240
 27206-10104-18226.png :  400x400+0+320
 28824-13023-24184.png :  400x400+160+80
 30261-16558-25650.png :  400x400+0+80
   31250-3578-9750.png :  400x400+320+0
  32078-14314-1511.png :  400x400+160+160
     4555-18116-29.png :  400x400+160+320
  5004-10810-17642.png :  400x400+320+320
  5167-27533-24066.png :  400x400+240+160
  5774-30645-16062.png :  400x400+80+80

(The same information would be contained in the output of identify {1,2,3,4,5}*.png -- it would just not jump out so obviously.) (相同的信息将包含在identify {1,2,3,4,5}*.png的输出中—显然不会跳出来。)

What does this show? 这说明什么? The %g percent-escape prints the geometry information about the canvas associated with the PNG tile: %g percent-escape打印有关与PNG磁贴相关联的画布的几何信息:

  1. 400x400 is the overall size of this tile's canvas. 400x400是此图块画布的整体大小。 It is obvious, that this was the size of the original PNG representing the complete QR code. 显然,这就是代表完整QR码的原始PNG的大小。
  2. +X+Y is the offset associated with this tile on the complete canvas. +X+Y是与此画布在整个画布上关联的偏移量

Using this info makes it extremely easy to directly know which PNG tile has to be placed on which location of the puzzle: 使用此信息可以非常轻松地直接知道必须在拼图的哪个位置放置哪个PNG磁贴:

  • +0+0 obviously has to go to the top left corner +0+0显然必须转到左上角
  • +0+80 obviously goes just below that +0+80明显低于该值
  • +80+0 obviously goes just right of the top left corner +80+0显然位于左上角的右边
  • ...and so on and so forth, until ...依此类推,直到
  • +320+320 goes into bottom right corner +320+320进入右下角

The OP could have avoided that side-channel info leak (which in this case gives the complete game away) by adding the +repage parameter to the IM command he used to produce the tiles. 通过将+repage参数添加到他用来生成图块的IM命令中,OP可以避免该边路信息泄漏(在这种情况下,它可以使整个游戏失败)。

In order to "repair" the leaky tiles he provided and produce more challenging ones I did this: 为了“修复”他提供的漏水砖并制作更具挑战性的漏水砖,我做到了:

 mkdir challenge

 for i in {1,2,3,4,5}*.png; do
     convert $i +repage challenge/$i
 done

Update 2 更新2

(In answer to the comment which despaired about the failure to "see" the info with the help of a hex editor...) (回答对无法通过十六进制编辑器“查看”信息感到绝望的评论...)

The same info as identify reveals could be obtained with the help of exiftool too (albeit in a less "accessible" form): 也可以借助exiftool获得与identify显示相同的信息(尽管以“访问性较差”的形式):

exiftool 11976-7751-26756.png  | grep -E '(Virtual Image|Width|Height|Offset)'
 Image Width                     : 80
 Image Height                    : 80
 Image Offset                    : 80, 0 (pixels)
 Virtual Image Width             : 400
 Virtual Image Height            : 400

Here is a better algorithm, which I scripted already: 这是一个更好的算法,我已经编写了脚本:

  1. From each tile, shave off a 1 pixel row or column from each edge, and output it to ImageMagick's special *.text format, using names which indicate their respective left/right or top/bottom edge origin. 在每个图块上,从每个边缘上去除1个像素行或列,然后将其输出为ImageMagick的特殊*.text格式,并使用表示其各自左/右或上/下边缘原点的名称。

  2. Convert each such column/row, create the md5sum of its *.txt and sort these alphabetically. 转换每个这样的列/行,创建其*.txtmd5sum ,然后按字母顺序对它们进行排序。

  3. Determine which MD5 sums are identical. 确定哪些MD5和是相同的。

  4. Determine from the identical MD5 sums the candidates which would fit at the respective border. 从相同的MD5中确定适合各个边界的候选值。

Code snippet 程式码片段

for i in {1,2,3,4,5}*.png; do
  convert ${i}[1x80+0+0]  +repage left---edge-${i/.png/.text}
  convert ${i}[1x80+79+0] +repage right--edge-${i/.png/.text}
  convert ${i}[80x1+0+0]  +repage top----edge-${i/.png/.text}
  convert ${i}[80x1+0+79] +repage bottom-edge-${i/.png/.text}
done

One example how such a text file may look is this: 这样的文本文件看起来可能是一个示例:

cat right--edge-5167-27533-24066.text

# ImageMagick pixel enumeration: 1,80,255,gray
0,0: (0,0,0)  #000000  gray(0)
0,1: (0,0,0)  #000000  gray(0)
0,2: (0,0,0)  #000000  gray(0)
0,3: (0,0,0)  #000000  gray(0)
0,4: (0,0,0)  #000000  gray(0)
0,5: (0,0,0)  #000000  gray(0)
0,6: (0,0,0)  #000000  gray(0)
0,7: (255,255,255)  #FFFFFF  gray(255)
0,8: (255,255,255)  #FFFFFF  gray(255)
0,9: (255,255,255)  #FFFFFF  gray(255)
0,10: (255,255,255)  #FFFFFF  gray(255)
0,11: (255,255,255)  #FFFFFF  gray(255)
0,12: (255,255,255)  #FFFFFF  gray(255)
0,13: (255,255,255)  #FFFFFF  gray(255)
0,14: (255,255,255)  #FFFFFF  gray(255)
0,15: (255,255,255)  #FFFFFF  gray(255)
0,16: (255,255,255)  #FFFFFF  gray(255)
0,17: (255,255,255)  #FFFFFF  gray(255)
0,18: (255,255,255)  #FFFFFF  gray(255)
0,19: (255,255,255)  #FFFFFF  gray(255)
0,20: (255,255,255)  #FFFFFF  gray(255)
0,21: (255,255,255)  #FFFFFF  gray(255)
0,22: (255,255,255)  #FFFFFF  gray(255)
0,23: (255,255,255)  #FFFFFF  gray(255)
0,24: (255,255,255)  #FFFFFF  gray(255)
0,25: (255,255,255)  #FFFFFF  gray(255)
0,26: (255,255,255)  #FFFFFF  gray(255)
0,27: (255,255,255)  #FFFFFF  gray(255)
0,28: (255,255,255)  #FFFFFF  gray(255)
0,29: (255,255,255)  #FFFFFF  gray(255)
0,30: (255,255,255)  #FFFFFF  gray(255)
0,31: (255,255,255)  #FFFFFF  gray(255)
0,32: (255,255,255)  #FFFFFF  gray(255)
0,33: (0,0,0)  #000000  gray(0)
0,34: (0,0,0)  #000000  gray(0)
0,35: (0,0,0)  #000000  gray(0)
0,36: (0,0,0)  #000000  gray(0)
0,37: (0,0,0)  #000000  gray(0)
0,38: (0,0,0)  #000000  gray(0)
0,39: (0,0,0)  #000000  gray(0)
0,40: (0,0,0)  #000000  gray(0)
0,41: (0,0,0)  #000000  gray(0)
0,42: (0,0,0)  #000000  gray(0)
0,43: (0,0,0)  #000000  gray(0)
0,44: (0,0,0)  #000000  gray(0)
0,45: (0,0,0)  #000000  gray(0)
0,46: (0,0,0)  #000000  gray(0)
0,47: (0,0,0)  #000000  gray(0)
0,48: (0,0,0)  #000000  gray(0)
0,49: (0,0,0)  #000000  gray(0)
0,50: (0,0,0)  #000000  gray(0)
0,51: (0,0,0)  #000000  gray(0)
0,52: (0,0,0)  #000000  gray(0)
0,53: (0,0,0)  #000000  gray(0)
0,54: (0,0,0)  #000000  gray(0)
0,55: (0,0,0)  #000000  gray(0)
0,56: (0,0,0)  #000000  gray(0)
0,57: (0,0,0)  #000000  gray(0)
0,58: (0,0,0)  #000000  gray(0)
0,59: (0,0,0)  #000000  gray(0)
0,60: (0,0,0)  #000000  gray(0)
0,61: (0,0,0)  #000000  gray(0)
0,62: (0,0,0)  #000000  gray(0)
0,63: (0,0,0)  #000000  gray(0)
0,64: (0,0,0)  #000000  gray(0)
0,65: (0,0,0)  #000000  gray(0)
0,66: (0,0,0)  #000000  gray(0)
0,67: (0,0,0)  #000000  gray(0)
0,68: (0,0,0)  #000000  gray(0)
0,69: (0,0,0)  #000000  gray(0)
0,70: (0,0,0)  #000000  gray(0)
0,71: (0,0,0)  #000000  gray(0)
0,72: (0,0,0)  #000000  gray(0)
0,73: (0,0,0)  #000000  gray(0)
0,74: (0,0,0)  #000000  gray(0)
0,75: (0,0,0)  #000000  gray(0)
0,76: (0,0,0)  #000000  gray(0)
0,77: (0,0,0)  #000000  gray(0)
0,78: (0,0,0)  #000000  gray(0)
0,79: (0,0,0)  #000000  gray(0)

As you can see, it is a textual description for each pixel's color of the extracted column (where the pixel coordinates are given in the first field of each line of text). 如您所见,它是提取列的每个像素颜色的文字描述(其中像素坐标在每行文本的第一字段中给出)。 The first line indicates which color space is used. 第一行指示使用哪个颜色空间。

*Sort MD5 sums alphabetically *按字母顺序对MD5进行求和

When sorting the MD5 sums of these text files alphabetically, it should be immediately obvious where there are identical pixel color rows and columns: 当按字母顺序对这些文本文件的MD5总和进行排序时,在具有相同像素颜色的行和列的地方应该立即显而易见:

md5sum *.text | sort

Results: 结果:

(I manually added a few comments at the end of some lines.) (我在某些行的末尾手动添加了一些注释。)

09c0670b59c03fb3d6f8116ee0fe35a2  bottom-edge-10297-13918-3702.text
09c0670b59c03fb3d6f8116ee0fe35a2  top----edge-28824-13023-24184.text
10be914aa8b6aaa8c0e35a4a93421f3a  left---edge-20056-20936-29071.text  #left edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  left---edge-22806-3380-17484.text   #left edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  left---edge-24658-20374-23042.text  #left edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  left---edge-27206-10104-18226.text  #left edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  left---edge-30261-16558-25650.text  #left edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  right--edge-16369-21469-8252.text   #right edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  right--edge-21875-14159-1067.text   #right edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  right--edge-24426-18830-5627.text   #right edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  right--edge-31250-3578-9750.text    #right edge of QR
10be914aa8b6aaa8c0e35a4a93421f3a  right--edge-5004-10810-17642.text   #right edge of QR
217c799ce772d99e11b7ba2a04f42bb7  bottom-edge-11976-7751-26756.text
217c799ce772d99e11b7ba2a04f42bb7  top----edge-5774-30645-16062.text
2c96cebc6cc175b54cae54f1a27771fa  bottom-edge-24426-18830-5627.text
2c96cebc6cc175b54cae54f1a27771fa  top----edge-21875-14159-1067.text
3088414b0fe1190bbd4ed9315d86a0ac  left---edge-13789-10513-4721.text
3088414b0fe1190bbd4ed9315d86a0ac  right--edge-22806-3380-17484.text
3755d45bb6ad21b70f545f39c5550eda  left---edge-17636-24599-1877.text
3755d45bb6ad21b70f545f39c5550eda  right--edge-20056-20936-29071.text
41fc32b4b70622b4aff7d9e81f81daad  left---edge-13858-18007-13070.text
41fc32b4b70622b4aff7d9e81f81daad  right--edge-10297-13918-3702.text
480bed740a716fa10593ba061c5b6df5  left---edge-5004-10810-17642.text
480bed740a716fa10593ba061c5b6df5  right--edge-20021-11440-20836.text
55cc4713ee13ebbeb5c2e212e430da94  bottom-edge-28824-13023-24184.text
55cc4713ee13ebbeb5c2e212e430da94  top----edge-32078-14314-1511.text
62fecd6971445d4176a842727767d3f7  left---edge-4555-18116-29.text
62fecd6971445d4176a842727767d3f7  right--edge-18056-16294-30425.text
69565761226f122f98267862108119a6  left---edge-21875-14159-1067.text
69565761226f122f98267862108119a6  right--edge-26507-21853-11958.text
72cec2b0a518c2cce7204188923d9f79  left---edge-26507-21853-11958.text
72cec2b0a518c2cce7204188923d9f79  right--edge-15816-4564-31665.text
7343348f1b10e47b33e0bde47b455c2b  left---edge-16369-21469-8252.text
7343348f1b10e47b33e0bde47b455c2b  right--edge-22161-18187-20222.text
7661c257d28e1916208ed2a70989e42d  bottom-edge-13789-10513-4721.text
7661c257d28e1916208ed2a70989e42d  top----edge-17636-24599-1877.text
7d2a0d7aae6dc017ffa7af7180b1c017  left---edge-5167-27533-24066.text
7d2a0d7aae6dc017ffa7af7180b1c017  right--edge-32078-14314-1511.text
85b744d1774cd4ebe50f0cc40d10b491  left---edge-18056-16294-30425.text
85b744d1774cd4ebe50f0cc40d10b491  right--edge-27206-10104-18226.text
88942ff37ce0e884d1995a6dd11708d6  left---edge-10297-13918-3702.text
88942ff37ce0e884d1995a6dd11708d6  right--edge-11976-7751-26756.text
9185daee4fdcea482c9fa805bba40346  bottom-edge-31250-3578-9750.text
9185daee4fdcea482c9fa805bba40346  top----edge-16369-21469-8252.text
9b8a7f18e4ebbc7249e5f26ac18190a8  left---edge-28824-13023-24184.text
9b8a7f18e4ebbc7249e5f26ac18190a8  right--edge-5774-30645-16062.text
9bd8f7a474229aefd988c4231f3b26f4  bottom-edge-21875-14159-1067.text
9bd8f7a474229aefd988c4231f3b26f4  top----edge-5004-10810-17642.text
a1778c1a468c122bf408a9c2bec9135c  bottom-edge-13858-18007-13070.text
a1778c1a468c122bf408a9c2bec9135c  top----edge-22161-18187-20222.text
a4f3eee0e523f1b343d292987da297b3  bottom-edge-20056-20936-29071.text
a4f3eee0e523f1b343d292987da297b3  bottom-edge-24658-20374-23042.text
a4f3eee0e523f1b343d292987da297b3  top----edge-27206-10104-18226.text
a4f3eee0e523f1b343d292987da297b3  top----edge-30261-16558-25650.text
af851da184ea6d6586c64aaefdc6875b  bottom-edge-22806-3380-17484.text
af851da184ea6d6586c64aaefdc6875b  top----edge-20056-20936-29071.text
b4047de9fb6458ebfde5b3a11b40241a  left---edge-5774-30645-16062.text
b4047de9fb6458ebfde5b3a11b40241a  right--edge-30261-16558-25650.text
b58fe9214967f6d2311e11cb0bf1acc4  left---edge-15816-4564-31665.text
b58fe9214967f6d2311e11cb0bf1acc4  right--edge-17636-24599-1877.text
bef4d7004da4f5de4ca5beeabc1222e8  bottom-edge-5774-30645-16062.text
bef4d7004da4f5de4ca5beeabc1222e8  top----edge-13789-10513-4721.text
c042d1cd3dfb339177e8da3c2907d58e  bottom-edge-15816-4564-31665.text
c042d1cd3dfb339177e8da3c2907d58e  top----edge-4555-18116-29.text
c5f38ebda77190495d77df1fb7002d1e  bottom-edge-32078-14314-1511.text
c5f38ebda77190495d77df1fb7002d1e  top----edge-15816-4564-31665.text
c61f738453fa3a86b52b2de5c0d43530  left---edge-20021-11440-20836.text
c61f738453fa3a86b52b2de5c0d43530  right--edge-4555-18116-29.text
c772762652d22cbf228e57f0dcf1a3b4  bottom-edge-22161-18187-20222.text
c772762652d22cbf228e57f0dcf1a3b4  top----edge-5167-27533-24066.text
cfaa399406e0be3d07297f23c684e7c3  left---edge-11976-7751-26756.text
cfaa399406e0be3d07297f23c684e7c3  left---edge-31250-3578-9750.text
cfaa399406e0be3d07297f23c684e7c3  right--edge-13858-18007-13070.text
cfaa399406e0be3d07297f23c684e7c3  right--edge-24658-20374-23042.text
d39c2a0c14c20b66b441d368c164171d  bottom-edge-18056-16294-30425.text  #bottom edge of QR
d39c2a0c14c20b66b441d368c164171d  bottom-edge-20021-11440-20836.text  #bottom edge of QR
d39c2a0c14c20b66b441d368c164171d  bottom-edge-27206-10104-18226.text  #bottom edge of QR
d39c2a0c14c20b66b441d368c164171d  bottom-edge-4555-18116-29.text      #bottom edge of QR
d39c2a0c14c20b66b441d368c164171d  bottom-edge-5004-10810-17642.text   #bottom edge of QR
d39c2a0c14c20b66b441d368c164171d  top----edge-10297-13918-3702.text   #top edge of QR
d39c2a0c14c20b66b441d368c164171d  top----edge-11976-7751-26756.text   #top edge of QR
d39c2a0c14c20b66b441d368c164171d  top----edge-13858-18007-13070.text  #top edge of QR
d39c2a0c14c20b66b441d368c164171d  top----edge-24658-20374-23042.text  #top edge of QR
d39c2a0c14c20b66b441d368c164171d  top----edge-31250-3578-9750.text    #top edge of QR
d71e7b561d2cc251c962a843daff53bb  bottom-edge-5167-27533-24066.text
d71e7b561d2cc251c962a843daff53bb  top----edge-26507-21853-11958.text
d7ffe4aaf744387e7fa9db32271247e0  bottom-edge-26507-21853-11958.text
d7ffe4aaf744387e7fa9db32271247e0  top----edge-20021-11440-20836.text
da2aa01201b3da20a970928bc2bdef36  bottom-edge-30261-16558-25650.text
da2aa01201b3da20a970928bc2bdef36  top----edge-22806-3380-17484.text
dd86f02cfc0e260463c75ae5b8709f33  bottom-edge-16369-21469-8252.text
dd86f02cfc0e260463c75ae5b8709f33  top----edge-24426-18830-5627.text
dfdaa88ebf33284ac0367f92060cd060  bottom-edge-17636-24599-1877.text
dfdaa88ebf33284ac0367f92060cd060  top----edge-18056-16294-30425.text
f8e2f384f2269e086dc00fb6ff0b3f41  left---edge-32078-14314-1511.text
f8e2f384f2269e086dc00fb6ff0b3f41  right--edge-13789-10513-4721.text
fa59372704f3b48912a33f3780e9dce7  left---edge-22161-18187-20222.text
fa59372704f3b48912a33f3780e9dce7  right--edge-28824-13023-24184.text
fff7e26c6f9852fcfa51e79d154dc58a  left---edge-24426-18830-5627.text
fff7e26c6f9852fcfa51e79d154dc58a  right--edge-5167-27533-24066.text

One can immediately identify the following pattern: 可以立即识别出以下模式:

  1. 10 identical MD5 sums of d39c2a0c14c20b66b441d368c164171d d39c2a0c14c20b66b441d368c164171d 10个相同的MD5总和
  2. 10 identical MD5 sums of 10be914aa8b6aaa8c0e35a4a93421f3a 10be914aa8b6aaa8c0e35a4a93421f3a 10个相同的MD5总和
  3. 20 pairs of identical MD5 sums for left/right edges 左右边缘20对相同的MD5总和
  4. 20 pairs of identical MD5 sums for top/bottom edges 上下边缘的20对相同的MD5总和

In the case of '1.' 在“ 1”的情况下。 and '2.' 和“ 2”。 it is easy to see that these are all-white edges, representing left/right/top/bottom pieces of the complete QR. 可以很容易地看到它们是全白色的边缘,代表完整QR的左/右/上/下部分。

The rest of the matches, '3.' 其余比赛,“ 3”。 and '4.' 和“ 4”。 make it easy to fit each individual tile to a left or right "partner" in a deterministic way. 使您可以轻松地以确定性的方式将每个单独的图块安装到左侧或右侧“伙伴”。


Update 更新资料

I've not seen Mark's answer until now. 直到现在我还没有看到马克的答案。 But I see his approach is similar to mine. 但是我看到他的方法与我的相似。

I'm not willing to add my complete script to produce the final re-composed QR code though. 不过,我不愿意添加完整的脚本来生成最终的重组QR码。

So if Mark's solution includes this, he should get the approvement for the correct answer. 因此,如果Mark的解决方案包括这一点,那么他应该获得正确答案的批准。

I understand about nothing of your explanations but for matching tiles it suffices to compare the pixels along the common edge. 我对您的解释一无所知,但要匹配图块,就足以比较公共边缘上的像素。 This is because the splits are made across the QR cells, not between them. 这是因为拆分是在QR单元之间而不是在QR单元之间进行的。

You can work filling the array row by row, every time trying all unused blocks until you find a match. 您可以逐行填充数组,每次尝试使用所有未使用的块直到找到匹配项。 Actually several matches could arise by coincidence, so it is advisable to continue the search even after a match has been found. 实际上,碰巧可能会出现多个匹配项,因此即使找到匹配项,也建议继续搜索。 This will lead to a recursive implementation. 这将导致递归实现。

The corners and their immediate neighbors are easier to place by hand. 角落和它们的近邻更容易用手放置。 With a little scrutiny, you can also find the blocks with the timing pattern. 仔细检查一下,您还可以找到带有时序模式的块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM