barcodegs1-datamatrix

How to calculate the variable weight/price check digit in a GTIN?


The GS1 standard defines GTIN codes that contain a 4 or 5 digit variable weight or price. This variable weight or price part needs to be validated with a check digit.

How can I calculate this check digit in code? Please be aware that this check digit is not calculated the same way as the default check digit at the end of the GTIN.

For reference: https://www.gs1.org/docs/barcodes/GS1_General_Specifications.pdf Page 466/467


Solution

  • You did not specify the language of choice, so hopefully this will be useful to you. Essentially it can be boiled down to array lookups and simple math. This code is written is AutoITScript, but it should be simple to translate to others.

    I am sure this code could be made smarter (with 2d array lookup, functions etc) but for simplicity I made it more readable.

    It should be noted that AutoIT is not a typed language, so 1234 can be treated as a number and a string all the same. Also that AutoIT uses $var[index1][index2] to access a 0-based array value.

    Hope this helps you on ! If so, please accept solution.

    RESULTS

    ============= barcode checksum variable length ================
    https://www.gs1.org/docs/barcodes/GS1_General_Specifications.pdf section 7.9.2
    ----------------------
    Doing checksum on 4 digits: 2875
    digit 1 is: 2 --> Check = 4
    digit 2 is: 8 --> Check = 5
    digit 3 is: 7 --> Check = 1
    digit 4 is: 5 --> Check = 3
     ==> Sum is 39
     ==> CHECK DIGIT IS RIGHT-MOST DIGIT = 9
    ----------------------
    Doing checksum on 5 digits: 14685
    digit 1 is: 1 --> Check = 5
    digit 2 is: 4 --> Check = 8
    digit 3 is: 6 --> Check = 7
    digit 4 is: 8 --> Check = 4
    digit 5 is: 5 --> Check = 9
     ==> Sum is 33
     ==> CHECK DIGIT IS 40-sum =  7
    

    The code

    #include <String.au3>
    
    ; barcode checksum
    ; https://www.gs1.org/docs/barcodes/GS1_General_Specifications.pdf section 7.9.2
    ;
    
    ConsoleWrite("============= barcode checksum variable length ================" & @CRLF)
    ConsoleWrite("https://www.gs1.org/docs/barcodes/GS1_General_Specifications.pdf section 7.9.2" & @CRLF)
    
    ;                      index 0              index 1                index 2                index 3
    ;                     --- wf2- ----------   ---  wf3 -----------   --- wf5+  ----------   ---- wf5- ----------
    Static $f[4][10] = [ [0,2,4,6,8,9,1,3,5,7], [0,3,6,9,2,5,8,1,4,7], [0,5,1,6,2,7,3,8,4,9], [0,5,9,4,8,3,7,2,6,1]   ]
    
    ;                              4 digit version   5 digit version
    static $lookupTables[2][5] =[  [ 0, 0, 1, 3] ,  [ 2, 0, 3, 2, 0] ]
    
    ; ==================================
    ; show some examples
    _calcit(2875)
    _calcit(14685)
    
    
    ; -------------------- function to calculate digits
    ;
    Func _calcit($thenumber)
        ; assume the length is correct here
        ; theNumber is now array [0] is left-most
        local $arrayNumber = _StringExplode($thenumber, "", 0)
        local $t  ; our lookup digit
        local $tSum ; summarized
        local $theversion = 0   ; 0 = 4 digit, 1 = 5 digits
        if StringLen($thenumber) = 4 then
                $theversion = 0
        else
                $theversion = 1
        endif
    
        ConsoleWrite("----------------------" & @CRLF)
        ConsoleWrite("Doing checksum on " & StringLen($thenumber) &  " digits: " & $thenumber & @CRLF)
        for $i = 0 to StringLen($thenumber)-1
            ConsoleWrite("digit " & $i+1 & " is: " & $arrayNumber[$i])
            ;lookup the number in our 2d array. Which row determined by the lookup table.
            $t = $f [$lookupTables[$theversion][$i]] [$arrayNumber[$i] ]
            ConsoleWrite(" --> Check = " & $t & @CRLF)
            $tSum = $tSum + $t
        Next
    
        if $theversion = 0 then
            $tSum = $tSum * 3
            ConsoleWrite(" ==> Sum is " & $tSum & @CRLF)
            ConsoleWrite(" ==> CHECK DIGIT IS RIGHT-MOST DIGIT = " & StringRight($tSum, 1) & @CRLF)
        else
            ConsoleWrite(" ==> Sum is " & $tSum & @CRLF)
            $tSum = 40-$tSum
            ConsoleWrite(" ==> CHECK DIGIT IS 40-sum =  " & StringRight($tSum, 1) & @CRLF)
        EndIf
    EndFunc