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\$
  • 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 '16 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\$ – Ryan Wolton Nov 7 '16 at 10:00
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\$
  • \$\begingroup\$ Inconsistent var & int alarm ;-) \$\endgroup\$ – t3chb0t Nov 4 '16 at 13:47
  • \$\begingroup\$ @t3chb0t Can't see any inconsistency. Please point me. \$\endgroup\$ – Dmitry Nov 4 '16 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 '16 at 14:53
  • \$\begingroup\$ @t3chb0t This code was copied from the OP. Fixed anyway. \$\endgroup\$ – Dmitry Nov 4 '16 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\$ – Ryan Wolton Nov 7 '16 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
    \$\begingroup\$ how? why? Please explain so OP and future readers can better understand what you did. Thanks! \$\endgroup\$ – Vogel612 Jul 16 '18 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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