-1

I need to validate ICCID, I found only one algo:

int numberStringLength = 18;

int cs = 0;
int dodd;
for (int i = 0; i < numberStringLength; i += 2)
{
    dodd = Convert.ToInt32(iccid.Substring(i + 1, 1)) << 1;
    cs += Convert.ToInt32(iccid.Substring(i, 1)) + (int)(dodd / 10) + (dodd % 10);
}
cs = (10-(cs % 10)) % 10;

if (cs == Convert.ToInt32(iccid.Substring(numberStringLength, 1)))
{
    return true;
}
else
{
    return false;
}

but it returns false for 100% right ICCID (89148000005339755555). Where can I get real ICCID algo? Thanks

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159
  • I'm not understanding your issue. First, have you debugged this code, if not, I would highly recommend. Second, you want to validate a ICCID if I'm correct, right? Third, your output isn't correct based on the algorithm you found correct? You're also asking for a *real ICCID algo* what does this mean? – Trevor May 07 '21 at 12:59
  • Did you debug the code and check which calculation is not giving result as per the expectations? – Chetan May 07 '21 at 13:00
  • @Codexer this algo returns 'false' for valid ICCID – Oleg Sh May 07 '21 at 13:04
  • 1
    Without checking the code, I'd suggest to refer to the ICCID itself and see how it's built. It consists of 18 - 22 characters (17 to 21 + 1 check digit). In your case, you assume that the length is static (18 digits). – jAC May 07 '21 at 13:10
  • You can find an answer [here](https://stackoverflow.com/questions/21249670/implementing-luhn-algorithm-using-c-sharp) already about this. – Trevor May 07 '21 at 13:35

1 Answers1

2

According to Wikipedia, ICCIDs use the Luhn algorithm.

Your code that you found is a bit broken, as it assumes that the value has an odd number of digits (an even number of normal digits, plus 1 check digit). It starts parsing the value from the left-most digit, and assumes that this left-most digit ("8" in your example) is not doubled and the next one ("9") is doubled. But this is not correct if the value has an even number of digits. The "8" should be the one that's doubled in your case.

Thankfully, it's very easy to implement the Luhn algorithm ourselves, properly, using that Wikipedia page as reference:

string input = "89148000005339755555";

int sum = 0;
// We'll use index i = 0 means the right-most digit, i = 1 is second-right, etc
for (int i = 0; i < input.Length; i++)
{
    // Get the digit at the i'th position from the right
    int digit = int.Parse(input[input.Length - i - 1].ToString());

    // If it's in an odd position (starting from the right), then double it.
    if (i % 2 == 1)
    {
        digit *= 2;

        // If it's now >= 10, subtract 9
        if (digit >= 10)
        {
            digit -= 9;
        }
    }

    sum += digit;
}

// It's a pass if the result is a multiple of 10
bool pass = sum % 10 == 0;
Console.WriteLine(pass ? "Pass" : "Fail");

See it on dotnetfiddle.net.

canton7
  • 37,633
  • 3
  • 64
  • 77
  • it returns "pass" for `00000000000000000000`. Probably, it's correct value for luhn algo, but it's not appropriate for business processes :) – Oleg Sh May 07 '21 at 13:52
  • 1
    That is correct, following the Luhn algorithm, if you read it. It's explicitly called out in the pros/cons section of that Wiki page – canton7 May 07 '21 at 13:52