An algorithm to calculate the check digit for 18-digit SSCC GS1 codes

I'm calculating the GS1 SSCC codes that are 18-digit barcodes. The 18th digit is a check digit which is used to validate the rest of that code and check that it is correct. the check digit is a number between 0-9 and is calculated using a specific algorithm on the preceding 17 digits which are the input for this code. You can find more information on: http://www.morovia.com/kb/Serial-Shipping-Container-Code-SSCC18-10601.html

static int getCheckDigit(string SSCC)
{
int[] SSCCArray = SSCC.ToCharArray().Select(c => (int)char.GetNumericValue(c)).ToArray();

int position = 0;
int oddPisitonsSUM = 0;
int evenPositionsSUM = 0;
int oddSumMultiply3;
int totalSUM;
int mod10Remainder;
int CheckDigit;

foreach (int i in SSCCArray)
{
position += 1;

if (position % 2 == 0)
{
evenPositionsSUM += i;
}
else
{
oddPisitonsSUM += i;
}
}
oddSumMultiply3 = oddPisitonsSUM * 3;
totalSUM = oddSumMultiply3 + evenPositionsSUM;
mod10Remainder = totalSUM % 10;

if (mod10Remainder == 0)
{
return mod10Remainder;
}
else
{
CheckDigit = (10 - mod10Remainder);
return CheckDigit;
}
}


There is no doubt a more elegant solution to this, but this is my first crack at it. All constructive criticisms are welcome.

• Could you write something more like what it is supposed to do? Maybe an example how to use it? What results to expect etc? Nov 4, 2016 at 12:39
• Hi @t3chb0t. I apologise! This is my first post, you're right I should explain more clearly. GS1 SSCC codes are 18-digit barcodes. The 18th digit is a check digit which is used to validate the rest of that code and check that it is correct. the check digit is a number between 0-9 and is calculated using a specific algorithm on the preceding 17 digits which are the input for this code. Check out this site morovia.com/kb/Serial-Shipping-Container-Code-SSCC18-10601.html Nov 7, 2016 at 10:00

First, you iterate through the input string twice: the first time when converting string to int[] SSCCArray and the second time when iterating through array.

Next, you don't need to know the position itself in the array (or string), you just need to know if the position is odd or even. This can be reached via bool variable.

Next, what is the input string has some invalid chars? It makes sense to handle this case.

My proposal:

private static int getCheckDigit(string sscc)
{
int oddPisitonsSum = 0;
int evenPositionsSum = 0;

bool evenPosition = false;

foreach (char c in sscc)
{
int i = (int)char.GetNumericValue(c);
if (i < 0)
{
// Invalid char detected
continue; // or throw an exception
}

if (evenPosition)
{
evenPositionsSum += i;
}
else
{
oddPisitonsSum += i;
}
evenPosition = !evenPosition; // Toggle the flag
}
int totalSum = oddPisitonsSum * 3 + evenPositionsSum;
int mod10Remainder = totalSum % 10;

return mod10Remainder == 0 ? mod10Remainder : 10 - mod10Remainder;
}

• Inconsistent var & int alarm ;-) Nov 4, 2016 at 13:47
• @t3chb0t Can't see any inconsistency. Please point me. Nov 4, 2016 at 14:44
• At the top of the function int oddPisitonsSum = 0; and at the end of the function var mod10Remainder = totalSum % 10; Nov 4, 2016 at 14:53
• @t3chb0t This code was copied from the OP. Fixed anyway. Nov 4, 2016 at 15:10
• @Dmitry Thanks for the suggestion, I would say that there should be no need to check for invalid chars, the SSCC should be valid by contract and this would be a pre-condition. I also just copied this code and replaced it with mine and the program doesn't seem to like it, I can't tell you what the problem is but this does seem like a tidier version, thanks. Nov 7, 2016 at 9:56

I think you can reduce it down

int sum = 0;
for(int i = 0; i < SSCC.Length; i++)
{
int charValue = (int)char.GetNumericValue(SSCC[i]);
if (charValue < 0)
{
continue;
}
if (i % 2 == 0)
{
sum += charValue;
}
else
{
sum += charValue * 3;
}
}
return sum % 10 == 0 ? 0 : 10 - sum % 10;

• how? why? Please explain so OP and future readers can better understand what you did. Thanks! Jul 16, 2018 at 8:53