Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check the validity of the Canadian Social Insurance Number in C#?

Tags:

c#

algorithm

I've been given the assignment to write an algorithm in C# that checks the validity of a Canadian Social Insurance Number (SIN). Here are the steps to validate a SIN.

Given an example Number: 123 456 782

  1. Remove the check digit (the last digit): 123456782
  2. Extract the even digits (2,4,6,8th digith): 12345678
  3. Double them:
        2  4  6  8
        |  |  |  |
        v  v  v  v
        4  8  12 16 
    
  4. Add the digits together:
    4+8+1+2+1+6 = 22
  5. Add the Odd placed digits:
        1+3+5+7 = 16
          Total : 38

Validity Algorithm

  1. If the total is a multiple of 10, the check digit should be zero.
  2. Otherwise, Subtract the Total from the next highest multiple of 10 (40 in this case)
  3. The check digit for this SIN must be equal to the difference of the number and the totals from earlier (in this case, 40-38 = 2; check digit is 2, so the number is valid)

I'm lost on how to actually implement this in C#, how do I do this?

like image 926
user518307 Avatar asked Nov 24 '10 04:11

user518307


People also ask

How do I check if my Canadian SIN is valid?

You can confirm the SIN of a current or former employee by contacting Service Canada at 1-866-274-6627. If calling from outside Canada, dial 506-548-7961 (long distance charges apply).

How do I know when my SIN number expires?

Your temporary SIN expires on the date provided in your immigration documents. You must ensure that both expiry dates match. If you have applied for renewal of a work or study permit, and your permit expires before a decision is made, you have the right* to continue working or studying under the same conditions.

Does a Canadian SIN number expire?

Information for temporary residentsOnce your SIN record is updated, you will receive a SIN with a new expiry date. Your previous SIN (whether in a paper format or a plastic card) is no longer valid. Destroy it in a secure manner.


1 Answers

This is a nice problem to solve. This should be more efficient than converting to string and parsing back to integer. This solution will work on .NET 3.5 and later.

    public static IEnumerable<int> ToDigitEnumerable(this int number)
    {
        IList<int> digits = new List<int>();

        while(number > 0)
        {
            digits.Add(number%10);
            number = number/10;
        }

        //digits are currently backwards, reverse the order
        return digits.Reverse();
    }

    public static bool IsCanadianSocialInsuranceNumber(int number)
    {
        var digits = number.ToDigitEnumerable();

        if (digits.Count() != 9) return false;

        //The left side of the addition is adding all even indexes (except the last digit).
        //We are adding even indexes since .NET uses base 0 for indexes

        //The right side of the addition, multiplies the odd index's value by 2, then breaks each result into
        //individual digits, then adds them together
        var total = digits.Where((value, index) => index%2 == 0 && index != 8).Sum()
                    + digits.Where((value, index) => index%2 != 0).Select(v => v*2)
                          .SelectMany(v => v.ToDigitEnumerable()).Sum();

        //The final modulous 10 operator is to handle the scenarios where the total
        //is divisble by 10, in those cases, the check sum should be 0, not 10
        var checkDigit = (10 - (total%10)) % 10;

        return digits.Last() == checkDigit;
    }

One problem with this solution is that it assumes that number, represented as an integer, is 9 digits (can't start with a 0). If the number can start with a 0, then it has to be represented as a string (or converted to a string and padding with zeros). The logic to test will remain mostly intact, but the parts that assume integers will need to be swapped out with strings, and then you'll have to do parsing.

like image 89
Brian Ball Avatar answered Sep 25 '22 19:09

Brian Ball