Gefällt dir dieser Artikel?

QR Codes: Funktionsweise und Aufbau

erschienen in der Kategorie Technik, am 13.08.2025
Schnatterente
Nachdem wir uns vorgestern damit beschäftigt haben, wie QR-Codes entstanden sind und uns gestern angesehen haben, was man alles mit ihnen machen kann und wie man sie erstellt, wollen wir uns heute mal der Frage widmen, wie sie technisch funktionieren. Auf diesem Wissen aufbauend, habe ich zudem noch ein paar wertvolle Tipps für euch, wie man bei der Generierung vieler QR-Codes zu einheitlichen Ergebnissen kommt.

Wie ist ein QR-Code aufgebaut?

HIer ist eine schematische Darstellung des Aufbaus eines QR-Codes:
QR Code Aufbau
Die kleinen Kacheln eines QR-Codes werden als Module bezeichnet. Sie können nur zwei Farben haben – entsprechend wird klar, dass es sich beim QR-Code um eine Darstellung für einen Binärcode handelt. Jedes Modul zeigt den Zustand eines einzelnen Bits (0 oder 1).

Das Modul unten links, das hier mit einem gelben Punkt markiert ist, heißt Dark Module und repräsentiert die verwendete Farbe für die dunklen Module. Wie man an den weiter unten folgenden Beispielgrafiken aber gut sehen kann, muss die Farbe eigentlich gar nicht einheitlich sein – wichtig ist vor allem ein ausreichender Kontrast.

Die vielen grau dargestellten Module sind die eigentlichen Nutzdaten des QR-Codes, die je nach verwendetem Fehlerkorrekturverfahren mit mehr oder weniger viel Redundanz eingebettet werden. Zu den Details dazu kommen wir gleich noch …

Der Rahmen um den QR-Code (hier grün dargestellt) wird als Quiet Zone (Ruhezone) bezeichnet und dient der klaren Abgrenzung von anderen grafischen Elementen.

Die drei großen Felder an den äußeren Ecken heißen Finder (in der Grafik "Position") und dienen der Positionsbestimmung. Wie vorgestern schon erläutert, wurden sie eingeführt, damit man QR-Codes von jeder Richtung aus einlesen kann und sich keine Gedanken darüber zu machen braucht, wie rum man sein Telefon oder Lesegerät dabei halten muss. Anhand der Stelle des fehlenden Finders kann die korrekte Orientierung einfach bestimmt werden.

Ebenfalls zur (besseren) Positionsbestimmung dienen die Alignments, die im Datenmuster des QR-Codes untergebracht sind. Je nach QR-Code-Größe (Version) gibt es sie gar nicht, nur einmal oder mehrfach. Die Alignments sind vor allem dafür da, Verzerrungen bei schräg fotografierten QR-Codes zu erkennen.

Zwischen den Findern verlaufen zwei Synchronisationslinien (in der Grafik "Timing"), die die Matrixgröße definieren und immer abwechselnd dunkle und helle Module enthalten.

Der fliederfarben markierte Datenbereich enthält die Version des QR-Codes. Sie ist ist hier zwei Mal vorhanden. Diese Dopplung dient dem Erhalt der Scanbarkeit des QR-Codes, wenn dieser an einer der Stellen beschädigt oder verdeckt wird.
Bei QR-Codes mit einer Version kleiner Sieben fehlt die Versionsangabe. In diesem Fall muss sie der Scanner selbst aus der QR-Code-Größe ermitteln. (Dabei werden die Größen der Finder, der Module erfasst und deren Abstände analysiert.)

Ist die Versionsangabe vorhanden, besteht sie aus 18 Bits. Sechs Bits werden für die Versionsnummer benötigt (Zahlen von 7 bis 40), die zusätzlichen 12 Bits dienen "nur" der Redundanz, damit sich die Versionsangabe auch bei vereinzelten Lesefehlern noch auswerten lässt. Hierfür (und auch für die Fehlerkorrektur der unten folgenden Datenformatangabe) werden in QR-Codes BCH-Codes genutzt. BCH-Codes basiert auf Polynomdivision und können in diesem konkreten Fall bis zu drei fehlerhaft eingelesene Bits (sog. "Bitflips") erkennen und korrigieren. (Um den Rahmen hier nicht zu sprengen, erkläre ich hier nicht mehr zu BCH-Codes, empfehle aber, sich diese einmal näher anzuschauen, weil es sich dabei um ein sehr schönes und leicht verständliches Fehlerkorrekturkonzept handelt.)

Es gibt 40 verschiedene QR-Code-Versionen. Version 1 hat ein Datenmuster aus 21 x 21 Modulen. In Version 40 sind es 177 x 177 Module. Die Modulanzahl lässt sich anhand der Formel
(Versionsnummer – 1) * 4 + 21

direkt aus der Versionsangabe ableiten.

Die rot markierten Module repräsentieren das verwendete Datenformat. Die Angabe umfasst bei kleineren QR-Codes (bis Version 6) 15 Bits. (Bei größeren QR-Codes sind es mehr Module mit mehr Redundanzinformationen.)
Auch dieser Datensatz ist doppelt im QR-Code abgelegt. Er enthält zwei Bits, welche die Fehlertoleranzklasse angeben und drei Bits, die das genutzte Maskenmuster definieren. Die verbleibenden zehn Bits sind wiederum Fehlerkorrekturinformationen (BCH-Code).

Maskenmuster

Aus den drei Bits für das Maskenmuster ergeben sich 2³ = 8 verschiedene Varianten. Das verwendete Maskenmuster legt fest, welche Farbe ein Bit an der jeweiligen Stelle im QR-Code in Abhängigkeit von seinem Wert (0 oder 1) haben soll:
Die Datenverteilung im QR-Code anhand der Maskenmuster
Konkret heißt das also, dass ein Bit mit dem Wert 1 an einer Stelle des QR-Codes hell ist und an einer anderen dunkel. Dies ist so umgesetzt, um Störfaktoren beim Einlesen des QR-Codes zu minimieren. Beispielsweise soll vermieden werden, das große einfarbige Fläche entstehen oder Modulmuster, die mit einem Finder oder Alignment verwechselt werden könnten.
Es ist die Aufgabe des QR-Code-Generators, ein passendes Maskenmuster für den jeweiligen QR-Code zu finden, das solche Probleme minimiert.

Fehlerkorrektur

Die Angabe für die Fehlerkorrektur umfasst zwei Bits. Da 2² = 4 ist, ergeben sich also vier mögliche Fehlerkorrekturstufen (00, 01, 10, 11). Je höher die gewählte Fehlerkorrekturstufe eingestellt ist, desto mehr redundante Informationen werden ins Datenmuster des QR-Codes eingebracht. Entsprechend vergrößert sich auch der Bereich des QR-Codes, den man beschädigen oder (zum Beispiel durch das Einfügen eines Logos) verdecken kann, ohne die Lesbarkeit des QR-Codes zu gefährden. Die Redundanzinformationen für die Nutzdaten werden hier übrigens nicht mit einem klassischen BCH-Code erzeugt, sondern mit einem Reed-Solomon-Code. (Erkläre ich jetzt auch nicht näher, die Beschäftigung damit lohnt sich aber ebenfalls.)

Die vier Fehlerkorrekturklassen heißen üblicherweise L, M, Q und H:
  • Fehlerkorrektur Level L (Low): bis zu 7 % verdeckt
  • Fehlerkorrektur Level M (Medium): bis zu 15 % verdeckt
  • Fehlerkorrektur Level Q (Quartile): bis zu 25 % verdeckt
  • Fehlerkorrektur Level H (High): bis zu 30 % verdeckt (oft für QR-Codes mit Logo genutzt)
Zur Verdeutlichung, habe ich mal diese Grafik erstellt. Der goldene QR-Code nutzt die Fehlerkorrekturstufe L, der lila-orangefarbene QR-Code Fehlerkorrekturlevel M, der grüne QR-Code Level Q und der Regenbogen-QR-Code Level H.
QR-Codes mit dem gleichen Inhalt, aber unterschiedlicher Fehlertoleranz
Man sieht deutlich die Zunahme an Datenpunkten, die zu einer schrittweisen Verkleinerung der einzelnen Module führt. Auch die Zunahme an Alignments ist sichtbar. Wenn wir noch mehr Daten in einen QR-Code packen, werden es noch mehr:
Ein QR-Code mit langem Text und Fehlertoleranzlevel H

Warum ändert sich die Größe des Rahmens um den QR-Code?

Neben der Zunahme an Informationen, fällt oben in den vier Grafiken auch auf, dass sich die Größe der Quiet Zone verändert. Die vier QR-Codes enthalten die gleichen Daten und wurden mit dem gleichen QR-Code Generator von t1p.de erstellst. Warum ist das also so?

Es liegt daran, dass ich dem Generator eine Zielgröße (in Pixeln) mitgegeben habe, weil ich eine PNG-Grafik generieren wollte. Bedenkt man die mathematischen Zusammenhänge, wird schnell klar, warum das so sein muss: Beim Rendern des QR-Codes zu einer Pixelgrafik, ist ein Pixel die kleinstmögliche darstellbare Größe. Die Pixel geben ein Raster vor und dieses muss mit dem Raster des QR-Codes in Einklang gebracht werden. Für ein gleichmäßiges Bild, muss also anhand der Modulanzahl des QR-Codes und der Zielgröße der Pixelgrafik eine passende, einheitliche Pixelgröße für ein einzelnes QR-Code-Modul gefunden werden.
Diesem Mapping sind jedoch Grenzen gesetzt, da alle Module des QR-Codes die gleiche Pixelgröße haben müssen und man ein Pixel nicht weiter teilen kann. Um den entstehenden Versatz zwischen einer rechnerisch möglichen Grafikgröße und der vom Nutzer gewünschten Zielgröße zu kompensieren, erfolgt eine automatische Anpassung der Größe der Quiet Zone. In den allermeisten Fällen sind die Anpassungen aber so klein, dass sie nicht auffallen oder zumindest nicht stören.

Praxistipp: Wie kann ich die Rahmengröße des QR-Codes einheitlich halten?

Falls einen dieser Effekt doch stört, kann man entweder zur Erstellung von Vektorgrafiken (wie SVG) übergehen, bei der dieses Pixel-Mapping nicht notwendig ist, oder die gewünschte Zielgröße anpassen. Diese muss man reduzieren, wenn der Weißraum um den QR-Code zu groß wird oder sie anheben, falls er zu klein wird.

Ein anderer Hebel ist die Datenmenge des QR-Codes, welche sich ja durch die einzubettenden Daten und das verwendete Fehlerkorrekturlevel bestimmt. Wenn man keine bestimmte Fehlertoleranzstufe benötigt, kann man mit diesem Parameter spielen und schauen, ob ein besser passendes Ergebnis entsteht.

Wenn man für eine Publikation komplett einheitliche QR-Codes haben möchte, um ein harmonisches Gesamtbild zu erzeugen, geht es aber noch präziser. Denn zumindest bei der Einbettung von Internetadressen kann man leicht dafür sorgen, dass alle QR-Codes die gleiche Datensatzgröße bekommen:
Wie gestern schon erläutert, hat es einige Vorteile, Kurz-URLs statt langer Links in QR-Codes einzubetten. Mithilfe der Kurz-URLs kann man leicht erreichen, dass alle Links die gleiche Länge haben. Die aus unterschiedlich langen Zieladressen entstehende Variabilität wird somit eliminiert und alle QR-Codes erhalten die gleiche Geometrie und insbesondere auch gleich große Quiet Zones. Da t1p.de nicht nur QR-Codes, sondern auch Kurzlinks erzeugt und diese (wenn man keine selbst ausgewählten Kurz-URLs verwendet) immer gleich lang sind, lässt sich auch dieses Problem damit sehr bequem lösen.

Wie viele Daten passen in einen QR-Code?

Nachdem wir den Aufbau von QR-Codes nun analysiert und (hoffentlich) verstanden haben, möchte ich den Artikel mit der Beantwortung einer Frage abschließen, die sehr oft gestellt wird: Wie viele Daten passen denn nun eigentlich in so einen QR-Code?

Diese Tabelle liefert die Antwort. Sie zeigt die in Abhängigkeit von der gewählten Fehlertoleranz nutzbare Datengröße (in Byte) für die einzelnen QR-Code-Versionen.

VersionModuleBytes in LowBytes in MediumBytes in Quartile Bytes in High
121×211714117
225×2532262014
329×2953423224
433×3378624634
537×37106846044
641×411341067458
745×451541228664
849×4919215210884
953×5323018013098
1057×57271213151119
1161×61321251177137
1265×65367287203155
1369×69425331241177
1473×73458362258194
1577×77520412292220
1681×81586450322250
1785×85644504364280
1889×89718560394310
1993×93792624442338
2097×97858666482382
21101×101929711509403
22105×1051003779565439
23109×1091091857611461
24113×1131171911661511
25117×1171273997715535
26121×12113671059751593
27125×12514651125805625
28129×12915281190868658
29133×13316281264908698
30137×13717321370982742
31141×141184014521030790
32145×145195215381112842
33149×149206816281168898
34153×153218817221228958
35157×157230318091283983
36161×1612431191113511051
37165×1652563198914231093
38169×1692699209914991139
39173×1732809221315791219
40177×1772953233116631273

Ein QR-Code kann also bis zu 2953 Byte transportieren. Und man sieht deutlich, wie teuer man sich die Fehlertoleranz erkaufen muss, wenn man einen QR-Code erstellen will, der Beschädigungen ausgesetzt sein könnte oder ein Logo beherbergen soll.

Geschnatter

1 Kommentar, selbst mitschnattern << < Seite 1/1 > >>
Tobias, am 14.09.2025 um 15:24 Uhr
Zur Einordnung: Woher weiß ich welche Version ich generieren muss? Welche Versionen wurden in den Beispielen genutzt?

Danke!
Antwort: In der Regel musst du das nicht selbst festlegen, sondern der QR-Code-Generator entscheidet es anhand der abzubildenden Datenmenge und der gewünschten Fehlerkorrektur.

Bei den Beispielen, rein informativ:
Goldener QR-Code: Version 4, Level L, Datenmaske 2
Lila-orangener QR-Code: Version 5, Level M, Datenmaske 2
Grüner QR-Code: Version 7, Level Q, Datenmaske 3
Regenbogen-QR-Code: Version 8, Level H, Datenmaske 2
der ganz große QR-Code: Version 36, Level H, Datenmaske 4