Du druckst einen vermeintlich kostenlosen QR-Code auf 500 Einladungen oder Speisekarten – und zwei Wochen später zeigt der Scan plötzlich eine Bezahlschranke statt deiner Webseite. Oder du möchtest eine Konfigurationsdatei, einen öffentlichen SSH-Schlüssel oder ein WLAN-Passwort auf ein zweites Gerät bringen, ohne Cloud-Dienst, Messenger-Konto oder USB-Stick dazwischenzuschalten.
Ein statischer QR-Code nach ISO/IEC 18004 kodiert deine Zeichenkette samt Fehlerkorrektur-Bytes direkt als Schwarz-Weiß-Matrix im Bild und kommt ohne fremden Weiterleitungsserver aus. Für größere Textmengen, Fotos und Dateien bis 1 MB verpackt ein optischer Frame-Stream Dateiname, MIME-Typ und Rohbytes in nummerierte, per CRC-16 gesicherte Einzel-QR-Codes (bei Fotos auf Wunsch vorab lokal per Canvas-WebP auf rund 20–35 QR-Pakete geschrumpft), die eine Webcam in beliebiger Reihenfolge abfilmt und lokal zusammensetzt.
Statische QR-Codes laufen niemals ab, weil die Zieladresse direkt im Punktmuster steckt statt hinter einer fremden Kurz-URL. Reicht ein einzelnes Quadrat für längere Texte oder Dateien nicht mehr aus, überträgt eine Schleife nummerierter QR-Frames die Daten rein optisch von Bildschirm zu Kamera.
Warum manche „kostenlose“ QR-Codes ablaufen und wie die Matrix wirklich funktioniert
Ein QR-Code kennt technisch kein Verfallsdatum. Wenn ein gedruckter Code nach einer Testphase plötzlich den Dienst verweigert, hast du keinen direkten Link kodiert, sondern einen dynamischen QR-Code: Im Bild steckt dann eine fremde Kurz-URL wie https://qr-anbieter.example/x7k9p, die erst auf dem Server des Anbieters auf dein eigentliches Ziel weiterleitet. Schaltet der Betreiber diese Weiterleitung ab, wird jeder Druck unbrauchbar.
Kodierst du deine echte Zieladresse oder ein standardisiertes Schema wie WIFI:T:WPA;S:MeinNetz;P:Geheim;; direkt in die Matrix, entsteht ein statischer QR-Code. Solange deine eigene Zieladresse existiert, bleibt das Muster unbegrenzt lesbar – nachträglich ändern lässt sich das Ziel auf bereits gedrucktem Papier allerdings nicht mehr, sofern du keine Weiterleitung auf deiner eigenen Domain einrichtest.
Fehlerkorrektur, Ruhezone und Polarität
Damit ein Code trotz Kratzern, Kaffeeflecken oder ungünstigem Kamerawinkel lesbar bleibt, ergänzt der Generator zusätzliche Prüfbytes über eine . Vier Stufen sind im Standard festgelegt:
- Stufe L (~7 % Redundanz): Kleinste Modulanzahl; sinnvoll für lange URLs auf sauberen Bildschirmen.
- Stufe M (~15 % Redundanz): Ausgewogener Standard für Visitenkarten, Flyer und Web.
- Stufe Q (~25 % Redundanz): Robuste Wahl für Aufkleber, Werkstätten oder leicht gewölbte Flächen.
- Stufe H (~30 % Redundanz): Höchste Reserve, erzeugt aber deutlich kleinere Einzelpunkte und erfordert sauberen Druck.
Ebenso entscheidend für zuverlässiges Scannen sind die sowie die Helligkeitspolarität: Der ISO-Standard erwartet dunkle Module auf hellem Grund. Viele Smartphone-Apps lesen heute zwar auch weiße Codes auf schwarzem Hintergrund, ältere Handscanner an Kassen oder Einlasskontrollen scheitern daran jedoch regelmäßig. Für verlässliche Lesbarkeit sollte das Kontrastverhältnis mindestens 4,5:1 betragen – dieselbe rechnerische Grundlage wie im Leitfaden zu Accessibility & BITV 2.0.
Wie die optische QR-Datenbrücke Texte und Dateien ohne Startsignal überträgt
Theoretisch fasst ein einzelner QR-Code der Version 40 bis zu 2.953 Bytes. Praktisch verschmelzen die winzigen Punkte auf normalen Laptop-Displays und Handykameras aber oft schon ab 350 bis 600 Bytes zu einem kaum fokussierbaren Flimmern.
Um dennoch Konfigurationsdateien, Fotos, Screenshots oder Schlüssel rein optisch über einen zu schicken, verpackt der Sender Dateiname, MIME-Typ und Rohbytes in einen kompakten Binär-Umschlag (2 Bytes Header-Länge + JSON-Metadaten + Datei-Bytes), teilt diesen in Pakete von 160 bis 950 Bytes auf und spielt sie mit bis zu 12 FPS als Endlosschleife ab. Große Kamerafotos (bis 25 MB) schrumpft eine vorgeschaltete <canvas>-WebP-Stufe direkt im Arbeitsspeicher auf rund 18 bis 30 KB – das entspricht bei 950 Bytes Paketgröße nur etwa 20 bis 32 QR-Codes:
1// Binärer LKQR2-Umschlag für Texte & Dateien inklusive CRC-16-CCITT-Sicherung2export function crc16Ccitt(bytes: Uint8Array): string {3 let crc = 0xffff;4 for (let i = 0; i < bytes.length; i++) {5 crc ^= bytes[i] << 8;6 for (let bit = 0; bit < 8; bit++) {7 crc = (crc & 0x8000) !== 0 ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff;8 }9 }10 return crc.toString(16).padStart(4, "0");11}12
13export function buildOpticalFileFrames(14 fileName: string,15 mimeType: string,16 fileBytes: Uint8Array,17 maxChunkBytes = 16018): string[] {19 const headerBytes = new TextEncoder().encode(20 JSON.stringify({ k: "file", n: fileName, t: mimeType })21 );22 const envelope = new Uint8Array(2 + headerBytes.length + fileBytes.length);23 envelope[0] = (headerBytes.length >> 8) & 0xff;24 envelope[1] = headerBytes.length & 0xff;25 envelope.set(headerBytes, 2);26 envelope.set(fileBytes, 2 + headerBytes.length);27
28 const crcHex = crc16Ccitt(envelope);29 const sessionId = `${crcHex}${envelope.length.toString(36)}`;30 const total = Math.ceil(envelope.length / maxChunkBytes);31
32 return Array.from({ length: total }, (_, i) => {33 const slice = envelope.slice(i * maxChunkBytes, (i + 1) * maxChunkBytes);34 const base64 = btoa(String.fromCharCode(...slice));35 // Format: Protokoll | Sitzung | Paket/Gesamt | Gesamt-CRC16 | Base64-Paket36 return `LKQR2|${sessionId}|${i + 1}/${total}|${crcHex}|${base64}`;37 });38}Woher weiß der Empfänger, wo der Anfang ist? Gar nicht über einen speziellen Start-Trigger, sondern über Selbstbeschreibung jedes einzelnen Bildes: Jedes QR-Paket trägt seine exakte Position (4/12), die Gesamtzahl (12) und die Session-ID im Klartext-Kopf. Schaltest du die Kamera mitten in der Schleife erst bei Paket 7 ein, legt der Browser sofort ein Map-Register für 12 Plätze an, liest 7..12 und im direkt anschließenden Schleifendurchlauf 1..6. Sobald alle Plätze gefüllt sind, sortiert er die Blöcke numerisch von 1 bis 12, prüft die CRC-16-Summe über den gesamten Datenstrom, liest ab Byte 0 den Dateinamen aus und bietet die Datei sofort zum Herunterladen an. Wie solche Werkzeuge dauerhaft als installierbare Web-App bereitstehen, vertieft Offline-KI & lokale Web-Apps.
Wann eignet sich ein QR-Code – und wann ist ein anderes Verfahren überlegen?
- Für Drucksachen immer SVG exportieren, damit Kanten im Layoutprogramm gestochen scharf bleiben
- Willst du ein Druckziel später ändern können, verlinke auf eine kurze Route deiner eigenen Domain statt auf fremde Gratis-Portale
- Beim Kamera-Stream moderate
4 FPSund160 BytesPaketgröße wählen – das schlägt zu dichte Einzelbilder mit vielen Scan-Wiederholungen
- Keine fremden Kurz-URL-Generatoren für Schilder, Visitenkarten oder Vereinsflyer ohne Einsicht in die Ziel-URL verwenden
- Keine hellen QR-Punkte auf dunklem oder stark gemustertem Foto-Hintergrund ohne helle Ruhezone platzieren
- Keine sensiblen Zugangsdaten oder privaten Schlüssel in serverseitige Online-Generatoren kopieren
Da die Kamera des Empfängers kein Funksignal an den Sender zurückschickt, weiß der sendende Bildschirm nicht, welches Paket dem Empfänger noch fehlt. Für Fotos empfiehlt sich deshalb die integrierte WebP-Stufe „Kompakt“ (~20–35 QR-Pakete, ein Umlauf dauert bei 8 FPS nur ~3–4 Sekunden) statt unkomprimierter Megabyte-Originale.
Prüfpunkte vor Druck oder Datenübertragung
- Inhalt vor dem Druck gegenprüfen: Scanne den fertigen Code mit der Standard-Kamera-App und lies die angezeigte Ziel-URL im Klartext – steht dort wirklich deine eigene Domain statt eines Weiterleitungsdienstes?
- Mindestgröße und Kontrast einhalten: Auf Papier mindestens
2 × 2 cmKantenlänge (bei langen vCards lieber3 × 3 cm), dunkle Module auf hellem Grund und mindestens4,5:1Kontrast wählen. - WLAN-Sonderzeichen testen: Enthält dein WLAN-Passwort Semikolon (
;), Doppelpunkt (:) oder Backslash (\), prüfe den Verbindungsaufbau einmal real an iOS und Android. - Optischen Stream blendfrei abfilmen: Beim Webcam-Transfer Bildschirmhelligkeit erhöhen und schräges Gegenlicht vermeiden, damit der Belichtungsmesser der Kamera das Raster nicht überstrahlt.
Quellen und nächste Schritte
- ISO/IEC 18004:2024 – Information technology — Automatic identification and data capture techniques — QR code bar code symbology specification: iso.org/standard/83389.html
- ZXing Project Documentation – Barcode Contents Specification (
WIFI:,VCARD,mailto:URI-Formate): github.com/zxing/zxing/wiki/Barcode-Contents - MDN Web Docs – MediaDevices.getUserMedia() & lokale Kamera-Verarbeitung im Browser: developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
- node-qrcode & jsQR (Open-Source-Referenzimplementierungen) – github.com/soldair/node-qrcode sowie github.com/cozmo/jsQR
- Weiterführend im Digital Garden: Lies Accessibility & BITV 2.0 zur exakten Berechnung von Luminanz-Kontrasten nach WCAG 2.2 oder Offline-KI in Web-Apps für den Service-Worker-Aufbau komplett lokal arbeitender PWAs.