writeups2026tamu/Quick-Response-misc.md
2026-04-01 21:47:42 +02:00

1.8 KiB

Quick Response - misc

fridgebuyer

  • The QR is 29x29 == version 3
  • Each module = 32x32 px
  • What should be solid is alternated. The 7x7 finder patterns should be solid but are not visible in the 3 corners (top left, bottom left, top right)
  • What should be alternated are solid lines (timing strips)
  • So the original QR was likely XORed with a Checkerboard pattern
  • https://www.pclviewer.com/rs2/qrmasking.htm Mask 000: (i + j) mod 2 = 0 is this
  • But this was applied to entire qr code, not only to the data region
  • So need to XOR every module with (row + col) % 2 again.

sol

from PIL import Image
import numpy as np
from pyzbar.pyzbar import decode

img = Image.open("quick-response.png").convert("RGB")
arr = np.array(img)

# extract module grid 
module_size = 32
n = 29
dark = np.array([20, 22, 27])

grid = np.zeros((n, n), dtype=int)
for r in range(n):
    for c in range(n):
        cy = r * module_size + module_size // 2
        cx = c * module_size + module_size // 2
        pixel = arr[cy, cx]
        if np.sum((pixel.astype(int) - dark.astype(int)) ** 2) < 100:
            grid[r, c] = 1

# XOR (i + j) mod 2 = 0
for r in range(n):
    for c in range(n):
        grid[r, c] ^= (r + c) % 2

# write fixed QR code
scale = 10
border = 4
total = (n + 2 * border) * scale
out = Image.new("L", (total, total), 255)
px = out.load()
for r in range(n):
    for c in range(n):
        if grid[r, c] == 1:
            for dy in range(scale):
                for dx in range(scale):
                    px[(c + border) * scale + dx, (r + border) * scale + dy] = 0

result = decode(out)
for r in result:
    print(r.data.decode())

gigem{d1d_y0u_n0t1c3_th3_t1m1n9_b175}