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
2 4 6 8 | | | | v v v v 4 8 12 16
4+8+1+2+1+6 = 22
1+3+5+7 = 16
Total : 38
Validity Algorithm
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?
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).
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With