"""The QR oracle: two independent implementations, neither of them ours. The Emergency Kit's QR codes are the one artifact in this product that has to be right years after it was printed, on a phone we have never seen, when the person holding it has already lost everything else. "It looks like a QR code" is not verification of that. So every symbol the JS encoder produces is checked twice here: 1. Decoded back to its payload by **ZXing** (zxing-cpp), which is the library most phone scanners are descended from. This answers "will it scan?". 2. Compared **bit-for-bit** against Python's `qrcode` at the same version, EC level and mask. This answers "is it the right symbol?", which decoding alone does not — error correction can hide a real mistake in a symbol that still reads. Neither tool is ours, and they were checked against each other before either was trusted (test/qr.test.mjs's fixtures come from this file). Reads a JSON list of {text, ec, version, mask, modules} on stdin; writes a JSON verdict per case on stdout. Needs: pip install --user zxing-cpp qrcode pillow numpy """ import json import sys import numpy as np import qrcode import zxingcpp from PIL import Image EC = { "L": qrcode.constants.ERROR_CORRECT_L, "M": qrcode.constants.ERROR_CORRECT_M, "Q": qrcode.constants.ERROR_CORRECT_Q, "H": qrcode.constants.ERROR_CORRECT_H, } def to_image(modules, scale=8, quiet=4): """Render a module matrix the way a printer would: dark on white, with the quiet zone the specification requires. Without the quiet zone a correct symbol simply does not decode, which is a real failure mode and not one we want to discover on paper.""" n = len(modules) side = (n + quiet * 2) * scale img = Image.new("L", (side, side), 255) px = img.load() for r in range(n): for c in range(n): if modules[r][c]: for y in range(scale): for x in range(scale): px[(c + quiet) * scale + x, (r + quiet) * scale + y] = 0 return img def reference_matrix(text, ec, mask): """The reference symbol, forced to alphanumeric mode. python-qrcode picks the most efficient mode for the data, so an all-digit payload comes out in numeric mode — a different, equally valid symbol that decodes to the same string. Our encoder is alphanumeric-only by design, so comparing against an auto-selected reference would report a difference that is not a defect. Forcing the mode compares like with like. Real CONTRA codes begin "A1-"/"C1-" and are never all digits, so this only affects synthetic payloads in the sweep — but a test that is wrong on the easy cases teaches you to ignore it on the hard ones.""" q = qrcode.QRCode(error_correction=EC[ec], mask_pattern=mask, border=0) q.add_data(qrcode.util.QRData(text.encode("ascii"), mode=qrcode.util.MODE_ALPHA_NUM)) q.make(fit=True) return [[1 if cell else 0 for cell in row] for row in q.get_matrix()], q.version def check(case): text, ec, mask = case["text"], case["ec"], case["mask"] modules = case["modules"] out = {"text": text, "ec": ec, "mask": mask, "version": case["version"]} # 1. Does it scan? decoded = zxingcpp.read_barcode(np.array(to_image(modules))) out["decoded"] = None if decoded is None else decoded.text out["scans"] = decoded is not None and decoded.text == text # 2. Is it the same symbol another encoder would have made? try: ref, ref_version = reference_matrix(text, ec, mask) out["reference_version"] = ref_version out["same_size"] = len(ref) == len(modules) out["identical"] = out["same_size"] and all( ref[r][c] == modules[r][c] for r in range(len(ref)) for c in range(len(ref)) ) if out["same_size"] and not out["identical"]: out["differing_modules"] = sum( ref[r][c] != modules[r][c] for r in range(len(ref)) for c in range(len(ref)) ) except Exception as exc: # noqa: BLE001 - the verdict carries the reason out["identical"] = False out["reference_error"] = str(exc) out["ok"] = bool(out["scans"] and out.get("identical")) return out def main(): cases = json.load(sys.stdin) print(json.dumps([check(c) for c in cases])) if __name__ == "__main__": main()