有啥算法可以验证澳大利亚的 TFN 号码吗?

Posted

技术标签:

【中文标题】有啥算法可以验证澳大利亚的 TFN 号码吗?【英文标题】:Is there any algorithm to validate Australian TFN number?有什么算法可以验证澳大利亚的 TFN 号码吗? 【发布时间】:2017-03-08 05:52:06 【问题描述】:

我们希望验证客户输入的澳大利亚 TFN 号码。 有没有在某处提到的官方算法?

Wikipedia page 提到了一个简单的模 11 算法,但它似乎只是一个示例。

【问题讨论】:

该页面上的示例确实给出了每个数字的权重。 here(和其他地方)提供了相同的算法。但正如两页所述,尽管众所周知,ATO 并未提供算法的详细信息。 是的,但就是这样。除非有官方的东西,否则我们不能依赖这些加权因子,否则我们最终也可能会为有效数字抛出错误。 :) 这里有一个 ABN 验证算法,但 TFN 没有 - abr.business.gov.au/HelpAbnFormat.aspx ABN 代码在这里:***.com/questions/14174738/… 【参考方案1】:

在 Javascript 中:

var tfn = $('#tfn').val();

//remove spaces and update
tfn = tfn.replace(/\s+/g, '');
$('#tfn').val(tfn);

//remove hyphens and update
tfn = tfn.replace(/[-]/g, '');
$('#tfn').val(tfn);

//validate only digits
var isNumber = /^[0-9]+$/.test(tfn);
if(!isNumber) 
    return doError('Invalid TFN, only numbers are allowed.');


//validate length
var length = tfn.length;
if(length != 9) 
    return doError('Invalid TFN, must have 9 digits.');


var digits = tfn.split('');

//do the calcs
var sum = (digits[0]*1)
        + (digits[1]*4)
        + (digits[2]*3)
        + (digits[3]*7)
        + (digits[4]*5)
        + (digits[5]*8)
        + (digits[6]*6)
        + (digits[7]*9)
        + (digits[8]*10);

var remainder = sum % 11;

if(remainder == 0) 
    doSuccess('Valid TFN, hooray!');
 else 
    return doError('Invalid TFN, check the digits.');

参考:https://github.com/steveswinsburg/tfn-validator/blob/master/tfn-validator.html

在 C# 中:

static void Main(string[] args)

    int count = 0;
    StringBuilder sb = new StringBuilder();
    Random random = new Random();
    while (count < 500000)                 
        int randomNumber = random.Next(100000000, 999999999);
        if (ValidateTFN(randomNumber.ToString()))
        
            sb.AppendLine(randomNumber.ToString());
            count++;
        
    
    System.IO.File.WriteAllText("TFNs.txt", sb.ToString());



public static bool ValidateTFN(string tfn)

    //validate only digits
    if (!IsNumeric(tfn)) return false;

    //validate length
    if (tfn.Length != 9) return false;

    int[] digits = Array.ConvertAll(tfn.ToArray(), c => (int)Char.GetNumericValue(c));

    //do the calcs
    var sum = (digits[0] * 1)
            + (digits[1] * 4)
            + (digits[2] * 3)
            + (digits[3] * 7)
            + (digits[4] * 5)
            + (digits[5] * 8)
            + (digits[6] * 6)
            + (digits[7] * 9)
            + (digits[8] * 10);

    var remainder = sum % 11;
    return (remainder == 0);


public static bool IsNumeric(string s)

    float output;
    return float.TryParse(s, out output);

【讨论】:

谢谢 Jeremy.. 您的解决方案中的称重数字在***页面上是相同的,但它们是税务部门的官方数字,有什么线索吗? 是的。您可以直接联系澳大利亚税务局@nnnnnn:softwaredevelopers.ato.gov.au/obtainTFNalgorithm。我在金融部门工作,并在生产中使用此代码。它是正确的。 值得注意的是,现在的 TFN 是 9 位的,但过去有些是 8 位的。 8 位 TFN 的权重为 (10, 7, 8, 4, 6, 3, 5, 1)。 ATO 预计未来将有 10 位数的 TFN,它们将再次具有不同的权重【参考方案2】:

在 Swift 5 中:

确保您使用键盘类型的数字键盘以防止用户添加非数字字符。

func isTFNValid (tfn: String) -> Bool
    if (tfn.count != 9) 
        return false
     else 
        let characters = Array(tfn)
        let digits = characters.map  Int(String($0))!
        //do the calcs
        var sum = (digits[0]*1)
                + (digits[1]*4)
                + (digits[2]*3)
                + (digits[3]*7)
                + (digits[4]*5)
                + (digits[5]*8)
                + (digits[6]*6)
                + (digits[7]*9)
                + (digits[8]*10)

        var remainder = sum % 11;

        if(remainder == 0 && tfn.count == 9) 
            return true
         else 
            return false
        
    

感谢Jeremy Thompson 的原始回答。

【讨论】:

【参考方案3】:

支持 Java 8 甚至更高版本的实现

public class TFNUtils 
    public static String format(String tfn) 
        if (tfn == null) 
            return null;
        
        tfn = tfn.replaceAll("\\s+","");
        tfn = tfn.replaceAll("\\-", "");
        if (tfn.length() != 9) 
            return null;
        
        int sum = (Integer.parseInt(String.valueOf(tfn.charAt(0))))
                + (Integer.parseInt(String.valueOf(tfn.charAt(1)))*4)
                + (Integer.parseInt(String.valueOf(tfn.charAt(2)))*3)
                + (Integer.parseInt(String.valueOf(tfn.charAt(3)))*7)
                + (Integer.parseInt(String.valueOf(tfn.charAt(4)))*5)
                + (Integer.parseInt(String.valueOf(tfn.charAt(5)))*8)
                + (Integer.parseInt(String.valueOf(tfn.charAt(6)))*6)
                + (Integer.parseInt(String.valueOf(tfn.charAt(7)))*9)
                + (Integer.parseInt(String.valueOf(tfn.charAt(8)))*10);
        if ((sum % 11) != 0)
            return null;
        
        StringBuilder tfnCompute = new StringBuilder(11);
        tfnCompute.append(tfn.charAt(0));
        tfnCompute.append(tfn.charAt(1));
        tfnCompute.append(tfn.charAt(2));
        tfnCompute.append('-');
        tfnCompute.append(tfn.charAt(3));
        tfnCompute.append(tfn.charAt(4));
        tfnCompute.append(tfn.charAt(5));
        tfnCompute.append('-');
        tfnCompute.append(tfn.charAt(6));
        tfnCompute.append(tfn.charAt(7));
        tfnCompute.append(tfn.charAt(8));
        return tfnCompute.toString();
    

    public static boolean isValid(String tfn) 
        return format(tfn) != null;
    


public class TFNUtilsTest 
    @Test
    public void testFormat() throws Exception 
        assertEquals("123-456-782", TFNUtilsTest.format("123-456-782"));
        assertEquals("123-456-782", TFNUtilsTest.format("123456782"));
        assertEquals("123-456-782", TFNUtilsTest.format("123 456 782"));

        // invaild returns null
        assertNull(TFNUtilsTest.format("123 456 7829"));
        assertNull(TFNUtilsTest.format("123 456 78"));
    

    @Test
    public void testIsValid() throws Exception 
        assertTrue(TFNUtilsTest.isValid("123-456-782"));
        assertTrue(TFNUtilsTest.isValid("123 456 782"));

        assertFalse(TFNUtilsTest.isValid(null));
        assertFalse(TFNUtilsTest.isValid(""));
        assertFalse(TFNUtilsTest.isValid("123-456-780"));    // invalid check-digit
        assertFalse(TFNUtilsTest.isValid("123-456.782"));    // invalid seperator
        assertFalse(TFNUtilsTest.isValid("123-456-7820"));   //  > 9 digits
    

【讨论】:

以上是关于有啥算法可以验证澳大利亚的 TFN 号码吗?的主要内容,如果未能解决你的问题,请参考以下文章

aud是啥货币

商品货币澳币的区别

这所高科技大学将领导澳大利亚最大的人工智能研究所!

UTXO团队赴澳出席Blockchain APAC会议

澳专家:印度有两个幻觉 边界争端易导致危机

时区缩写