Public Test Corpus
Our scanner-compatibility claims are only as good as the evidence they're built on. This page is the corpus, the inputs we regression-test our encoder families against, plus the phone-camera behaviour you can audit yourself without taking our word for any of it.
Download corpus.zip Bundled fixtures JSON + CSV + methodology + README. ~4 KB.
Loading version…
How to use the corpus
Every test vector lives in /test-vectors/fixtures.json. One JSON object per type with the input fields and the expected decoded substring(s). Fetched live from this site, no stale copies.
Take any fixture's fields map, drop the values into the generator for that type, and hit Generate. The resulting QR is bit-for-bit identical to what our CI round-trips against.
Point an iPhone Camera, Android Camera, Google Lens, industrial scanner (Zebra, Honeywell, Datalogic), or app-specific reader (a banking app, an authenticator) at the generated QR. Confirm the decoded text contains every expect substring for that fixture.
If a scanner in your fleet returns a decode that doesn't match the fixture, file an issue. We'll reproduce, add your scanner to the public compatibility matrix, and (if it's an encoder bug) ship a fix.
Expected scan results
Rendered from the same dataset as the compatibility matrix and every type page's "Scans on" line, so the three cannot disagree. The full fixture file at /test-vectors/ has 33 entries, one per encoder family we regression-test; it is not one row per product type, and we do not claim it is.
| Type | Fixture input | iPhone Camera | Android Camera | Pro scanner |
|---|---|---|---|---|
| URL | https://example.com/test | Opens linkA1 | Opens linkA5 | DecodesA8 |
| WiFi | WIFI:S:MyNet;T:WPA;P:...;; | Joins networkA1 | Joins networkA5 | Decodes payloadA8 |
| WiFi Enterprise (EAP) | WPA2-EAP PEAP identity=alice@corp | iOS 17+, reportedU | Decodes; join depends on the OEMU | Decodes payloadQ |
| vCard | FN=Alice ORG=Acme ... | Add to ContactsA1 | Add to ContactsA5 | Decodes payloadA8 |
| TOTP | otpauth://totp/...?secret=JBSW... | Authenticator app reads itA9, A10 | Authenticator app reads itA9, A10 | Decodes URIA8 |
| eSIM | LPA:1$rsp.example.com$K2-LM... | iOS 17.4+ provisionsA4 | Android 13+ provisionsU | Decodes URIQ |
| Bitcoin (BIP-21) | bitcoin:1A1zP1eP... | Wallet app opensQ | Wallet app opensQ | Decodes URIQ |
| SEPA (EPC) | BCD header + name + IBAN + amount | Raw string onlyQ | Raw string onlyQ | Decodes raw stringQ |
| Swiss QR-bill | SPC header + IBAN + address + amount | Raw string onlyQ | Raw string onlyQ | Decodes raw stringQ |
| Micro QR | Compact payload | No decodeV, U | No decodeG | Industrial readersZ |
| rMQR | Rectangular payload | No decodeU | No decodeG | Newer Zebra, Scandit and Cognex firmwareZ |
| GS1 Digital Link | https://id.gs1.org/01/09506000134352 | Opens URLQ | Opens URLQ | POS firmware parses the AIsQ |
| Aztec | Arbitrary payload | No decodeA2 | Google Lens, some variantsA7 | NativeA8 |
| Data Matrix | Arbitrary payload | No decodeA2 | Google LensA6 | NativeA8 |
| PDF417 | AAMVA or arbitrary | No decodeA2 | Google Lens, unevenA7 | NativeA8 |
| AAMVA driver license | @\n\x1e\rANSI 636014100002DL... | iOS 17+ license-aware flowA3 | License-aware apps onlyU | NativeA8 |
| EAN-13 / UPC-A | 0012345678905 | No decodeAp | Google LensG | Every retail POSA8 |
| Code 128 | ABC-123 | No decodeAp | Google LensG | NativeA8 |
How to read the marks
- ✓: reads it from the stock camera app, no extra app needed
- ~: reads it under a condition given in the cell (a specific app, OS version, or mode)
- ✗: does not decode it; you need a scanner app or hardware
Evidence
- A: our own device test; the number is the row in the attestation log
- Ap: Apple's support page describes the Camera app and Code Scanner as reading QR codes and lists no other symbology
- G: Google Lens decodes the ML Kit barcode formats: Codabar, Code 39, Code 93, Code 128, EAN-8, EAN-13, ITF, UPC-A, UPC-E, Aztec, Data Matrix, PDF417 and QR Code; Micro QR and rMQR are not on the list
- Z: Zebra lists Micro QR and rectangular Micro QR among the DS8100 series' 2D symbologies
- V: Apple's Vision framework decodes Micro QR for third-party apps since iOS 15; that is a developer API, not the Camera app
- Q: a standard QR symbol, so decoding is the attested QR result; the question is what the phone does with the payload
- U: not in our attestation log yet; from vendor documentation or field reports, treat as provisional
What "expected scan result" means
- Decodes, native phone-camera reader returns the payload without needing a separate app.
- Partial, decode depends on a specific app (authenticator, wallet, banking) or a specific OS version.
- No decode, native camera returns nothing. Requires a specialist scanner or reader.
- The small letters after each result name the evidence: A plus a number is a row of the attestation log below; other letters are vendor documentation, listed under each table. A U means we have not put that cell through our own devices yet.
Methodology notes
- Every fixture round-trips. Our CI generates each code in headless Chromium, decodes it back via the browser's
BarcodeDetectorAPI, and asserts the substring match. A green CI means the corpus is internally consistent. - Scanner results in this table are from manual testing on real devices. Not synthesized. iPhone 15 Pro on iOS 18.3, Pixel 8 on Android 14, Zebra DS8100 imager on firmware CAAACS00-002-R06.
- We publish negative results. If iPhone Camera refuses to decode a symbology (Data Matrix, Aztec, PDF417), that's a "No decode" in the table, not a rebrand of "native reader".
- The corpus is versioned. When we add a type or fix an encoder bug, the corresponding fixture entry ships in the same commit. The changelog records each fixture change, and corpus.VERSION.txt carries the hash of the fixture file the current ZIP was built from.
Scanner-fleet attestation log
Every manual device run, dated. Rows are added when we acquire hardware or a user reports a discrepancy; a result never changes silently, it gets a new row.
| # | Device | OS / app | Corpus slice | Result | Date | Notes |
|---|---|---|---|---|---|---|
| A1 | iPhone 15 Pro | iOS 18.3, native Camera | All QR fixtures | pass | 2026-04-10 | |
| A2 | iPhone 15 Pro | iOS 18.3, native Camera | Aztec, PDF417, Data Matrix | fail | 2026-04-10 | None decode natively (expected, see /standards/non-qr-2d/) |
| A3 | iPhone 15 Pro | iOS 18.3, native Camera | AAMVA PDF417 | partial | 2026-04-10 | iOS 17+ license-aware flow offers Add to Wallet; raw PDF417 not returned |
| A4 | iPhone 15 Pro | iOS 18.3, Wallet | eSIM LPA | pass | 2026-04-12 | Add-eSIM flow triggers correctly |
| A5 | Pixel 8 | Android 14, native Camera | All QR fixtures | pass | 2026-04-10 | |
| A6 | Pixel 8 | Android 14, Google Lens | Data Matrix | pass | 2026-04-10 | |
| A7 | Pixel 8 | Android 14, Google Lens | Aztec, PDF417 | partial | 2026-04-10 | Some variants decode; support is uneven |
| A8 | Zebra DS8100 | firmware CAAACS00-002-R06 | All 2D + 1D fixtures | pass | 2026-04-11 | Industrial imager, canonical reference |
| A9 | Google Authenticator | v7.0+ (iOS/Android) | TOTP, HOTP | pass | 2026-04-12 | SHA-1 only, 6-digit (ignores algorithm/digits params per Google's de facto profile) |
| A10 | 1Password | v8 (iOS/Android/macOS) | TOTP, HOTP | pass | 2026-04-12 | Full RFC support incl SHA-256, SHA-512, 8-digit |
What's coming
- Pre-rendered artifacts. The current ZIP bundles fixtures + methodology + CSV. A future revision will add pre-rendered SVG + PNG of each fixture so you can drop them straight into a scanner-fleet harness. Pending build-time headless-browser step.
- Scanner-fleet attestation. The dated device log is published on this page and grows each time we verify against a new device.
- Third-party verification. An independent security lab runs the corpus through a scanner fleet and publishes a signed attestation. Pending, commissioned; report will publish here on arrival.
See also
- /test-vectors/, full fixture JSON and searchable table.
- /compatibility/, live scanner compatibility matrix.
- /standards/, per-standard reference pages.
- /print-size/, physical-print guidance that sits alongside the corpus.