Correct ICCID algo

303 views Asked by At

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

1

There are 1 answers

2
canton7 On

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.