1
\$\begingroup\$

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.

\$\endgroup\$
2
  • 5
    \$\begingroup\$ Could you write something more like what it is supposed to do? Maybe an example how to use it? What results to expect etc? \$\endgroup\$
    – t3chb0t
    Nov 4, 2016 at 12:39
  • \$\begingroup\$ 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 \$\endgroup\$ Nov 7, 2016 at 10:00

2 Answers 2

2
\$\begingroup\$

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;
}
\$\endgroup\$
5
  • \$\begingroup\$ Inconsistent var & int alarm ;-) \$\endgroup\$
    – t3chb0t
    Nov 4, 2016 at 13:47
  • \$\begingroup\$ @t3chb0t Can't see any inconsistency. Please point me. \$\endgroup\$
    – Dmitry
    Nov 4, 2016 at 14:44
  • \$\begingroup\$ At the top of the function int oddPisitonsSum = 0; and at the end of the function var mod10Remainder = totalSum % 10; \$\endgroup\$
    – t3chb0t
    Nov 4, 2016 at 14:53
  • \$\begingroup\$ @t3chb0t This code was copied from the OP. Fixed anyway. \$\endgroup\$
    – Dmitry
    Nov 4, 2016 at 15:10
  • \$\begingroup\$ @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. \$\endgroup\$ Nov 7, 2016 at 9:56
0
\$\begingroup\$

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;
\$\endgroup\$
1
  • 1
    \$\begingroup\$ how? why? Please explain so OP and future readers can better understand what you did. Thanks! \$\endgroup\$
    – Vogel612
    Jul 16, 2018 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.