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

67 lines
1.8 KiB
Markdown

# Quick Response - misc
![](https://notes.c3h2.de/pad/uploads/9a90b18f-69a4-48ea-b747-21651fbe0d41.png)
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())
```
![](https://notes.c3h2.de/pad/uploads/1251408d-9160-4c39-9e94-e2897518cad9.png)
**gigem{d1d_y0u_n0t1c3_th3_t1m1n9_b175}**