Geeks With Blogs

News

View Anthony Trudeau's profile on LinkedIn

Add to Technorati Favorites


Anthony Trudeau

The EPCglobal tag data standards provides a calculation for the GTIN (global trade item number) check digit during SGTIN (serialized global trade item number) decoding.  However, this algorithm although mathematically correct does not work computationally due to different methods of handling modulus for negative numbers.

The tag data standards document defines the calculation for the GTIN check digit as:

d14 = (-3(d1 + d3 + d5 + d7 + d9 + d11 + d13) - (d2 + d4 + d6 + d8 + d10 + d12)) mod 10

The algorithm in the tag data standards document will always lead to calculating the modulus of a negative.  Therefore, the check digit will usually be incorrect.  For example, -57 mod 10 should mathematically be 3 not -7 as calculated by the .NET Framework and CALC.EXE for that matter (Microsoft Excel returns 3.)

But, taking into account the complication from calculating modulus on negative numbers, as well as factoring in UCC-12, EAN/UCC-13, and EAN/UCC-14 GTIN formats you get a slightly more complex algorithm that the following helper class illustrates.  This helper class leverages the EPC expansion pack for the GlobeRanger iMotion EdgeWare platform in order to parse either the 64-bit or 96-bit SGTIN values.  You could also substitute your own parsing algorithm.

Imports:

using System;
using Globeranger.Core.Epc.Encoding;
using Globeranger.Core.Epc.Encoding.Sgtin;

Class:

public class GtinResolver
{
     public static string CheckDigitFromGtin(string gtin)
     {
          switch (gtin.Length)
          {
               case 11: // UCC-12 format
                    return CheckDigitFromGtin12(gtin);

               case 12: // UCC-13 format
                    return CheckDigitFromGtin13(gtin);

               case 13: // UCC-14 format
                    return CheckDigitFromGtin14(gtin);

               default:
                    throw new NotSupportedException("Unsupported GTIN format");
          }
     }

     private static string CheckDigitFromGtin12(string gtin)
     {
          int[] digits = ToIntArray(gtin);
          int checkValue = 10 - ((((digits[0] + digits[2] + digits[4] + digits[6]
               + digits[8] + digits[10]) * 3) + (digits[1] + digits[3] + digits[5]
               + digits[7] + digits[9])) % 10); 

          return checkValue.ToString();
     }

     private static string CheckDigitFromGtin13(string gtin)
     {
          int[] digits = ToIntArray(gtin);
          int checkValue = 10 - (((digits[1] + digits[3] + digits[5] + digits[7]
               + digits[9] + digits[11]) * 3 + (digits[0] + digits[2]
               + digits[4] + digits[6] + digits[8] + digits[10])) % 10);

          return checkValue.ToString();
     }

     private static string CheckDigitFromGtin14(string gtin)
     {
          int[] digits = ToIntArray(gtin);
          int checkValue = 10 - ((((digits[0] + digits[2] + digits[4] + digits[6]
          + digits[8] + digits[10] + digits[12]) * 3)
          + (digits[1] + digits[3] + digits[5] + digits[7] + digits[9]
          + digits[11])) % 10);

          return checkValue.ToString();
     }

     public static string FromEncodedSgtin64Urn(string urn, string companyPrefix)
     {
          Sgtin64BitPayload payload = new Sgtin64BitPayload(urn);
          string gtin = payload.ItemReference.Substring(0, 1)
               + companyPrefix + payload.ItemReference.Substring(1);
          string checkDigit = CheckDigitFromGtin(gtin);

          return gtin + checkDigit;
     }

     public static string FromEncodedSgtin96Urn(string urn)
     {
          Sgtin96BitPayload payload = new Sgtin96BitPayload(urn);
          string gtin = payload.ItemReference.Substring(0, 1)
               + payload.CompanyPrefix + payload.ItemReference.Substring(1);
          string checkDigit = CheckDigitFromGtin(gtin);

          return gtin + checkDigit;
     }

     private static int[] ToIntArray(string value)
     {
          int[] digits = new int[value.Length];

          for (int i = 0; i < digits.Length; i++)
          {
               digits[i] = int.Parse(value.Substring(i, 1));
          }

          return digits;
     }
}

Posted on Tuesday, February 21, 2006 12:36 PM | Back to top


Comments on this post: Calculating a GTIN Check Digit

# re: Calculating a GTIN Check Digit
Requesting Gravatar...
I might be mistaken, but if I'm calculating the check digit for GTIN14 in the same way you are doing in CheckDigitFromGtin14() I get incorrect check digits when the sum of the 13 digits passed end with a 0, e.g. 50, 60, 70, etc.

Using the following 13 digits as an example 6009163500109:
The sum of the digits according to the formula = 80.
10 - (80%10) = 10. In my code it caused it to return 1 as the check digit and not 0. My result would thus be 60091635001091 whereas the correct result is 60091635001090.

I used the following GTIN calculator.
http://www.gs1.org/barcodes/support/check_digit_calculator

Regards



Left by Gerhard on Sep 28, 2009 8:37 AM

# re: Calculating for Delaware UCC/Financing Statement filing number check digit
Requesting Gravatar...
Hi. Does anybody know the mathematical formula used to determine the check digit for Delaware's UCC filing number? I'd really appreciate any help on this. Thank you very much and god bless.
Left by Gorby Tan on Feb 12, 2010 5:56 AM

Your comment:
 (will show your gravatar)


Copyright © Anthony Trudeau | Powered by: GeeksWithBlogs.net