Verwenden Sie den ausgelesenen Wert eines QR-Codes nie ungeprüft — Erfolgreiche Fehlerkorrektur garantiert nicht den Wert

· · QR-Code, Barcode, Fehlerkorrektur, Eingabevalidierung, Datenqualität, Geschäftssysteme, C#, Design, Betrieb vor Ort

Das Prüfterminal im Lager macht „piep“. Das ist das Signal, dass der QR-Code auf dem Lieferschein gelesen wurde. Die dekodierte Zeichenkette wird direkt an das Bestandssystem weitergereicht, der Beleg wird zugeordnet, und die Versandanweisung wird bestätigt. QR-Codes haben Fehlerkorrektur, also kommt auch bei leichter Verschmutzung der korrekte Wert zurück — Systeme, die auf dieser Annahme aufgebaut sind, sind alles andere als selten.

Die erste Hälfte davon stimmt. QR-Codes sind so gestaltet, dass Daten trotz Verschmutzung und Beschädigung wiederhergestellt werden können, und von Fehlerkorrekturstufe L bis H lassen sich etwa 7 % bis 30 % der Codewörter wiederherstellen.1 Das Problem liegt in der zweiten Hälfte: der Schlussfolgerung, „also ist der zurückgekommene Wert korrekt“.

Anhand von Beispielbildern tatsächlich erzeugter QR-Codes und Messungen mit zwei verschiedenen Decodern legt dieser Artikel dar, warum erfolgreiche Fehlerkorrektur den Wert nicht garantiert, und was ein Geschäftssystem selbst validieren sollte. Jeder in diesem Artikel gezeigte QR-Code ist echt. Die lesbaren können Sie direkt mit einem zur Hand befindlichen QR-Leser prüfen (einige sind als Belegexemplare enthalten, um zu zeigen, dass sie nicht gelesen werden können; diese sind an ihrer jeweiligen Stelle gekennzeichnet). Wir haben außerdem ein QR-Code-Dekodierungs-Vergleichswerkzeug (japanische Oberfläche) vorbereitet, mit dem Sie im Browser zwischen jsQR und OpenCV.js wechseln können. Die Messungen in diesem Artikel lassen sich dort nachvollziehen.

1. Das Wichtigste zuerst

  • Fehlerkorrektur bedeutet „Wiederherstellung“, nicht „Validierung“. Der Standard selbst stellt fest, dass verschmutzte Module zu einer „Fehldekodierung als scheinbar gültiges, aber anderes Codewort“ führen.2
  • Bei zufälliger Verschmutzung fällt es im Wesentlichen auf die Seite von „nicht lesbar“. Über 9.700 gemessene Versuche gab es null Fälle, in denen ein falscher Wert zurückgegeben wurde.
  • Konzentriert sich die Beschädigung jedoch an einer Stelle, erhalten Sie zuverlässig einen anderen Wert. Werden nur 7 von 26 Codewörtern beschädigt, liest sich 004873 als 104873, und zwei unabhängige Decoder lieferten beide denselben Fehler.
  • Außerhalb der Fehlerkorrektur gibt es weit einfachere Fallstricke. Structured Append, Zeichenkodierung, ein weiterer Code im Bildausschnitt. Alle können auftreten, ohne dass irgendein Fehler ausgelöst wird. Je nach Decoder können Warnungen oder Ausnahmen erscheinen, aber wie sie erscheinen, ist implementierungsabhängig, und Kombinationen, die auf der stillen Seite landen, gibt es tatsächlich.
  • Behandeln Sie einen dekodierten Wert daher als unvalidierte Eingabe. Die Grundform ist, ihn über drei Stufen entgegenzunehmen: Formatprüfung → Prüfziffer → geschäftliche Validierung.

2. Ein Beispiel — Zwei QR-Codes, die fast identisch aussehen

Betrachten Sie zunächst das Original. Beide der folgenden lesen sich ohne jeden Fehler.

Oben ein normaler QR-Code, unten ein QR-Code mit einem einzelnen vertikalen Streifen aus Beschädigung. Sie sehen fast identisch aus

  • A (oben)NO:20260725-004873
  • B (unten)NO:20260725-104873

Sie sind echt, Sie können sie also mit einem zur Hand befindlichen Leser ausprobieren. Dieses Belegnummernschema lautet „8-stelliges Bestelldatum + 5-stellige laufende Nummer + 1 Prüfziffer“; verändert hat sich also der Nummernteil — aus 00487 wurde 10487, was auf einen anderen Beleg, 10.000 Einträge entfernt, verweist.

Die vorinstallierte iOS-Kamera reagiert möglicherweise nicht. Die vorinstallierte Kamera ist darauf ausgelegt, Inhalte zu priorisieren, die sie „öffnen“ kann, etwa eine URL, sodass bei einem reinen Text-QR wie in diesem Artikel möglicherweise nichts erscheint. Eine QR-Leser-App liest sie. Dass dasselbe Bild je nach Leser-Implementierung unterschiedlich reagiert — genau das Thema dieses Artikels — lässt sich schon beim ersten Beispiel erleben.

Der einzige Unterschied zwischen B und A sind 31 Module innerhalb eines einzelnen vertikalen Streifens, Spalten 10 bis 14 von links. Das sind 15 % der 208 Module im Codewort-Bereich.

Ein Diagramm, das innerhalb von B die 31 gegenüber A veränderten Module mit roten Kästen markiert zeigt. Sie verteilen sich auf einen schmalen vertikalen Streifen

Und der entscheidende Punkt ist, dass der Decoder für beide keinen Fehler zurückgibt. Es gibt nicht einmal einen Hinweis „Korrektur angewendet“. Aus Sicht der Anwendung sind beide gleichermaßen erfolgreiche Lesevorgänge.

Ein Vorbehalt: Diese Beschädigung wurde bewusst konstruiert, und die Wahrscheinlichkeit, dass sie zufällig entsteht, ist nicht hoch. Wie sie aufgebaut wurde und wie weit sie von realer Verschmutzung entfernt ist, wird in Abschnitt 4 behandelt.

3. Warum es passiert — Ein Blick in die Fehlerkorrektur

Die Fehlerkorrektur von QR-Codes verwendet Reed-Solomon-Codes und arbeitet pro Codewort (8-Bit-Einheiten). Hier die Aufschlüsselung für das hier verwendete Symbol der Version 1, Fehlerkorrekturstufe M (21×21 Module).2

Codewörter insgesamt Datencodewörter Fehlerkorrekturcodewörter Korrekturfähigkeit gemäß Standard
26 16 10 4 Codewörter

Die letzte Spalte fällt ins Auge. Mit 10 Fehlerkorrekturcodewörtern kann ein Reed-Solomon-Code bis zu 5 korrigieren. Die vom Standard definierte Korrekturfähigkeit beträgt jedoch 4. Dieser Unterschied von einem wird bewusst als Fehldekodierungsschutz-Codewörter p zurückgehalten (für Version 1-M gilt p = 2). Tabelle 13 des Standards vermerkt zudem in einer Fußnote, dass „um die Wahrscheinlichkeit von Fehldekodierungen zu senken, die Korrekturfähigkeit unter die Hälfte der Anzahl der Fehlerkorrekturcodewörter gesetzt wird“.2

Mit anderen Worten: Der Standard selbst ist unter der Annahme gestaltet, dass „Fehlerkorrektur einen falschen Wert erzeugen kann“. Derselbe Abschnitt sagt auch Folgendes:

Da der QR-Code eine Matrixsymbologie ist, führt ein Defekt, der ein Modul von dunkel zu hell (oder umgekehrt) ändert, dazu, dass das betroffene Symbolzeichen als scheinbar gültiges, aber anderes Codewort fehldekodiert wird.2

Der Grund liegt im Korrekturprinzip selbst. Was die Reed-Solomon-Dekodierung tut, ist, nach einem Codewort innerhalb eines festen Abstands (der Korrekturfähigkeit) vom empfangenen Muster zu suchen. Findet sie eines, gibt sie es als Antwort zurück; findet sie keines, endet es mit „nicht lesbar“. Sie sucht nicht nach dem nächstgelegenen Codewort, egal wie stark das Muster beschädigt ist.

Aus dieser Eigenschaft ergeben sich zwei Lager von Ergebnissen. Zufällige Beschädigung streut weit von jedem Codewort weg, sodass sie meist in „nicht gefunden = nicht lesbar“ fällt. Gefährlich wird es, wenn die Beschädigung zufällig in die Nachbarschaft eines anderen Codeworts fällt. In diesem Fall entscheidet der Decoder, dass jenes Codewort die richtige Antwort ist, und gibt es zurück. Das zurückgegebene Codewort ist vollständig in sich konsistent, sodass es keine Möglichkeit gibt zu erkennen, dass es falsch ist.

4. Wie weit reicht die Korrektur, und wo wird es gefährlich?

Hier beginnen die Messungen. Vorweg das Fazit: Gefährlich ist nicht die „Menge“ an Verschmutzung, sondern „wo sie landet“.

4.1. Zufällige Verschmutzung fällt auf die Seite von „nicht lesbar“

An einem Symbol der Version 1-M haben wir eine bestimmte Anzahl der 208 Module im Codewort-Bereich zufällig umgeklappt und die Ergebnisse klassifiziert (300 Versuche pro Stufe, insgesamt 3.900).

Ein Vergleich von QR-Codes mit 6 umgeklappten Modulen und mit 9 umgeklappten Modulen. Der obere lässt sich lesen, der untere nicht

Oben sind 6 umgeklappt, unten 9. Der obere liest sich korrekt, der untere lässt sich überhaupt nicht lesen. Ein Unterschied von 3 Modulen ist für das menschliche Auge kaum wahrnehmbar. Die Grenze liegt an einer Stelle, die sich visuell nicht zeigt.

Umgeklappte Module Korrekt gelesen Nicht lesbar Falscher Wert
0–5 1.799 1 0
6 131 169 0
7 32 268 0
8 11 289 0
9–12 0 1.200 0

Die Lesbarkeit bricht zwischen 5 und 6 zusammen, und ab 9 ist sie vollständig verschwunden. Und kein einziger falscher Wert trat auf. Beschädigung, die sich nicht korrigieren lässt, fällt auf die Seite von „nicht lesbar“ — das ist die schlicht gute Nachricht. Die Zahlen waren mit jsQR nahezu identisch (alle 1.800 korrekt für 0–5; ab 6 innerhalb eines Falls Abweichung von OpenCV).

Betrachtet man dasselbe pro Codewort, wird die Grenze noch schärfer (200 Versuche pro Stufe, insgesamt 1.800).

Beschädigte Codewörter Korrekt gelesen Nicht lesbar Falscher Wert
0–5 1.194 6 0
6–8 0 600 0

Bis zu 5 Codewörter werden korrigiert. Wie im vorherigen Abschnitt erklärt, beträgt die Korrekturfähigkeit gemäß Standard 4, und der Rest ist ein Vorrat für „Erkennen ohne Korrigieren“. jsQR las ebenfalls alle 1.200 Fälle von 0–5 korrekt, sodass beide Implementierungen diesen Vorrat vollständig für die Korrektur aufwenden. Auf den vom Standard als Fehldekodierungsschutz zurückgehaltenen Spielraum kann man sich auf Implementierungsebene nicht verlassen.

Wir führten zusätzlich jeweils 2.000 weitere Versuche für Beschädigung eindeutig jenseits der Korrekturfähigkeit durch (6 Codewörter und 8 Codewörter), und auch hier gab es null falsche Werte — alles endete mit „nicht lesbar“.

Aus der Kamera stammende Verschlechterung zeigt dieselbe Tendenz. Hier die Ergebnisse einer gleichmäßig über das gesamte Symbol angewendeten Unschärfe, Rauschen und reduziertem Kontrast (je 200 Versuche, insgesamt 1.000).

Unschärfe σ Rauschen σ Kontrast Korrekt gelesen Nicht lesbar Falscher Wert
0 0 1,00 200 0 0
1,5 10 0,90 183 17 0
3,0 20 0,70 1 199 0
4,5 30 0,50 0 200 0
6,0 40 0,35 0 200 0

Das Ergebnis ist entweder „liest sich korrekt“ oder „liest sich nicht“ — es gibt keinen Mittelweg. Mit fortschreitender Verschlechterung sinkt die Erfolgsquote, aber alles Verlorene wird zu einem Lesefehler.

Das gilt allerdings für gleichmäßige Verschlechterung. Reales Kamerawackeln hat eine Richtung, und schräges Fotografieren oder ungleichmäßige Beleuchtung beschädigt nur einen Teil des Bildes. Wie wir als Nächstes sehen werden, ist es die Verzerrung der Beschädigung, die gefährlich wird — verallgemeinern Sie dies also nicht zu „Bildqualitätsprobleme verursachen keine Fehllesungen“.

4.2. Landet sie ungünstig, erhalten Sie zuverlässig einen anderen Wert

Beispiel B aus Abschnitt 2 wurde bewusst als eine solche Art „ausgerichteter Beschädigung“ konstruiert.

Reiht man die 26 Codewörter von NO:20260725-004873 (A) und NO:20260725-104873 (B) auf, unterscheiden sie sich an 12 Stellen: zwei Datencodewörter plus die zehn davon mitgezogenen Fehlerkorrekturcodewörter.

Verschiebt man 7 dieser 12 Stellen in Richtung der Werte von B, liegt das resultierende Muster 7 Codewörter von A und 5 Codewörter von B entfernt. Beträgt die Korrekturfähigkeit 5, deutet der Decoder dies als „B mit 5 beschädigten Stellen“ und korrigiert es zu B.

Bedingung Getestete Kombinationen Anzahl als B fehlgelesen
7 Codewörter zu B hin verschoben (Abstand 5 von B) 792 792 (100 %)
8 Codewörter zu B hin verschoben (Abstand 4 von B) 495 495 (100 %)

Ausnahmslos jede Kombination wurde fehlgelesen. Die untere Zeile liegt im Abstand 4 von B — also innerhalb der vom Standard definierten Korrekturfähigkeit. Selbst eine Implementierung, die die Fehldekodierungsschutz-Codewörter p respektiert, liefert dasselbe Ergebnis, sobald die Beschädigung um ein Codewort wächst. p senkt nur die Wahrscheinlichkeit; es verhindert nichts.

Das in Abschnitt 2 gezeigte B ist die Kombination unter diesen, bei der sich die Beschädigung zu einem einzelnen vertikalen Streifen gruppiert (31 Module). Minimiert lässt sie sich auf 23 Module reduzieren. Zwei voneinander unabhängige Implementierungen, OpenCV 5.0.0 und jsQR 1.4.0, geben beide NO:20260725-104873 zurück.

4.3. Wie dieses Ergebnis einzuordnen ist

Um ehrlich zu sein: Diese Art von Beschädigung entsteht wahrscheinlich nicht zufällig. Bei willkürlicher Verschmutzung ergaben 9.700 Versuche null Fehllesungen. Das ist keine Geschichte à la „das könnte morgen passieren“.

Dennoch lässt es sich aus drei Gründen nicht ignorieren.

  • Reale Beschädigung ist nicht zufällig. Falten verlaufen geradlinig, Abrieb durch Transport konzentriert sich auf denselben Rand, und ein verstopfter Druckkopf erzeugt vertikale Streifen. Die hier verwendete streifenförmige Beschädigung ist ein Beispiel für diese Art „positionell ausgerichteter Beschädigung“. Allerdings umfasst B Änderungen in beide Richtungen — 17 Module weiß→schwarz und 14 schwarz→weiß —, sodass ein Defekt, der lediglich Tinte entfernt, sie nicht reproduzieren kann. Dass beide Richtungen gemeinsam auftreten, erfordert etwas wie den Schatten einer Falte, der die Binarisierungsschwelle verschiebt, sich überlagernde Verschmutzung und verblassten Druck, oder ein anderes, teilweise darübergeklebtes Etikett.
  • Die Anzahl der Scans ist um Größenordnungen höher. Eine bei einem einzelnen Scan vernachlässigbare Wahrscheinlichkeit sieht an einem Standort mit zehntausenden Lesevorgängen pro Tag anders aus. Und da eine Fehllesung keinen Fehler auslöst, hinterlässt sie keinen Datensatz und wird am Ende als Bestandsabweichung unbekannten Ursprungs verbucht.
  • Dass man sie bewusst erzeugen kann, bedeutet, dass andere sie auch erzeugen können. Das hier verwendete Muster wurde mechanisch konstruiert, nachdem ein Zielwert ausgewählt wurde. Für QR-Codes, bei denen ein Motiv zur Manipulation besteht — Preisschilder, Coupons —, wird dies zu einer Angriffstechnik.

5. „Es wurde gelesen, ist aber falsch“ ohne jeden Bezug zur Fehlerkorrektur

Das sind diejenigen, auf die Sie in der Praxis tatsächlich häufiger stoßen werden. Sie treten auf, selbst wenn die Fehlerkorrektur einwandfrei funktioniert, und sind nicht einmal eine Frage der Wahrscheinlichkeit.

5.1. Nur das erste Symbol eines Structured-Append-Satzes lesen

QR-Codes verfügen über einen Mechanismus (Structured Append), um lange Daten auf mehrere Symbole zu verteilen und sie vom Leser zusammensetzen zu lassen. Das Folgende ist das erste von drei Symbolen, in die NO:20260725-004873/LOT:AB-77/QTY:120/EXP:20270131 aufgeteilt wurde.

Das erste von drei Structured-Append-QR-Symbolen. Für sich allein gelesen, liefert es eine Belegnummer mit fehlendem Ende

Es sieht aus wie ein gewöhnlicher QR-Code, ohne Hinweis darauf, dass es eines von dreien ist. Für sich allein gelesen, gibt OpenCV Folgendes zurück:

NO:20260725-00487

Kein Fehler, keine Warnung. Eine völlig plausibel aussehende Belegnummer, bei der nur die abschließende Prüfziffer 3 fehlt. Das zweite und dritte Symbol ergeben entsprechend 3/LOT:AB-77/QTY: und 120/EXP:20270131. Übergibt man dasselbe Bild an jsQR, kam eine leere Zeichenkette zurück. Was passiert, wenn eine Anwendung, die kein Structured Append erwartet, zufällig das erste Symbol scannt, hängt vom Decoder ab.

5.2. Zeichenkodierung und ECI

Als Nächstes ein QR-Code mit 部品番号 東-004873 in Shift_JIS ohne ECI-Angabe.

Ein in Shift_JIS ohne ECI-Angabe erzeugter QR-Code. Das Lesen erzeugt verstümmelten Text

Auch dieser ist echt. Lesen Sie ihn mit einem zur Hand befindlichen Leser, und Sie erhalten entweder 部品番号 東-004873, eine verstümmelte Zeichenkette oder gar nichts — was Ihnen verrät, welche Interpretation Ihr Leser verwendet.

Geben Sie dieses Bild in das QR-Code-Dekodierungs-Vergleichswerkzeug ein, sehen Sie die rohe Bytefolge, die jsQR extrahiert hat, neben den Ergebnissen der erneuten Interpretation als UTF-8, Shift_JIS, EUC-JP und so weiter. Sie können dort direkt sehen, wie dieselbe Bytefolge je nach Zeichenkodierung zu etwas völlig anderem wird.

Hier die Ergebnisse, denselben Inhalt mit unterschiedlichen Zeichenkodierungen und ECI-Angaben zu erzeugen und den beiden Decodern zu übergeben. Alle vier dieser Symbole sind unter den Beispielen des Werkzeugs enthalten. Beachten Sie jedoch, dass die Werte in der Tabelle mit Pythons cv2 gemessen wurden und allein die dritte Zeile von der Browser-Version abweicht (unmittelbar nach der Tabelle im Detail besprochen). Was sich mit dem Werkzeug bestätigen lässt, ist das Verhalten der Browser-Version; das „Sterben mit einer Ausnahme“ der dritten Zeile lässt sich nur mit Pythons cv2 reproduzieren.

Erzeugungsbedingung OpenCV 5.0.0 jsQR 1.4.0
Shift_JIS / ohne ECI Gibt eine verstümmelte Zeichenkette als Erfolg zurück Leere Zeichenkette
UTF-8 / ohne ECI 部品番号 東-004873 部品番号 東-004873
Shift_JIS / mit ECI Gibt eine Warnung aus und scheitert an der Dekodierung Leere Zeichenkette
UTF-8 / mit ECI 部品番号 東-004873 部品番号 東-004873

Die erste Zeile ist die schlimmste. OpenCV interpretierte die Bytefolge als Latin-1 und gab eine defekte Zeichenkette zurück, \x95\x94\x95i..., völlig ohne Fehler. Aus Sicht der Anwendung ist das ein normaler Lesevorgang, und landet er direkt in der Datenbank, haben Sie einen verstümmelten Datensatz erzeugt.

Das ist kein Fehler in OpenCV — es ist ein Verhalten genau im Einklang mit der vom aktuellen Standard definierten Standardinterpretation (ISO/IEC 8859-1).3 Was vom Standard abweicht, ist, Shift_JIS ohne ECI einzugeben.

Auch die dritte Zeile ist nicht zu übersehen. Obwohl ECI (der Mechanismus zur expliziten Angabe der Zeichenkodierung) korrekt angegeben war, gab OpenCV die Warnung QR: ECI is not supported properly aus und starb anschließend mit einer Ausnahme, unfähig, den Rückgabewert als UTF-8 zu interpretieren. Die Umkehrung, bei der der standardtreu erstellte QR-Code derjenige ist, der sich nicht lesen lässt, kommt tatsächlich vor.

Mehr noch: Diese dritte Zeile liefert selbst innerhalb desselben OpenCV je nach Sprachbindung unterschiedliche Ergebnisse. Die obige Tabelle zeigt das Ergebnis mit Pythons cv2, übergibt man aber dasselbe Bild der Browser-Version (opencv.js 5.0.0), wird keine Ausnahme ausgelöst — sie gibt als Erfolg die Zeichenkette ���i��� ��-004873, voller Ersatzzeichen, zurück. Der Grund liegt darin, dass Emscripten beim Konvertieren von std::string als UTF-8 ungültige Bytes zu U+FFFD verwirft, statt eine Ausnahme zu werfen. Gleiche Version, gleiches Bild — das Einzige, was sich geändert hat, ist die aufrufende Sprache. Python, wo eine Ausnahme wenigstens bemerkbar macht, dass etwas schiefging, ist die bessere der beiden Optionen; die Browser-Version sagt „es wurde gelesen“ und liefert dabei einen defekten Wert zurück. Sie können dies selbst mit den Beispielen des Werkzeugs bestätigen.

5.3. Mehrere QR-Codes im Bildausschnitt

Mehrere auf einem Beleg gedruckte QR-Codes, oder das Etikett der nächsten Box im Sichtfeld — alltägliche Situationen. Wir haben drei nebeneinander angeordnete QR-Codes getestet.

Ein Bild mit drei nebeneinander angeordneten QR-Codes. Von links: NO:, ITEM:, LOT:

Zunächst lieferte auf diesem Bild die Einzellese-API von OpenCV überhaupt nichts zurück. Das ist jedoch keine Garantie dafür, dass „sie die Eingabe bei mehreren Codes zurückweist“. Die Einzellese-API ist nur dokumentiert, einen QR-Code zu erkennen und zu dekodieren; nirgends steht, dass sie mehrere Symbole zurückweist, und je nach Layout könnte sie durchaus eines davon zurückgeben. Verwenden Sie das Vorhandensein oder Fehlen eines Rückgabewerts der Einzellese-API nicht als Ersatz für die Erkennung mehrerer Codes.

Wie sieht es also mit der Mehrfachlese-API aus? Hier wurde es unangenehm.

Hier die Ergebnisse, das obige Bild (NO: / ITEM: / LOT: von links) unverändert zu übernehmen und nur die Pixelabmessungen zu variieren. Dies entspricht einem realen Scanner, bei dem sich der Abstand zum Ziel oder die Kameraauflösung ändert.

Bildbreite Rückgabereihenfolge
1.001 px NO: / LOT: / ITEM:
1.502 px Nichts zurückgegeben
2.002 px NO: / LOT: / ITEM:
3.003 px NO: / ITEM: / LOT:
4.004 px LOT: / NO: / ITEM:

Dasselbe Bild, und doch ändert allein die Änderung der Auflösung die Reihenfolge. Sie ist weder von links nach rechts noch größte zuerst. Es gibt sogar eine Auflösung, bei der sich nichts lesen lässt. Die Reihenfolge wird durch die interne Funktionsweise des Erkennungsalgorithmus bestimmt, und da sie nirgendwo spezifiziert ist, ist genau das das Ergebnis.

Das bedeutet, dass Code, der annimmt, „der erste sollte die Belegnummer sein“, und Index 0 verwendet, heute möglicherweise zufällig funktioniert, aber morgen einen anderen Code aufgreift, nur weil jemand die Kamera näher herangeführt hat. Das ist die Art von Fehler, die schwer zu reproduzieren und schwer nachzuvollziehen ist.

Die empfangende Seite muss nach Inhalt, nicht nach Reihenfolge auswählen. Alle mit der Mehrfachlese-API erfassen, nur diejenigen akzeptieren, deren Präfix und Format übereinstimmen, und einen Fehler auslösen, wenn null oder zwei oder mehr Übereinstimmungen vorliegen — das ist die sichere Schreibweise.

5.4. Der Inhalt könnte von vornherein nicht korrekt sein

Es gibt eine Ebene, die Bildverarbeitung grundsätzlich nicht erkennen kann. Die gedruckten Ausgangsdaten sind falsch; ein altes Etikett von vor einer Umetikettierung klebt noch auf der Box; ein Etikett eines anderen Handelspartners hat sich untergemischt; das Etikett ist eine Fotokopie.

Ein QR-Code sagt Ihnen nur, was dort geschrieben steht. Ob es korrekt ist und ob es Ihre eigene Organisation ausgestellt hat, lässt sich nur von der empfangenden Seite bestätigen.

6. Wie Sie mit dem empfangenen Wert umgehen

Die Gegenmaßnahme läuft darauf hinaus, Ihre eigene Validierung außerhalb der Fehlerkorrektur zu stapeln.

Stufe Was validiert wird Was erfasst wird
1. Formatprüfung Länge, Zeichenklassen, Trennzeichen, exakte Präfixübereinstimmung Lesen eines anderen Codes, ein Structured-Append-Fragment, verstümmelter Text
2. Selbstvalidierung Prüfziffer Erkennt Änderungen an einzelnen Zeichen zuverlässig; verpasst manche Änderungen an mehreren Zeichen
3. Geschäftliche Validierung Stammdatenabgleich, und ob es zu dem passt, was jetzt gerade verarbeitet werden soll Alte Etiketten, Etiketten eines anderen Unternehmens, Aufgreifen des falschen Belegs

Die Beispiel-Belegnummer ist NO: + 8-stelliges Bestelldatum + 5-stellige laufende Nummer + 1 Prüfziffer, wobei die letzte Ziffer dasselbe Modulo-10-Gewicht-3-Schema wie bei GS1 verwendet. Die fehlgelesene NO:20260725-104873 aus Abschnitt 2 wird hier gestoppt, weil die korrekte Prüfziffer für 2026072510487 0 ist, was nicht mit der 3 auf dem Etikett übereinstimmt.

using System.Linq;
using System.Text.RegularExpressions;

public sealed record ScanOutcome(bool Accepted, string? SlipNo, string Reason);

public static class SlipScanValidator
{
    // NO: + 8-stelliges Bestelldatum + '-' + 5-stellige laufende Nummer + 1 Prüfziffer
    // Mit \z abschließen, nicht mit $. In .NET passt $ auch unmittelbar vor einem
    // abschließenden Zeilenumbruch, sodass "NO:20260725-004873\n" durchgelassen würde.
    // Für Ziffern [0-9] statt \d verwenden. In .NET passt \d generell auf Unicode-Ziffern,
    // einschließlich Vollbreiten-Ziffern, aber die nachgelagerte Prüfziffernberechnung
    // setzt ASCII voraus
    private static readonly Regex Format =
        new(@"\ANO:(?<date>[0-9]{8})-(?<seq>[0-9]{5})(?<cd>[0-9])\z", RegexOptions.Compiled);

    public static ScanOutcome Validate(string? raw, ISlipRepository repo)
    {
        // 1. "Konnte nicht gelesen werden" nicht zu einem "leeren Erfolg" machen.
        //    Decoder unterscheiden sich darin, ob sie einen Fehlschlag mit null, einer leeren
        //    Zeichenkette oder einer Ausnahme signalisieren
        if (string.IsNullOrEmpty(raw))
            return new(false, null, "Der Code konnte nicht gelesen werden. Bitte erneut scannen");

        // 2. Formatprüfung. Auf exakte Übereinstimmung einschließlich Länge prüfen, nicht nur auf Präfix.
        //    Das Structured-Append-Fragment "NO:20260725-00487" wird hier zurückgewiesen
        var m = Format.Match(raw);
        if (!m.Success)
            return new(false, null, $"Entspricht nicht dem Beleg-QR-Format ({Describe(raw)})");

        // 3. Selbstvalidierung. Hat eine Fehldekodierung eine Ziffer verfälscht, wird das hier erfasst
        var body = m.Groups["date"].Value + m.Groups["seq"].Value;
        if (Modulus10Weight3(body) != m.Groups["cd"].Value[0] - '0')
            return new(false, null, "Die Prüfziffer stimmt nicht überein. Bitte das Etikett auf Verschmutzung prüfen");

        // 4. Geschäftliche Validierung. Existiert der Beleg, und befindet er sich in einem Zustand, den wir jetzt verarbeiten dürfen?
        var slip = repo.Find(raw);
        if (slip is null)
            return new(false, null, "Kein passender Beleg gefunden");
        if (slip.Status != SlipStatus.WaitingForShipment)
            return new(false, null, $"Dieser Beleg hat den Status \"{slip.Status}\". Er ist nicht zum Versand fällig");

        return new(true, raw, "OK");
    }

    // Dasselbe Modulo 10, Gewicht 3 wie bei GS1. Gewichte 3,1,3,1... vom rechten Ende her anwenden
    private static int Modulus10Weight3(string body)
    {
        var sum = 0;
        for (var i = 0; i < body.Length; i++)
        {
            var weight = (body.Length - i) % 2 == 1 ? 3 : 1;
            sum += (body[i] - '0') * weight;
        }
        return (10 - sum % 10) % 10;
    }

    // Ein dekodierter Wert ist externe Eingabe. Vor der Anzeige auf dem Bildschirm oder im Protokoll
    // nur druckbares ASCII beibehalten. char.IsControl verwirft nur Unicode Control (Cc) und lässt
    // Format-Zeichen (Cf) wie U+202E (Rechts-nach-links-Überschreibung) durch.
    // Als Positivliste, nicht als Negativliste schreiben
    private static string Describe(string raw)
    {
        var kept = raw.Where(c => c >= ' ' && c <= '~').Take(40).ToArray();
        if (kept.Length == 0) return "(Zeichenkette kann nicht angezeigt werden)";
        var safe = new string(kept);
        return kept.Length < raw.Length ? safe + "…(einige Zeichen entfernt)" : safe;
    }
}

Das Design von Prüfziffern selbst — die Formeln und wie man eine auswählt — ist in Codedesign für Geschäftssysteme — Produkt- und Kundencodes sowie Prüfziffern festlegen zusammengestellt. Ihr Wert im Kontext dieses Artikels liegt darin, dass die Prüfung nicht nur gegen menschliche Tippfehler, sondern auch gegen maschinelle Fehllesungen wirkt.

Was diese drei Stufen nicht schützen

Selbst mit allen drei Stufen an ihrem Platz gibt es drei Lücken. Alle lassen sich schließen, indem man „das Validierungsdesign eine Ebene tiefer treibt“, achten Sie also auch darauf.

Prüfziffern verpassen Änderungen an mehreren Zeichen. Was Modulo 10, Gewicht 3 zuverlässig erfasst, ist ein Fehler an einem einzelnen Zeichen. Tatsächlich erzeugen sowohl 2026072500487 als auch 2026072517487 eine Prüfziffer von 3, sodass NO:20260725-174873 Stufe 2 problemlos passiert. Eine Fehldekodierung ändert nicht zwangsläufig nur ein Zeichen, Sie können Stufe 3 also nicht überspringen.

Lassen Sie den Stammdatenabgleich nicht bei „existiert er“ stehenbleiben. Der Aufruf repo.Find() und die Statusprüfung im obigen Code bestätigen nur, dass „irgendwo ein verwendbarer Beleg existiert“. Scannt eine Mitarbeiterin oder ein Mitarbeiter das Etikett der nächsten Box, erfüllt auch dieses Etikett das Format, die Prüfziffer und den Status „wartet auf Versand“ und passiert daher problemlos. Der dekodierte Wert muss gegen den Artikel, den Sie gerade verarbeiten sollen, gegengeprüft werden — stimmt er mit dem nächsten Eintrag auf der Kommissionierliste überein, ist er mit der bereits gescannten Behälter-ID verknüpft, entspricht das Ziel dem gerade bearbeiteten Lauf? Womit Sie gegenprüfen, unterscheidet sich je nach Geschäftsprozess, daher kann dies allein kein generischer Code sein.

Duplikatverarbeitung lässt sich nicht durch Validierung verhindern. Scannen zwei Terminals dasselbe Etikett fast gleichzeitig, bestätigen beide „wartet auf Versand“, bevor sie den Status aktualisieren, sodass beide passieren. Das zu verhindern, ist Aufgabe der Ausführungsseite: Machen Sie den bedingten Zustandsübergang — etwas wie UPDATE ... WHERE status = 'WaitingForShipment' — zu einer einzigen atomaren Operation, oder fangen Sie eine erneute Ausführung mit einem Idempotenzschlüssel ab. Validierung ist eine Entscheidung am Eingang; sie ist kein Ersatz für Nebenläufigkeitskontrolle.

„Unfälle“ und „Angriffe“ sind unterschiedliche Probleme

Wovor die drei obigen Stufen schützen, sind Unfälle. Fehllesungen durch Verschmutzung, das Verpassen eines Structured-Append-Symbols, verstümmelter Text, ein untergemischtes altes Etikett — Fehler ohne böse Absicht werden dadurch gestoppt.

Sie sind jedoch kein Schutz für Einsatzzwecke, bei denen ein Motiv zur Manipulation des Codes besteht (Preisschilder, Coupons, Veranstaltungstickets, Zahlungen). Ein Angreifer kann frei einen QR-Code erzeugen, der das Format erfüllt, die Prüfziffer neu berechnet und auf eine andere, tatsächlich existierende Nummer verweist. Der Stammdatenabgleich prüft nur die Existenz und wird daher problemlos passiert.

Wenn der Besitz des QR-Codes Wert oder Berechtigung impliziert, müssen Sie dem Wert selbst Authentizität verleihen. Machen Sie ihn entweder zu einem unerratbaren, vom Server ausgegebenen Token (einem hinreichend langen Zufallswert), sodass sich eine Nummer nicht aus einer anderen ableiten lässt, oder fügen Sie der Nutzlast einen schlüsselgebundenen MAC oder eine digitale Signatur hinzu, sodass die empfangende Seite mit einem Schlüssel verifizieren kann. In beiden Fällen verwalten Sie den Verwendet-/Nicht-verwendet-Status auf dem Server, um zu verhindern, dass Duplikate zweimal verwendet werden.

Aber Authentizität allein verhindert kein Vertauschen. Lösen Sie einen echten QR-Code von einem billigen Produkt ab und kleben Sie ihn auf ein teures, ist das Token oder die Signatur weiterhin authentisch. Wird das Trägermedium wiederverwendet, wie bei austauschbaren Preisschildern, hilft auch die Verwendet-/Nicht-verwendet-Prüfung nicht. Was hier wirkt, ist derselbe Gedanke wie Stufe 3: über einen vom Wert getrennten Weg bestätigen, dass der QR-Code zum vor Ihnen liegenden Artikel gehört — die Identität des Produkts auf anderem Weg ermitteln und gegenprüfen, gegen den Transaktionskontext abgleichen (den Kassenbeleg, das Zulassungszeitfenster), oder sie physisch mit manipulationssicheren Etiketten verbinden, die beim Entfernen reißen.

Weder Prüfziffern noch Stammdatenabgleich garantieren irgendetwas über Authentizität. Und Authentizität selbst garantiert nicht, dass der Wert zum vor Ihnen liegenden Artikel gehört. Der entscheidende Punkt ist, nicht zu versuchen, „Schutz vor Fehllesung“, „Schutz vor Fälschung“ und „Schutz vor Vertauschen“ mit demselben Mechanismus abzudecken.

7. Auf betrieblicher Seite zu entscheidende Punkte

Es gibt Teile, die sich allein durch Code nicht schließen lassen.

  • Drucken Sie unter dem QR-Code stets eine menschenlesbare Zeichenkette. Das ist derselbe Gedanke wie GS1s HRI (Human Readable Interpretation).4 Besteht der Verdacht auf eine Fehllesung, bleibt so ein Mittel für eine Person zur Gegenprüfung. Im realen Betrieb ist es nicht ungewöhnlich, dass dies das einzige Mittel zur Entdeckung ist. Die betriebliche Praxis vor Ort für Barcodes im Allgemeinen ist zusammengefasst in GS1-Barcode-Standards: Grundlagen und betriebliche Fallstricke.
  • Legen Sie das Verfahren für den Fall fest, dass es „sich nicht lesen lässt“. Die maximale Anzahl erneuter Scans, den Rückfall auf manuelle Eingabe und wer das genehmigt. Bleibt dies vage, driftet der Standort in Richtung „den Winkel immer weiter ändern, bis es sich liest“ — was die Fehllesewahrscheinlichkeit nach oben treibt.
  • Protokollieren Sie die zurückgewiesenen Werte. Häufen sie sich bei bestimmten Etiketten oder Terminals, können Sie einen defekten Drucker oder Scanner frühzeitig erkennen. Schreiben Sie die rohe Zeichenkette jedoch nicht direkt in ein zeilenorientiertes Protokoll. Werte mit Zeilenumbrüchen oder Steuerzeichen können Protokollzeilen fälschen oder die Anzeige zerstören. Kürzen und escapen Sie das Original, bevor Sie es in einem strukturierten Protokollfeld oder einer Datenbankspalte speichern, und geben Sie auf von Menschen gelesenen Zeilen nur eine bereinigte Darstellung aus — bauen Sie diese Trennung von Anfang an ein. Bewahren Sie, wo möglich, auch das gescannte Bild auf.
  • Verwenden Sie kein Structured Append. Passen die Daten nicht hinein, erhöhen Sie die Version, oder legen Sie nur eine Kennung in den QR-Code und beziehen Sie den Rest aus den Stammdaten. Letzteres lässt sich zudem für ein kleineres Etikett nutzen und ermöglicht Inhaltskorrekturen ohne erneute Etikettenausgabe.
  • Lösen Sie die Zeichenkodierung, indem Sie sie „nicht hineinlegen“. Halten Sie geschäftlich genutzte QR-Codes innerhalb von ASCII. Byte-Modus ohne ECI-Angabe deklariert keine Zeichenkodierung, und die Standardinterpretation hat sich zwischen den Ausgaben des Standards geändert.3 Einfach UTF-8 zu schreiben, verschafft keine Interoperabilität, und ein Scanner mit anderer Interpretation erzeugt verstümmelten Text. Müssen Sie unbedingt Nicht-ASCII-Zeichen einbeziehen, ist die Deklaration von UTF-8 mit ECI-Angabe die gemäß Standard korrekte Antwort — aber wie Abschnitt 5.2 zeigt, existieren tatsächlich Implementierungen mit zweifelhafter ECI-Behandlung, sodass eine Verifikation auf der tatsächlichen Zielhardware unumgänglich bleibt.
  • Fügen Sie vor unumkehrbaren Vorgängen einen Bestätigungsschritt ein. Bei Vorgängen, die teuer rückgängig zu machen sind — Bestätigung eines Versands, Bestandsabbuchung, Zahlungsabschluss — zeigen Sie den aus dem dekodierten Wert nachgeschlagenen Produktnamen oder Betrag einer Person an. Eine Fehllesung mag als Wert plausibel aussehen, während sie im geschäftlichen Kontext deutlich merkwürdig wirkt.

Wie weit Sie die Validierung treiben, richtet sich nach dem Schaden, den ein Fehler verursacht.

Anwendungsfall Formatprüfung Prüfziffer Stammdatenabgleich Menschliche Bestätigung
Interne Lagerplätze und Regalnummern Erforderlich Optional Empfohlen Nicht erforderlich
Wareneingang/-ausgang und Inventur Erforderlich Empfohlen Erforderlich Nicht erforderlich
Versandbestätigung und Bestandsabbuchung Erforderlich Erforderlich Erforderlich Empfohlen
Rechnungsstellung und Zahlungsabschluss Erforderlich Erforderlich Erforderlich Erforderlich
Verhindern von Verwechslungen bei Arzneimitteln und Gefahrstoffen Erforderlich Erforderlich Erforderlich Erforderlich

8. Zusammenfassung

Die Fehlerkorrektur von QR-Codes ist ein Mechanismus, um die ursprünglichen Codewörter aus einem gedruckten Muster wiederherzustellen. Diese Aufgabe erfüllt sie ordentlich. Unsere Messungen bestätigten das: Gegen zufällige Verschmutzung und gleichmäßige Bildverschlechterung las sie innerhalb des korrigierbaren Bereichs korrekt und gab jenseits davon ehrlich auf.

Das ist jedoch eine andere Sache als die Frage, ob die von der Anwendung empfangene Zeichenkette geschäftlich korrekt ist. Je nachdem, wo die Beschädigung landet, kann die Korrektur greifen und einen anderen, gültigen Wert erzeugen. Und was Structured Append, Zeichenkodierung und einen weiteren Code im Bildausschnitt betrifft — das sind Probleme außerhalb der Fehlerkorrektur, die nicht einmal eine Frage der Wahrscheinlichkeit sind.

Dass der Standard selbst schreibt „als scheinbar gültiges, aber anderes Codewort fehldekodiert“ und sich die Mühe macht, Fehldekodierungsschutz-Codewörter zu reservieren, fasst diese Struktur treffend zusammen. Selbst damit lässt sich die Wahrscheinlichkeit nur senken — weiter kann der Standard nicht gehen. Nur die den Wert empfangende Anwendung kann die verbleibende Lücke schließen.

Ein dekodierter Wert ist unvalidierte, von außen eintreffende Eingabe. Behandeln Sie ihn genau wie eine über die Tastatur eingetippte Zeichenkette — das ist, wie wir glauben, der richtige Umgang mit QR-Codes.


Testumgebung

Die Abschnitte 2 bis 4, die das Verhalten der Fehlerkorrektur betrachten, verwenden durchgehend Version 1-M (21×21 Module). Die Beispiele in Abschnitt 5 unterscheiden sich in der Version je nach Datenmenge und sind entsprechend pro Abschnitt vermerkt.

Punkt Details
Decoder 1 OpenCV 5.0.0 cv2.QRCodeDetector
Decoder 2 jsQR 1.4.0 (Node.js 22)
Erzeugung segno 1.6.6 / Python 3.11
Symbole in Abschnitt 2–4 Version 1-M / 21×21 (26 Codewörter = 16 Daten + 10 Fehlerkorrektur)
Abschnitt 5.1 (Structured Append) Alle drei Symbole Version 1-M / 21×21
Abschnitt 5.2 (Zeichenkodierung und ECI) Shift_JIS ist Version 2-Q, UTF-8 ist Version 2-M (beide 25×25), da 18–23 Byte japanischer Zeichen nicht in die 16 Datencodewörter von Version 1-M passen
Abschnitt 5.3 (mehrere Codes) NO: und ITEM: sind Version 1-M; LOT:AB-77 ist Version 1-H, weil die Daten kurz sind und segno die Fehlerkorrekturstufe erhöht (alle 21×21)
  1. DENSO WAVE Incorporated, Error correction feature | QRcode.com 

  2. ISO/IEC 18004 Information technology — Automatic identification and data capture techniques — QR code bar code symbology specification. Die Formel der Fehlerkorrekturkapazität e + 2t ≦ d - p, die Werte der Fehldekodierungsschutz-Codewörter p sowie die Aussage zur „Fehldekodierung als scheinbar gültiges, aber anderes Codewort“ stehen in 8.5.1 Error correction capacity; das (26,16,4) von Version 1-M und die Fußnote, dass „die Korrekturfähigkeit unter die Hälfte der Anzahl der Fehlerkorrekturcodewörter gesetzt wird, um die Wahrscheinlichkeit von Fehldekodierungen zu senken“, stehen in Tabelle 13 (Zitate basieren auf der Ausgabe von 2000). Die aktuelle Ausgabe ist ISO/IEC 18004:2024 2 3 4

  3. Die Standardinterpretation im Byte-Modus, wenn kein ECI angegeben ist, hat sich zwischen den Ausgaben des Standards geändert. ISO/IEC 18004:2000 Abschnitt 8.3.1 legte fest: „The default interpretation for QR Code is ECI 000020 representing the JIS8 and Shift JIS character sets“, aber ab der Ausgabe von 2006 (QR Code 2005) ist der Standardwert ECI 000003, also ISO/IEC 8859-1. Das bedeutet auch, dass sich auf eine nicht deklarierte Standardvorgabe zu verlassen, die Interpretation allein deshalb ändern lässt, weil sich die Ausgabe des Standards geändert hat 2

  4. GS1, GS1 General Specifications 

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Verhindert eine Fehlerkorrekturstufe H Fehllesungen?
Nein. Eine höhere Stufe erhöht die Menge an korrigierbarer Beschädigung, beseitigt aber nicht das Phänomen, dass „die Korrektur greift und einen anderen Wert erzeugt“. Die Reed-Solomon-Dekodierung funktioniert, indem nach einem Codewort innerhalb der Korrekturfähigkeit des empfangenen Musters gesucht wird — fällt die Beschädigung zufällig in die Nachbarschaft eines anderen Codeworts, wird dieses als Antwort zurückgegeben (weit entfernte Beschädigung endet schlicht mit „nicht lesbar“). ISO/IEC 18004 stellt ausdrücklich fest, dass dies zu einer „Fehldekodierung als scheinbar gültiges, aber anderes Codewort“ führt, und reserviert einen eigenen Vorrat an Codewörtern zum Schutz vor Fehldekodierung — aber auch das ist eine Maßnahme, die die Wahrscheinlichkeit senkt, keine Garantie. Eine Fehllesung lässt sich nur in der Anwendung abfangen, die den Wert empfängt.
Wie häufig kommt es in der Praxis tatsächlich zu QR-Fehllesungen?
Bei zufälliger Beschädigung praktisch nie. Bei den Messungen für diesen Artikel gab es über 3.900 Versuche mit zufällig umgeklappten Modulen und 5.800 Versuche mit zufällig beschädigten Codewörtern null Fälle, in denen ein falscher Wert zurückgegeben wurde. Beschädigung jenseits der Korrekturfähigkeit fällt auf die Seite von „nicht lesbar“. Reale Beschädigung ist jedoch nicht zufällig: Falten, Abrieb und verstopfte Druckköpfe haben alle eine positionelle Ausrichtung. Zudem ist das Verpassen eines Structured-Append-Symbols oder das Aufgreifen des falschen Codes unter mehreren nicht einmal eine Frage der Wahrscheinlichkeit — bei den richtigen Bedingungen passiert es jedes Mal.
QR-Codes haben doch Fehlerkorrektur — brauche ich trotzdem eine Prüfziffer?
Ja. Beide schützen unterschiedliche Ebenen. Fehlerkorrektur behandelt die Konsistenz innerhalb des Symbols und garantiert die Wiederherstellung nur bis zur Grenze ihrer Korrekturfähigkeit. Darüber hinaus kann Beschädigung in ein anderes gültiges Codewort „wiederhergestellt“ werden. Eine Prüfziffer dagegen prüft, ob die von der Anwendung empfangene Zeichenkette als Codeschema wohlgeformt ist. Sie erkennt eine einzelne Zeichenänderung zuverlässig, verpasst aber manche Fälle mit mehreren geänderten Zeichen. Ein Prüfwert nach Modulo 10 hat nur zehn Möglichkeiten, und dieser Artikel zeigt ein Beispiel, bei dem eine Änderung von zwei Ziffern dennoch mit der Prüfziffer übereinstimmt. Betrachten Sie die Prüfziffer daher als die Ebene, die den Großteil der Fehllesungen stoppt, und überlassen Sie die endgültige Beurteilung dem Stammdatenabgleich und der geschäftlichen Gegenprüfung. Ein Vorteil ist, dass dieselbe Prüfung auch manuelle Eingabe, Abschrift und über andere Wege eintreffende Importe schützt.
Die Kamera-App meines Handys hat es gelesen — dann ist der Wert doch sicher korrekt?
„Es wurde gelesen“ bedeutet nur, dass der Decoder eine nicht leere Zeichenkette zurückgegeben hat; es sagt nichts darüber aus, ob der Inhalt korrekt ist. Auch wie ein Fehlschlag signalisiert wird, unterscheidet sich je nach Implementierung — eine Ausnahme, eine leere Zeichenkette oder null sind alle möglich —, sodass es ebenfalls riskant ist, „es wurde keine Ausnahme ausgelöst“ als Erfolgskriterium zu verwenden. Bei den Messungen für diesen Artikel gab es mehrere Fälle, in denen OpenCV und jsQR für dasselbe Bild unterschiedliche Ergebnisse zurückgaben. Bei einem QR-Code mit japanischem Text in Shift_JIS gab der eine eine verstümmelte Zeichenkette als Erfolg zurück, während der andere eine leere Zeichenkette lieferte. Auch beim ersten Symbol eines Structured-Append-Satzes gingen die Ergebnisse auseinander. Ob etwas gelesen wurde, sagt nichts darüber aus, ob der Wert richtig ist.
Sollten wir Structured Append (geteilte QR-Codes) im geschäftlichen Einsatz vermeiden?
Sofern kein besonderer Grund vorliegt, ist das Vermeiden die sicherere Wahl. Structured Append ist ein Mechanismus, bei dem Daten auf mehrere Symbole verteilt werden und der Leser sie sammelt und zusammensetzt, aber das Verhalten, wenn ein Decoder ohne Unterstützung dafür nur das erste Symbol erhält, ist implementierungsabhängig. Bei den Messungen für diesen Artikel gab OpenCV eine abgeschnittene Belegnummer ohne Fehler zurück, während jsQR eine leere Zeichenkette lieferte. Da es Implementierungen gibt, die ein Fragment als plausibel aussehenden Wert durchreichen, benötigen Sie eine Validierung, die unvollständige Ergebnisse zurückweist, wenn Sie kein Structured Append erwarten. Passen die Daten nicht hinein, ist es sicherer, die QR-Version zu erhöhen oder den Code zu verkürzen und stattdessen auf Stammdatenabgleich zu setzen.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog