最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there any algorithm to validate Australian TFN number? - Stack Overflow

programmeradmin5浏览0评论

We are looking to validate Australian TFN numbers entered by our clients. Is there any official algorithm mentioned somewhere?

The Wikipedia page mentions about a simple modulo-11 algorithm but it seems it is just an example.

We are looking to validate Australian TFN numbers entered by our clients. Is there any official algorithm mentioned somewhere?

The Wikipedia page mentions about a simple modulo-11 algorithm but it seems it is just an example.

Share Improve this question edited Apr 21, 2017 at 5:00 Jeremy Thompson 65.9k37 gold badges223 silver badges340 bronze badges asked Oct 26, 2016 at 2:01 ElevatedLyfElevatedLyf 1161 gold badge2 silver badges8 bronze badges 4
  • 1 The example on that page does give the weightings for each digit. The same algorithm is provided here (and other places). But as both pages say, officially the ATO doesn't provide details of the algorithm even though it's well known what it is. – nnnnnn Commented Oct 26, 2016 at 2:05
  • Yes, but that's what. Until there is something official we can't rely on those weighting factors otherwise we may end up throwing errors for valid numbers as well. :) – ElevatedLyf Commented Oct 26, 2016 at 5:28
  • There is an ABN validation algorithm here but nothing for the TFN - abr.business.gov.au/HelpAbnFormat.aspx – ElevatedLyf Commented Oct 26, 2016 at 5:34
  • The ABN code is here: stackoverflow./questions/14174738/… – Jeremy Thompson Commented Mar 8, 2017 at 4:31
Add a ment  | 

4 Answers 4

Reset to default 5

In Javascript 9 Digit:

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.');
}

Ref: https://github./steveswinsburg/tfn-validator/blob/master/tfn-validator.html

In C# 9 Digit:

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

Ref: https://softwaredevelopers.ato.gov.au/obtainTFNalgorithm

In C# 8 Digit:

public static bool ValidateTFN(string tfn)
{
    //validate only digits
    if (!IsNumeric(tfn)) return false;

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

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

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

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

Ref: https://jeremythompson/Rocks/TFN_algorithm_8_digit.pdf

In VB.Net 9 Digit:

Public Shared Function ValidateTFN(ByVal tfn As String) As Boolean
        If Not IsNumeric(tfn) Then Return False
        If tfn.Length <> 9 Then Return False
        Dim digits As Integer() = Array.ConvertAll(tfn.ToArray(), Function(c) CInt(Char.GetNumericValue(c)))
        Dim 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)
        Dim remainder = sum Mod 11
        Return (remainder = 0)
    End Function

In PHP 9 Digit:

function ValidateTFN($tfn)
{
    $weights = array(1, 4, 3, 7, 5, 8, 6, 9, 10);
 
    // strip anything other than digits
    $tfn = preg_replace("/[^\d]/","",$tfn);
 
    // check length is 9 digits
    if (strlen($tfn)==9) {
        $sum = 0;
        foreach ($weights as $position=>$weight) {
            $digit = $tfn[$position];
            $sum += $weight * $digit;
        }
        return ($sum % 11)==0;
    } 
    return false;
}

Ref: https://clearwater..au/code/tfn

In Swift 5:

Make sure you use keyboard type Number Pad to prevent users from adding non-numeric characters.

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) {
            return true
        } else {
            return false
        }
    }
}

Thank you Jeremy Thompson for the original answer.

An implementation that supports Java 8 and possibly higher

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

I have checked the c# code shared in this post, Actually the generated TFN number using that code has failed with the TFN validation in the mentioned WebSite. So I came with an alternate solution with the help of this website https://clearwater..au/code/tfn to generate valid TFN.

Try this code:

static void Main(string[] args)
        {
            int count = 0;
            Random random = new Random();
            while (count < 50)
            {
                int randomNumber = random.Next(100000000, 999999999);
                // - Validate TFN - [START]
                float output;
                //validate only digits
                string strRandomNumber = randomNumber.ToString();
                if (!float.TryParse(strRandomNumber, out output))
                {
                    Console.WriteLine("Invalid Input");
                }
                else
                {
                    //validate length
                    if (strRandomNumber.Length != 9)
                    {
                        Console.WriteLine("Invalid Length");
                    }
                    else
                    {
                        int[] digits = Array.ConvertAll(strRandomNumber.ToArray(), c => (int)Char.GetNumericValue(c));

                        //do the calcs                   
                        var sum = (digits[0] * 10)
                                + (digits[1] * 7)
                                + (digits[2] * 8)
                                + (digits[3] * 4)
                                + (digits[4] * 6)
                                + (digits[5] * 3)
                                + (digits[6] * 5)
                                + (digits[7] * 2)
                                + (digits[8] * 1);
                        var remainder = sum % 11;
                        // - Validate TFN - [END]
                        if ((remainder == 0))
                        {
                            Console.WriteLine(randomNumber.ToString());
                            break;
                        }
                    }
                }
                count++;
            }
        }
发布评论

评论列表(0)

  1. 暂无评论