如何检查的加拿大社会保险号在C#中的有效性?加拿大、社会保险、有效性

2023-09-11 04:37:55 作者:男神霸哥

我已经给分配到写检查的加拿大社会保险号码(SIN)的有效性的算法在C#。下面是步骤来验证一种罪过。

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.

给出一个例子编号: 123 456 782

删除校验位(最后一位):12345678 2 解压缩甚至数字(2,4,6,8th digith):1 2 3 4 5​​ 6 7 8 双击其中: Remove the check digit (the last digit): 123456782 Extract the even digits (2,4,6,8th digith): 12345678 Double them:

    2  4  6  8
    |  |  |  |
    v  v  v  v
    4  8  12 16 

添加数字在一起:

Add the digits together:

4+8+1+2+1+6 = 22

添加奇数放在数字:

Add the Odd placed digits:

    1+3+5+7 = 16

                           

      Total : 38

有效算法

如果合计为10的倍数,校验位应该是零。 另外,从10(40在这种情况下),下一个最高倍数减去总 在此SIN校验位必须等于多少的差异,从总量较早(在这种情况下, 40-38 = 2 ;校验位是2,所以数是有效的) If the total is a multiple of 10, the check digit should be zero. Otherwise, Subtract the Total from the next highest multiple of 10 (40 in this case) 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)

我迷路了如何真正实现这在C#中,我该怎么办呢?

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

推荐答案

这是一个很好的解决的问题。这应该是比转换为字符串并解析回整数更有效率。该解决方案将工作在.NET 3.5和更高版本。

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;
    }

与此解决方案的一个问题是它假定psented的整数,号码,重新$ P $,是9位数字(不能以0开始)。如果数字可以用0开始,那么它必须是psented作为字符串(或转换为字符串,并用0填充)重新$ P $。逻辑测试仍将大多保存完好,但将需要承担的整数部分被换出与字符串,那么你就必须做解析。

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.