Validating ABNs and ACNs in PHP

Here is a PHP validation class to validate Australian Business Numbers (ABN) and Australian Company Numbers (ACN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
 
/**
 *    Validator Class
 *    @author Paul Ferrett, 2009 (http://www.paulferrett.com)
 */
class Validator {
 
    /**
     *    Return true if $number is a valid ABN
     *    @param    string $number
     *    @return    bool True if $number is a valid ABN
     */
    public static function isValidAbnOrAcn($number) {
        $number = preg_replace('/[^0-9]/', '', $number);
        if(strlen($number) == 9) {
            return self::isValidAcn($number);
        }
        if(strlen($number) == 11) {
            return self::isValidAbn($number);
        }
        return false;
    }
 
 
    /**
     *    Validate an Australian Business Number (ABN)
     *    @param        string $abn        ABN
     *    @link        http://www.ato.gov.au/businesses/content.asp?doc=/content/13187.htm
     *    @return        bool            True if $abn is a valid ABN, false otherwise
     */
    public static function isValidAbn($abn) {
        $weights = array(10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19);
 
        // Strip non-numbers from the acn
        $abn = preg_replace('/[^0-9]/', '', $abn);
 
        // Check abn is 11 chars long
        if(strlen($abn) != 11) {
            return false;
        }
 
        // Subtract one from first digit
        $abn[0] = ((int)$abn[0] - 1);
 
        // Sum the products
        $sum = 0;
        foreach(str_split($abn) as $key => $digit) {
            $sum += ($digit * $weights[$key]);
        }
 
        if(($sum % 89) != 0) {
            return false;
        }
 
        return true;
    }
 
 
    /**
     *    Validate an Australian Company Number (ACN)
     *    @param        string $acn        ACN
     *    @link        http://www.asic.gov.au/asic/asic.nsf/byheadline/Australian+Company+Number+(ACN)+Check+Digit
     *    @return        bool            True if $acn is a valid ACN, false otherwise
     */
    public static function isValidAcn($acn){
        $weights = array(8, 7, 6, 5, 4, 3, 2, 1, 0);
 
        // Strip non-numbers from the acn
        $acn = preg_replace('/[^0-9]/', '', $acn);
 
        // Check acn is 9 chars long
        if(strlen($acn) != 9) {
            return false;
        }
 
        // Sum the products
        $sum = 0;
        foreach(str_split($acn) as $key => $digit) {
            $sum += $digit * $weights[$key];
        }
 
        // Get the remainder
        $remainder = $sum % 10;
 
        // Get remainder compliment
        $complement = (string)(10 - $remainder);
 
        // If complement is 10, set to 0
        if($complement === "10") {
            $complement = "0";
        }
 
        return ($acn[8] === $complement);
    }
}
?>

5 thoughts on “Validating ABNs and ACNs in PHP

  1. Mike

    Hi, how do you call this code?

    I assume something like:

    if (! new Validator($abn))
    $error = true;

    I guess your code also assumes the number is the correct length.

  2. paul Post author

    Hi Mike,

    A static class method is called using the :: operator. (see http://www.php.net/manual/en/language.oop5.static.php)

    <?php
    if(!Validator::isValidAbnOrAcn($abn)) {
      $error = true;
    }
    ?>

    All three functions remove all non numeric characters before testing for validity so it is only the numbers in the string that count. I assume that’s what you’re asking? If there are an incorrect number of numbers in the ABN then it’s not valid and the function will return false.

    Paul

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>