Hoe werkt een QR-code echt? De techniek achter het pixelmozaïek
Even je smartphonecamera erop richten is genoeg – en meteen opent een website, maakt je telefoon verbinding met de wifi of wordt een vCard in je adresboek opgeslagen. Wat in het dagelijks leven als magie aanvoelt, is een uiterst doordachte combinatie van informatica, wiskunde en optica.
Maar hoe ontstaat uit een lang internetadres of een tekst eigenlijk dat kenmerkende zwart-witpatroon? Waar zitten de gegevens in de code verborgen en waarom herkent de camera de inhoud zelfs als de QR-code schuin staat of licht beschadigd is?
In dit artikel ontleden we de werking van de Quick Response Code (QR-code) stap voor stap.
1. Het basisprincipe is eenvoudig: tekens worden nullen en enen.
Computers spreken binair, dat wil zeggen: ze begrijpen uitsluitend 0 en 1. Voordat informatie als patroon in een QR-code kan worden weergegeven, moet ze dus eerst in bits worden omgezet. Om opslagruimte te besparen, gebruikt de QR-software verschillende coderingsmodi:
- Numerieke modus: voor alleen cijfers (0–9). Zeer efficiënt, omdat telkens drie cijfers in tien bits worden samengevat.
- Alfanumerieke modus: voor cijfers, hoofdletters en een selectie speciale tekens.
- Bytemodus: voor algemene teksten, kleine letters, letters met accenten (UTF-8) en URL's.
- Kanjimodus: speciaal gecomprimeerd voor Japanse tekens.
Een kijkje achter de schermen laat zien hoe „QR” een binaire code wordt.
Om te begrijpen hoe ruimtebesparend een QR-code werkt, bekijken we de alfanumerieke modus. Elk teken krijgt daarbij een vaste getalswaarde (A = 10, B = 11, ..., Q = 26, R = 27).
Zodat niet elke letter afzonderlijk opgeslagen hoeft te worden, voegt het algoritme telkens twee tekens samen.
- De waarden van Q (26) en R (27) worden verrekend: $26 \times 45 + 27 = 1197$.
- Het getal 1197 wordt weergegeven als binair getal van 11 bits:
10010101101.
Zo worden de twee letters QR precies 11 bits aan nullen en enen. Blijft er aan het eind van een reeks één letter over, dan wordt die met 6 bits gecodeerd (bijv. $Q \rightarrow 26 \rightarrow 011010$).
2. De weg van binaire code naar het uiteindelijke beeldpatroon
Zodra je tekst in een reeks nullen en enen is vertaald, doorloopt die meerdere technische verwerkingsstappen:
Stap A: Technische extra gegevens en foutcorrectie
De reeks nullen en enen met je inhoud bestaat niet alleen daaruit. Voor de nuttige gegevens wordt een header geplaatst. Die vertelt de scanner: „Let op, nu komt een tekst in bytemodus met een lengte van 25 tekens!”
Daarna berekent een wiskundige methode, de zogeheten Reed-Solomon-foutcorrectie, extra beveiligingsbits. Die zorgen ervoor dat de code zelfs dan nog leesbaar is als tot ongeveer 30 % van de gegevens (niveau H) bedekt of beschadigd is (bijv. door een bedrijfslogo in het midden).
Stap B: Verdeling in het raster (modules)
De afzonderlijke vierkantjes in een QR-code heten modules. In principe geldt:
- 0 = witte module
- 1 = zwarte module
De bits worden echter niet gewoon regel voor regel van linksboven naar rechtsonder ingeschreven. De gegevensplaatsing begint rechtsonder en slingert in smalle kolommen van twee afwisselend omhoog en omlaag door het raster. Daarbij worden gereserveerde functiegebieden (zoals de hoeken) automatisch overgeslagen.
Daarom kun je in een kant-en-klare QR-code nooit naar één zwart vierkantje wijzen en zeggen: „Dit hier is de ‚h‘ in het webadres.“
Stap C: De maskeringstruc (waarom 1 niet altijd zwart is)
Zouden de bits direct getekend worden, dan kunnen er toevallig grote zwarte blokken, lange witte strepen of misleidende patronen ontstaan die de camerasoftware in de war brengen.
Daarom legt de software een maskeringspatroon over de matrix. Er zijn in totaal acht gestandaardiseerde maskers. Via een wiskundige XOR-bewerking draait het masker bepaalde bits om:
- 0 wordt 1 (wit wordt zwart)
- 1 wordt 0 (zwart wordt wit)
De scanner herkent aan de formaatinformatie naast de hoekvierkanten welk masker is gebruikt, en maakt die stap bij het uitlezen in een fractie van een seconde weer ongedaan.
3. De anatomie van een QR-code: wat betekenen de afzonderlijke patronen?
Bekijk je een QR-code van dichtbij, dan lijkt hij een willekeurig mozaïek. In werkelijkheid is elk afzonderlijk element strikt volgens ISO-norm geplaatst. Je kunt de opbouw vergelijken met de anatomie van een gezicht. Bepaalde kenmerken zitten altijd op dezelfde plek, zodat de smartphone de code in één oogopslag herkent.
Een klassieke QR-code is verdeeld in de volgende hoofdzones:
1. De drie grote hoekvierkanten (positiedetectiepatronen/finder patterns)
- Ze zitten linksboven, rechtsboven en linksonder.
- Wat ze doen: ze zijn het meest opvallende aan een QR-code. Deze drie ankerpunten vertellen de camera meteen: „Let op, hier staat een QR-code!” Ze verraden de software bliksemsnel de positie, de grootte en de hellingshoek, zodat de camera herkent of de smartphone recht of schuin wordt gehouden.
2. De gestippelde verbindingslijnen (timing patterns)
- Ze lopen tussen de drie hoekvierkanten – horizontaal tussen linksboven en rechtsboven, verticaal tussen linksboven en linksonder. Ze bepalen het raster (modulegrootte); de oriëntatie komt van de drie hoekvierkanten.
- Wat ze doen: deze lijnen bestaan uit afwisselend zwarte en witte modules. Ze werken als een liniaal voor de scanner: aan de hand van deze punten telt de software hoe groot het rastersysteem is (van versie 1 met 21 × 21 velden tot versie 40 met 177 × 177 velden).
3. De kleine binnenste vierkanten (uitlijningspatronen/alignment patterns)
- Ze zitten rechtsonder en bij complexe codes verspreid over het hele patroon.
- Wat ze doen: deze kleinere vierkanten dienen als digitale vizierkruizen. Ze helpen de scanner vervorming te compenseren, bijvoorbeeld als de QR-code op een gebogen colablikje is gedrukt of de flyer gekreukt is.
4. De stuurzone (formaatinformatie)
- Ze ligt direct naast de drie grote hoekvierkanten.
- Wat ze doet: hier staan de technische instructies voor de scanner. In deze paar pixels zijn twee cruciale gegevens opgeslagen: welk foutcorrectieniveau (L, M, Q of H) wordt gebruikt en welk maskeringspatroon over de gegevens is gelegd.
5. Het onzichtbare beschermkader (rustzone/quiet zone)
- Dit is de volledig witte, onbedrukte rand rond de hele QR-code.
- Functie: om de buitenranden van de code goed te kunnen vastleggen, heeft de camera een veiligheidsafstand nodig tot teksten, afbeeldingen of achtergrondgraphics. Deze rand moet minstens vier modules (pixelbreedtes) dik zijn. Ontbreekt de rustzone, dan weigert de camera vaak te scannen.
4. Wat gebeurt er bij het scannen op je smartphone?
Als je je camera op een QR-code richt, vinden op de achtergrond de volgende stappen plaats:
- Zoeken: De camera doorzoekt het videobeeld naar de drie grote finder patterns.
- Transformeren: De software berekent het perspectief en "trekt" een eventueel schuin gefotografeerd beeld digitaal recht.
- Demaskeren: Het rastersysteem leest de formaatinformatie uit, herkent het maskeringspatroon en heft het masker op.
- Foutcorrectie toepassen: Eventuele krassen, onscherpte of afdekkingen worden wiskundig hersteld.
- Decoderen: De nullen en enen worden volgens de modusregels weer omgezet in leesbare tekst, getallen of stuurcommando's.
- Actie uitvoeren: De smartphone herkent het gegevenstype (bijv.
https://voor een URL,WIFI:voor toegangsgegevens ofBEGIN:VCARDvoor contacten) en stelt de passende app voor.
Technical deep-dive: de belangrijkste vragen uitgelegd
Heb je internet nodig om een QR-code te scannen?
Nee, niet voor het scannen zelf. Het omzetten van de pixels in tekst gebeurt lokaal op je smartphone. Is de inhoud gewone tekst, een vCard of wifi-toegangsgegevens, dan werkt alles volledig offline. Pas als de code een internetadres (URL) bevat en je dat wilt openen, heb je een dataverbinding nodig.
Is een QR-code versleuteld?
Nee. Een QR-code is alleen gecodeerd, niet versleuteld. Elke universele QR-codescanner kan de gegevens erin uitlezen. Vertrouwelijke informatie zoals wachtwoorden, bankgegevens of persoonlijke pincodes hoort daarom nooit onbeschermd in een standaard QR-code.
Waarom zien sommige QR-codes er veel fijner en dichter uit dan andere?
Hoe meer gegevens direct in de code worden opgeslagen – bijvoorbeeld een lange tekst in vergelijking met een korte link –, hoe meer modules er nodig zijn. De code gaat dan over naar een hogere versie (van versie 1 met 21 × 21 modules tot versie 40 met 177 × 177 modules).
Statisch vs. dynamisch: waarom dynamische codes compacter blijven
- Statische QR-codes: Slaan het uiteindelijke doel (bijv. een URL van 150 tekens) direct op. Het patroon wordt erg dicht en moeilijker te scannen.
- Dynamische QR-codes: Slaan alleen een ultrakorte doorverwijslink op (bijv.
qron.ch/12da7). De code blijft visueel heel eenvoudig, makkelijk te scannen en het eigenlijke doel kan op de server altijd worden vervangen, zonder dat de code opnieuw gedrukt hoeft te worden.
Checklist voor werkende QR-codes
Maak je zelf QR-codes of laat je ze ontwerpen, let dan op deze basisprincipes:
- Korte links gebruiken: Gebruik dynamische QR-codes om de moduledichtheid laag te houden.
- Contrast bewaren: Kies een donker patroon op een lichte achtergrond (geïnverteerde codes geven sommige oudere camera's problemen).
- Rustzone respecteren: Laat minstens 4 modules ruimte tot teksten, snijranden of afbeeldingen.
- Foutcorrectie aanpassen: Een logo gebruikt foutcorrectiereserve – hoe groter het logo, hoe hoger het niveau moet zijn. Bij dynamische codes stelt QRown het niveau in en controleert het de scanbaarheid na het ontwerpen.
Veelgestelde vragen (FAQ)
Uit hoeveel modules bestaat een QR-code?
De kleinste QR-codes (versie 1) bestaan uit 21 × 21 modules, dus 441 velden. De grootste variant (versie 40) heeft een raster van 177 × 177 modules, dus 31.329 velden.
Kan een QR-code virussen of malware bevatten?
Een QR-code zelf bevat alleen tekst en kan geen schadelijke programmacode direct uitvoeren. Hij kan echter naar een gemanipuleerde phishingwebsite of een schadelijke download leiden. Controleer daarom vóór het openen altijd de domeinvoorvertoning op je smartphone!
Welke modus bespaart de meeste ruimte in een QR-code?
Het efficiëntst is de numerieke modus (alleen cijfers), gevolgd door de alfanumerieke modus. De bytemodus (voor algemene URL's en speciale tekens) heeft daarentegen de meeste opslagruimte per teken nodig.