Skip to content
UseQR
ESC

Jump to

MOVEOPEN50 places

Spec & internals

Why two generators produce different QR codes

Two generators given the same text can legally differ in version selection, error correction default, encoding-mode segmentation and mask choice: all produce valid codes that decode to the same string. A difference only signals a bug when the decoded text differs, most often from mishandled UTF-8 or stray whitespace.

View as MarkdownPaste this page into any AI assistant. It is plain, portable Markdown.

Different picture, same meaning

Encode the same URL in two tools and you will often get two visibly different codes. This alarms people (reasonably, since the codes are supposed to be the URL), but it is the expected consequence of the standard leaving several choices to the implementation. Each choice changes the module pattern without changing what decodes.

The four legitimate sources of difference:

Choice Typical variation Visual effect
Error correction default L, M or Q depending on library different density and pattern
Version selection smallest that fits vs a padded/forced minimum different code size
Mode segmentation one byte-mode run vs optimised mixed segments different bit stream, subtly different pattern
Mask choice scoring-implementation quirks pick a different winner completely different texture

The last one dominates. All eight mask patterns are valid, decoders read all of them, and the penalty-scored search that picks between them is easy to implement with small honest divergences, a slightly different reading of one penalty rule flips the winner, and two codes for the same data share almost no visual texture. Each individual generator is still deterministic; determinism just does not span implementations.

Mode segmentation is worth a concrete example: HELLO-2024 can be encoded as one byte-mode segment (8 bits/character) or one alphanumeric segment (5.5 bits/character), and a sophisticated encoder may split mixed data into multiple mode segments to save bits. All decode identically; the bit streams (and thus the patterns) differ.

When a difference IS a bug

The test is never how the codes look; it is what they decode to. Scan both. If the decoded strings differ at all, one generator is wrong. The recurring culprits:

  • UTF-8 mishandling, the classic. Some libraries truncate each character to its low byte unless told otherwise, silently mangling every non-ASCII character (UseQR's core works around exactly this in its underlying encoder by pre-expanding input to UTF-8 octets). Symptoms and fixes: UTF-8 and Unicode in QR codes.
  • Stray whitespace, a trailing newline picked up from a file or shell pipe encodes invisibly and breaks URLs at the far end.
  • Helpful mutations: tools that add http://, strip parameters, uppercase for alphanumeric mode, or route your URL through their own redirect domain (a business model, not a bug, but the decoded string is no longer your URL; see what free actually means).
  • Wrong ECI/charset signalling for non-Latin text, which decodes correctly on lenient scanners and as mojibake on strict ones.

Comparing images tells you nothing here; comparing decodes tells you everything. Decode with /scan, or use /validate, which renders and decodes in one step and confirms the round-trip matches your input, the discipline behind why you should verify.

Does the visual difference ever matter?

Occasionally, at the margins. A generator that defaults to error correction L produces a sparser code that tolerates less damage; one that defaults to Q produces a denser code that needs more printed size. Neither is wrong, but if you compare tools, compare them at the same stated settings, or you are measuring their defaults, not their correctness.

FAQ

Why does the same URL give different QR codes in different tools?

Because the standard leaves error correction defaults, version selection, mode segmentation and mask scoring to the implementation. Any combination yields a valid code, and mask choice alone can change the entire visual texture. All should decode to the same string.

Are both QR codes valid if they look different?

Almost always yes, different-looking codes for the same data are the normal result of different implementation choices. The only meaningful test is decoding both: identical decoded strings mean both codes are correct.

How do I check if a QR generator is correct?

Scan its output and compare the decoded string byte-for-byte with your input, including any accented or non-Latin characters and the exact URL parameters. A verify tool that renders then decodes automates this round-trip.

One generator's code is bigger for the same text. Why?

It chose a higher error correction level or a padded minimum version. Higher redundancy or forced size means more modules. Set both tools to the same error correction level before comparing sizes.

Try it: free, no signup