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

use*_*307 7 c# algorithm

我被赋予了在C#编写算法的任务,该算法检查加拿大社会保险号(SIN)的有效性.以下是验证SIN的步骤.

给出一个示例数字: 123 456 782

  1. 删除校验位(最后一位):12345678 2
  2. 提取偶数(2,4,6,8th digith):1 2 3 4 5 6 7 8
  3. 加倍他们:
        2  4  6  8
        |  |  |  |
        v  v  v  v
        4  8  12 16 
    
  4. 将数字加在一起:
    4+8+1+2+1+6 = 22
  5. 添加奇数位数:
        1+3+5+7 = 16
          Total : 38

有效性算法

  1. 如果总数是10的倍数,则校验位应为零.
  2. 否则,从下一个最高倍数10减去总数(在这种情况下为40)
  3. 此SIN的校验位必须等于之前的数字和总数之差(在这种情况下,40-38 = 2校验位为2,因此数字有效)

我迷失了如何在C#中实现这一点,我该怎么做?

Geo*_*ker 1

该程序的关键在于您需要有某种方法来迭代 SIN 中的每个整数。

由于最简单的方法是将整数转换为字符串以进行操作操作,然后再转换回整数以进行加法/乘法操作,因此我使用了以下方法:

该程序:

public class Program
{
    static void Main(string[] args)
    {
        int sn = 123456782;
        int[] Digits;
        int AddedResult = 0;
        string s = sn.ToString();
        string sa = s.Substring(s.Length - 1, 1);

        int checkDigit = Convert.ToInt32(sn.ToString().Substring(s.Length - 1, 1));
        //get the last digit.

        if (IsValidLength(sn))
        {

            sn = RemoveLastDigit(sn);
            Digits = ExtractEvenDigits(sn);
            Digits = DoubleDigits(Digits);
            AddedResult = AddedEvenDigits(Digits);
            AddedResult += AddOddDigits(sn);
            if (IsValidSN(AddedResult, checkDigit))
            {
                Console.WriteLine("The number is valid");
            }
            else
            {
                Console.WriteLine("The Number is not valid");
            }
        }
        else
        {
            Console.WriteLine("NotValidLength");
        }
        Console.Read();
        
    }

    public static bool IsValidSN(int AddedResult, int checkDigit)
    {
        return ((AddedResult % 10 == 0 && checkDigit == 0) || IsValidDifference(AddedResult, checkDigit));
        
    }

    public static bool IsValidDifference(int AddedResult, int checkDigit)
    {
        int nextHighestTens = AddedResult;
        while (nextHighestTens % 10 != 0)
        {
            nextHighestTens++;
        }
        return ((nextHighestTens - AddedResult) == checkDigit);
    }

    public static int AddOddDigits(int sn)
    {
        string s = sn.ToString();
        int i = 1;
        int addedResult = 0;
        foreach (char c in s)
        {
            if (i % 2 != 0)
            {
                addedResult += Convert.ToInt32(c.ToString());
            }
            i++;
        }

        return addedResult;
    }

    public static int AddedEvenDigits(int[] Digits)
    {
        int addedEvenDigits = 0;
        string s = "";
        for (int i = 0; i < Digits.Length; i++) //extract each digit. For example 12 is extracted as 1 and 2
        {
            s += Digits[i].ToString();
        }
        for (int i = 0; i < s.Length; i++) //now add all extracted digits
        {
            addedEvenDigits += Convert.ToInt32(s[i].ToString());
        }
        return addedEvenDigits;
    }

    public static int[] DoubleDigits(int[] Digits)
    {
        int[] doubledDigits = new int[Digits.Count()];
        for (int i = 0; i < Digits.Length; i++)
        {
            doubledDigits[i] = Digits[i] * 2;
        }
        return doubledDigits;
    }

    public static int[] ExtractEvenDigits(int sn)
    {
        int[] EvenDigits = new int[4];
        string s = sn.ToString(); //12345678

        int j = 0;
        for (int i = 1; i < s.Length; i += 2)
        {
            EvenDigits[j] = Convert.ToInt32(s[i].ToString());
            j++;
        }
        
        return EvenDigits;
    }

    public static int RemoveLastDigit(int sn)
    {
        string s = sn.ToString();
        return Convert.ToInt32(s.Substring(0, s.Count() - 1));
    }
    public static bool IsValidLength(int sn)
    {
        return (sn > 9999999 && sn < 1000000000);
    }
}
Run Code Online (Sandbox Code Playgroud)

我花了大约 20 分钟写了这篇文章,所以它并不值得交出。我计划将其作为练习进行改进,并为其编写了一些单元测试(我计划做得更好)。

[TestFixture]
public class SINTests
{
    private int SinNumber = 123456782;

    [Test]
    public void TestValidNumber()
    {
        Assert.IsTrue(Program.IsValidLength(SinNumber));
    }
    
    [Test]
    public void TestRemoveLastDigit()
    {
        Assert.AreEqual(12345678, Program.RemoveLastDigit(SinNumber));
    }

    [Test]
    public void TestExtractEvenDigit()
    {
        int sn = 12345678;
        int[] array = new int[] { 2,4,6,8 };
        Assert.AreEqual(array, Program.ExtractEvenDigits(sn));
    }

    [Test]
    public void TestAddOddDigits()
    {
        int sn = 12345678;
        int result = 1 + 3 + 5 + 7;
        Assert.AreEqual(result, Program.AddOddDigits(sn));
    }
    [Test]
    public void TestDoubleEvenDigits()
    {
        int sn = 12345678;
        int[] original = new int[] { 2, 4, 6, 8 };
        int[] array = new int[] { 4, 8, 12, 16 };
        Assert.AreEqual(array, Program.DoubleDigits(original));
    }
    [Test]
    public void TestOddDigits()
    {
        int sn = 12345678;
        Assert.AreEqual(16, Program.AddOddDigits(sn));
    }

}
Run Code Online (Sandbox Code Playgroud)

由于字符串可以解释为字符数组1,因此对字符串进行操作还需要注意将字符转换为整数与将字符串转换为整数不同的事实。例如:

Char c = '2';
int cInt = Convert.ToInt32(c); // returns 50
string s = c.ToString();
int sInt = Convert.ToInt32(s) //returns 2;
Run Code Online (Sandbox Code Playgroud)

1从技术上讲,字符串不是 C# 中的字符数组(尽管在 C 和 C++ 中是),但由于您可以通过索引器访问字符串的组成部分,因此可以将其视为字符数组。