Check valid tax id number in Kotlin

Chris Chen
2 min readAug 23, 2019

--

Photo from ddstax

The tax id number is different for each country. Here I want to show you how to check a tax id is valid or not. (Example is Taiwan rule.)

Here is the rule of the TW tax id:

Let's say the tax id is A B C D E F G H
A — G representer each number from 0~9, H is checksum.
A — G will multiply by specific value, if the outcome more than 10. You need add the units digit and ten digit.
A x 1
B x 2
C x 1
D x 2
E x 1
F x 2
G x 4
H x 1
Finally add all of the outcome. If the result divisible by 10. Then the number belongs to valid tax id number. Or G is 7, the (result+1) divisible by 10 is also a valid tax id number.
(統編驗證 中文補充)
假設統一編號為 A B C D E F G H
A — G 為編號, H 為檢查碼
A — G 個別乘上特定倍數, 若乘出來的值為二位數則將十位數和個位數相加
A x 1
B x 2
C x 1
D x 2
E x 1
F x 2
G x 4
H x 1
最後將所有數值加總, 被 10 整除就為正確
若上述演算不正確並且 G 為 7 得話, 再加上 1 被 10 整除也為正確
  1. We need to check general case like the input might be null, empty or contains non-numbers.
  2. Because the input is an array. We need to convert to an int array.
  3. Multiply with each specific factor.
  4. Logic check.
  5. Write test case to verify the function is properly.

So finally will look like:

//This solution will take O(N) time complexity and less extra space.fun isValidTaxId(taxId: String?): Boolean {
if (taxId.isNullOrEmpty() || taxId.length != 8
|| !Pattern.compile("\\d+").matcher(taxId).matches()) return false
val idArray = taxId.map { it - '0' }

val factorArray = intArrayOf(1, 2, 1, 2, 1, 2, 4, 1)
var result = 0
for (i in 0 until factorArray.size) {
val multiply = factorArray[i] * idArray[i]
result += if (multiply > 9) {
(multiply / 10) + (multiply % 10)
} else {
multiply
}
}

return result % 10 == 0 || ((idArray[6] == 7)
&& ((result + 1) % 10 == 0))
}

Remember we need to add test case to ensure our logic is correct.

class UiUtilTest {

@Test
fun isValidTaxId_Test() {
// is not tax id number
assertFalse(UiUtil.isValidTaxId(null))
assertFalse(UiUtil.isValidTaxId(""))
assertFalse(UiUtil.isValidTaxId("1234"))
assertFalse(UiUtil.isValidTaxId("1234abcd"))
assertFalse(UiUtil.isValidTaxId("123456789"))
assertFalse(UiUtil.isValidTaxId("12345678"))
assertFalse(UiUtil.isValidTaxId("87654321"))

// is tax id number
assertTrue(UiUtil.isValidTaxId("00238778"))
assertTrue(UiUtil.isValidTaxId("70664079"))
assertTrue(UiUtil.isValidTaxId("04595257"))
assertTrue(UiUtil.isValidTaxId("10458575"))
assertTrue(UiUtil.isValidTaxId("54049493"))
assertTrue(UiUtil.isValidTaxId("55667788"))
}
}

The test case contains null, empty case, shorter length, longer length…and so on. Had better cover all edge case then we can prevent any unexpected issue.

Can try to apply TDD to implement this feature to see what happens. (maybe less code, less implementation time, more testable function…etc)

Hope you like it. :)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Chris Chen
Chris Chen

No responses yet

Write a response