我需要一些现代 C# 代码来检查澳大利亚商业号码 (ABN) 是否有效。

要求松散的是

  • ABN 已被用户输入
  • 允许在任何时候使用空格使数字可读
  • 如果包含除数字和空格之外的任何其他字符 - 即使包含合法的数字序列,验证也会失败
  • 此检查是调用 ABN search webservice 的前兆,它将保存明显错误输入的调用

  • abr.business.gov.au 中指定了验证数字的确切规则,为了简洁和清晰起见,这里省略了这些规则。规则不会随着时间而改变。

    最佳答案

    这是基于 Nick Harris's 示例,但经过清理以使用现代 C# 习惯用法

    /// <summary>
    /// http://stackoverflow.com/questions/38781377
    /// 1. Subtract 1 from the first (left) digit to give a new eleven digit number
    /// 2. Multiply each of the digits in this new number by its weighting factor
    /// 3. Sum the resulting 11 products
    /// 4. Divide the total by 89, noting the remainder
    /// 5. If the remainder is zero the number is valid
    /// </summary>
    public bool IsValidAbn(string abn)
    {
        abn = abn?.Replace(" ", ""); // strip spaces
    
        int[] weight = { 10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
        int weightedSum = 0;
    
        //0. ABN must be 11 digits long
        if (string.IsNullOrEmpty(abn) || !Regex.IsMatch(abn, @"^\d{11}$"))
        {
            return false;
        }
    
        //Rules: 1,2,3
        for (int i = 0; i < weight.Length; i++)
        {
            weightedSum += (int.Parse(abn[i].ToString()) - (i == 0 ? 1 : 0)) * weight[i];
        }
    
        //Rules: 4,5
        return weightedSum % 89 == 0;
    }
    

    额外的 xUnit 测试让您的技术负责人感到高兴...
    [Theory]
    [InlineData("33 102 417 032", true)]
    [InlineData("29002589460", true)]
    [InlineData("33 102 417 032asdfsf", false)]
    [InlineData("444", false)]
    [InlineData(null, false)]
    public void IsValidAbn(string abn, bool expectedValidity)
    {
        var sut = GetSystemUnderTest();
        Assert.True(sut.IsValidAbn(abn) == expectedValidity);
    }
    

    10-07 14:12