QR-code op aanvoerbrief 2.xx.0: Specificaties Door: Datum 1e versie: Datum laatste wijziging Huidige Versie:
Bert Velthuijs 5 april 2012 (versie 0.xx) 20 september 2012 2.xx.0
Wijzigingen 19 juli 2012
Versie 1.xx: Compactere codering van de data, redactionele aanpassingen
20 september 2012
Versie 2.xx: Gewijzigde codering numerieke velden, 2 nieuwe datatypes, aanwijzingen voor het weglaten van records of kolommen, of downgraden toegevoegd.
Inhoudsopgave 1. Inleiding.......................................................................................................................................................3 2. Versies.........................................................................................................................................................3 3. Blokstructuur van de QR-code..................................................................................................................3 3.1 Terminator..............................................................................................................................................3 4. Header..........................................................................................................................................................4 5. Metadata......................................................................................................................................................4 6. Kolomdefinities...........................................................................................................................................4 6.1 Structuur van een kolomdefinitie (16 bit)................................................................................................4 7. Codering/decodering van datavelden.......................................................................................................5 8. Compacteren...............................................................................................................................................6 8.1 Weglaten van lege partijen....................................................................................................................6 8.2 Weglaten van lege kolommen................................................................................................................6 8.3 Downgraden van een kolomdefinitie......................................................................................................6 9. Voorbeelden van datavelden......................................................................................................................7
2
1. Inleiding Dit document bevat de technische specificatie van de QR-code op de aanvoerbrief. Andere relevante documenten: - QR-code op aanvoerbrief: Achtergrondinformatie - QR-code op aanvoerbrief: Specificaties velden Voorbeelden en testmogelijkheden zijn te vinden op de site www.anteater.nl.
2. Versies In de QR-code wordt een major- en minor versienummer opgeslagen: Vers_maj Major versienummer: Dit nummer geeft aan in welke structuur de data gegoten is. Als dit nummer verandert, is er andere software nodig om de gegevens te kunnen decoderen. Vers_min
Minor versienummer: In het document “QR-code op aanvoerbrief: Specificaties velden” is gespecificeerd wanneer dit nummer verhoogd wordt. Oude software zal een QR-code met een hoger minor versienummer, maar hetzelfde major versienummer nog steeds kunnen lezen.
Het onderliggende document is van toepassing op alle QR-codes die hetzelfde major versie nummer hebben, ongeacht het minor versie nummer. Als er in het document redactionele aanpassingen gedaan worden zonder dat de technische specificatie wijzigt, wordt het document versievolgnummer opgehoogd. Wijzigt het major- of minor versienummer, dan begint het document versievolgnummer weer op nul. Het versienummer van dit document is als volgt samengesteld: <Major versienummer QR-code> .xx..
.
3. Blokstructuur van de QR-code Hieronder is de opzet van de data-inhoud voor de QR-code weergegeven. Elk blokje in het diagram beslaat een geheel aantal bytes. Brief-data en Partij-data worden zonodig met enkele trailing 0-bits aangevuld tot een geheel aantal bytes. Header
Metadata
Brief-kolomdefinities
Terminator
Brief-data Partij-kolomdefinities
Terminator
Partij-data (minimaal 1 tot maximaal 6 partij regels)
Er is geen terminator tussen de brief-datavelden en de partij-kolomdefinities. De plaats waar de partijkolomdefinities beginnen moet worden bepaald aan de hand van het begin van de brief-datavelden en de opgegeven lengtes van de brief-datavelden. De volgorde van de partijen in de QR-code komt overeen met de volgorde op de aanvoerbrief.
3.1 Terminator De terminator is 8 bits en heeft de waarde 00h. De waarde 00h kan nooit het eerste byte van een geldige kolomdefinitie zijn, omdat dit een veldlengte 0 zou betekenen.
3
Als er een terminator wordt gedetecteerd, betekent dit het einde van de kolomdefinities, en het begin van de datavelden. Er volgt dan dus geen tag-byte.
4. Header De header is vijf bytes groot, en bestaat uit de volgende velden: Veldnaam
Type
Opmerking
Vers_maj
byte
Mogelijke waardes: 0-255. QR-codes volgens dit document hebben Vers_maj = 2
Vers_min
byte
Mogelijke waardes: 0-255
Fingerprint 2 bytes Vaste waarden: 0xAC, 0x53. Om eenvoudig te testen of een gescande code volgens deze specificatie gemaakt is. Meta_sz
byte
Het aantal bytes in het volgende blokje: meta-data.
5. Metadata Welke metadata opgenomen is, is gespecificeerd in het document “QR-code op aanvoerbrief: Specificaties velden”. Zolang hier in de toekomst alleen nieuwe velden aan toegevoegd worden, kan oude software de onbekende velden simpelweg overslaan, en wordt alleen het minor versienummer opgehoogd.
6. Kolomdefinities De 'kolomdefinities' worden gebruikt om aan te geven welke informatievelden er in het daarop volgende datablok aanwezig zijn, en wat het datatype en de lengte van de velden is. De Partij-kolomdefinities komen maar 1x voor in de QR-code. Elke partijregel bevat dan ook dezelfde partijdatavelden in de QR-code. Een kolomdefinitie-reeks wordt afgesloten met een terminator. De volgorde van de kolomdefinitie-velden is niet van belang. De volgorde van de datavelden moet uiteraard wel hetzelfde zijn als de volgorde van de bijbehorende kolomdefinities.
6.1 Structuur van een kolomdefinitie (16 bit) Aantal bits 2
6
8
Betekenis Type Lengte Tag Identificatie van de betekenis van de data ( geldige waarden: 1..255 ) Vaste lengte van een dataveld in tekens ( 1..63 ) Datatype (0..3) Zie hieronder de tabel voor de types, en de betekenis van het veld “Lengte” voor elk type. Code
Type
Lengte
Toelichting
0
Bit:
1
Een boolean wordt altijd opgeslagen als precies 1 bit. Een numerieke waarde van 0 of 1 kan ook in een bit opgeslagen worden.
1
Numeriek:
Aantal digits
Een binair getal gegroepeerd per 3 digits, met een aantal bits dat precies voldoende is om de hoogste getalswaarde te bevatten.
4
2
Alfanumeriek: Aantal karakters
Een reeks van 6 bit codes (0x00 tot 0x3F, 64 waarden).
3
Binair:
Een reeks van 8 bit codes (0x00 tot 0xFF)
Aantal bytes
Opmerking: Het Datatype in de kolomdefinitie geeft aan op welke wijze een veld gecodeerd is. Dit kan afwijken van het datatype van de informatie. Zo kunnen b.v. de sorteerkenmerken (die qua informatie alphanumeriek zijn, en zodanig in de invulinstructie zijn aangegeven), gecodeerd worden als numeriek, als in een bepaalde kolom alleen numerieke waarden voorkomen.
7. Codering/decodering van datavelden Numeriek De lengte van een numeriek veld geeft het maximaal aantal posities van het getal aan bij decimale weergave. Bij het coderen wordt een getal opgehakt in groepjes van drie digits (triplets), om het coderen en decoderen van lange numerieke reeksen te vereenvoudigen. Bij het vormen van triplets wordt gerekend vanaf het minst significante digit. Het getal 27653 wordt dus 27 653. De binaire getalswaarden van de resulterende groepjes worden, het meest signifante groepje eerst, in de data gezet. Het aantal bits dat gecodeerd moet worden kan eenvoudig berekend worden uit de lengte (L): Bits = ceil( 3.333 * L). Elk veld heeft een vaste breedte, dus exact dit aantal bits moet in de output gezet worden, of uit de input gelezen worden. Zonodig worden leading zero-bits toegevoegd. Voor het gemak volgt hier een tabel waaruit afgelezen kan worden hoeveel bits nodig zijn voor een numerieke veld met een lengte tussen 1 en 13: L
1
2
3
4
5
6
7
8
9
10
11
12
13
Bits
4
7
10
14
17
20
24
27
30
34
37
40
44
Als een numeriek veld gebruikt wordt om een alphanumeriek gegeven te coderen, kan een lege string gecodeerd worden als Alfanumeriek De Edifact specificatie stelt dat de UNOA karakterset gelijk is aan de ISO 646 karakterset, met uitzondering van de kleine letters. Dit komt neer op de volgende karakters: A..Z, 0..9, en <spatie>!”%&'()*+,-./:;<=>?_ Elk van deze karakters kan in 6 bits gecodeerd worden door de ASCII-waarde te nemen en daar 20h van af te trekken. Bij het decoderen moet er weer 20h bij opgeteld worden om de ASCII-waardes terug te winnen. Het maximaal aantal bits voor een alfanumeriek veld kan eenvoudig berekenden worden: Max = 6 x L Aangezien de velden een vaste lengte hebben, kan het nodig zijn tekens toe te voegen om aan de voorgeschreven lengte te komen. In dat geval zullen voorloopspaties toegevoegd worden, wat in de binaire representatie neerkomt op voorloopnullen, aangezien een spatie gecodeerd wordt als 6 nul-bits. Binair Dit datatype maakt het mogelijk reeksen van 8 bit codes in een veld op te slaan. Op dit moment (20 september 2012) wordt dit niet in de invulinstructie gebruikt, maar in de toekomst kan dat veranderen. Lege velden De standaard methode om een leeg veld te vullen, is eenvoudigweg het veld uit te vullen tot de vereiste 5
veldbreedte. Het hele veld zal dan 0-bits bevatten. Bij downgraden van een kolomdefinitie kan hierop een uitzondering ontstaan, zie daarvoor paragraaf 7.3.
8. Compacteren Hier volgen enkele technieken die de benodigde hoeveelheid bits voor het coderen van een aanvoerbrief verder kunnen reduceren. Toepassing hiervan leidt tot minder data, grovere modules, en dus betere leesbaarheid. Het staat een applicatie vrij om de hier genoemde technieken bij het coderen al dan niet toe te passen. Voor een decoderende applicatie maakt het geen verschil, aangezien deze uit de kolomdefinities de toegepaste type en lengte kan lezen.
8.1 Weglaten van lege partijen. Er hoeven niet meer partijen gecodeerd te worden dan er op de brief staan.
8.2 Weglaten van lege kolommen Als alle velden in een bepaalde kolom leeg zijn, mag deze kolom weggelaten worden. Ook een verplicht veld kan weggelaten worden als alle velden anders alleen 0-bits zouden bevatten. Een veld kan gezien worden als leeg als de lengte nul is, of als de gecodeerde data (vóór eventueel downgraden) uitsluitend uit 0-bits bestaat. Een decoderende applicatie zal alle waarden dus op een default waarde moeten initialiseren: 0 voor numeriek, voor strings.
8.3 Downgraden van een kolomdefinitie Een invulinstructie geeft aan wat het datatype en de lengte moeten zijn om alle mogelijk voorkomende waarden op te slaan. In de praktijk kan het echter zijn, dat de actuele waardes van velden toelaten dat een datatype gekozen wordt dat minder bits kost. In dat geval mag dat compactere type gebruikt worden. Uiteraard moet voor de partijdata gekeken worden naar álle partijen. Er mag uitsluitend gedowngrade worden, dus binair→ alphanumeriek → numeriek → bit. Lengtes mogen korter gemaakt worden, nooit langer. Om te voorkomen dat een alphanumeriek veld niet naar numeriek gedegradeerd kan worden omdat één of meer velden leeg zijn, moet het mogelijk zijn een lege string in een numeriek veld te coderen. Het vullen van het veld met 0-bits zou '0' opleveren bij decoderen. De gekozen oplossing is het meest significante triplet de hoogst geldige waarde+1 te geven. Afhankelijk van de lengte van het veld is dat dus 10, 100, of 1000. De eenvoudigste methode om deze situatie bij het decoderen te detecteren, is het decoderen op de normale wijze te doen, en achteraf te testen op de lengte van de resultaat-string.
6
9. Voorbeelden van datavelden Hieronder volgen twee voorbeelden. Bij de bitreeksen zijn spaties toegevoegd ter verduidelijking. Deze spaties komen in de praktijk dus niet voor; het is een aaneengesloten bitreeks. De betekenis van de tags is terug te vinden in het document “QR-code op aanvoerbrief: Specificaties velden”
Numeriek voorbeeld voor 'Productcode = 27563': Indicator = 'N' Lengte = 5 (gedowngrade vanaf 7) Tag = 133 (Productcode) Kolomdefinitie: 01 000101 10000101 (N Dataveld:
5
133 )
0011011 1000110011 (
27
563 )
Aangezien de lengte van het groepje '27' 2 posities (cijfers) is, is het grootste getal dat gecodeerd moet kunnen worden 99 , en hier zijn 7 bits voor nodig. 11011 is de binaire representatie van 27, en beslaat 5 bits. Het dataveld is daarom met 2 voorloopnullen aangevuld.
Alfanumeriek voorbeeld voor 'Eerste sorteerkenmerk, Minimum steellengte=45': Indicator = 'A' Lengte = 6 Tag = 150 Kolomdefinitie: 10 000110 10010110 (A Dataveld:
6
150 )
110011 010010 010000 ( 33h='S' 12h='2' 10h='0'
010000 010100 10h='0'
14h='4'
010101 15h='5' )
'S20045' bevat 6 tekens. Dit is ook de lengte die de kolomdefinitie aangeeft, er zijn dus geen voorloopspaties nodig. Een eventuele voorloopspatie zou gecodeerd worden als 6 leading nul-bits. De lengte van het dataveld in dit voorbeeld is 6 x 6 = 36 bits.
7