One would have thought that validating Australian Company Numbers [ACN], Australian Business Numbers [ABN], and Australian Registered Body Numbers [ARBN - same thing as ACNs with a slightly different use]
would be a thoroughly solved problem - but apparently not! The actual validation is not exactly complex from a mathematical perspective, but why waste time
working out how to do it and coding it? I’ve recently needed to work my way through to [fairly] robust solutions for Salesforce Apex and T-SQL,
and thought I’d try to help save any intrepid Googlers some time and consternation at not being able to find a quick solution they can just drop in.
If you’re wondering what Apex is and how you got here because you were looking for a Java solution - Apex is very Java-like, so you should have little trouble adapting this.
If you feel liking sinking the time in, you might be able to make these more efficient - I’ve tried to focus on clarity instead however! If you have any specific questions or this does something embarrassing like fail to compile, please leave a comment or ping me on Twitter.
This is a class exposing 3 static methods - Validate[ABN|ACN|ARBN] - each taking the number to validate in as a String. The methods first make a cursory clean of your input, only stripping whitespace and ensuring the string you provided is numeric, then trying to fail as early as possible, so they do feature multiple return points. You may wish to extend this by stripping out other characters such as dashes - this is all down to the context you’re using it in really - my focus was verifying data that is supposed to be pretty clean already.
The focus here was a little different to the Apex - these were being extracted from a database where dashes were permitted, and whitespace appeared everywhere seemingly at random. So three UDFs are dropped if necessary then defined - VALIDATE[ABN|ACN|ARBN] - each of which takes in a VARCHAR(256). They strip the dashes and whitespace from your VARCHAR input, and it’s pretty plain sailing from there - you’ll get a BIT indicating success or failure at the end. Possible extensions depending on your use case could include breaking the big IF into smaller stages and throwing CAST(‘Error reason’ as int) depending on the failure reason - which may help you get to grips with the particular data oddities of an unfamiliar database.