Skip to content

Instantly share code, notes, and snippets.

@asika32764
Last active February 18, 2025 09:55
Show Gist options
  • Save asika32764/1106d9061749044820536dd51c0399eb to your computer and use it in GitHub Desktop.
Save asika32764/1106d9061749044820536dd51c0399eb to your computer and use it in GitHub Desktop.
(PHP | TypeScript) 台灣公司統編驗證函式
<?php
/**
* 依照 2023 年最新規則進行驗證
*
* @see https://www.fia.gov.tw/singlehtml/3?cntId=c4d9cff38c8642ef8872774ee9987283
*
* @param string $vat
*
* @return bool
*/
function checkVAT(string $vat): bool
{
// 共八位,全部為數字型態
if (!preg_match('/^\d{8}$/', $vat)) {
return false;
}
// 邏輯乘數
$constants = [1, 2, 1, 2, 1, 2, 4, 1];
// 統編字元
$chars = str_split($vat);
$result = [];
// 兩數對應相乘
foreach (array_map(null, $chars, $constants) as [$a, $b]) {
$result[] = $a * $b;
}
// 乘積各位相加
$sum = array_reduce(
$result,
fn (int $sum, int $n) => $sum + array_sum(str_split($n)),
0
);
// 第 7 位為 7,取 0 or 1 相加後其中之一可被 5 整除即正確
// 這裡直接減 10 or 9 亦同
if ($vat[6] === '7') {
return ($sum - 10) % 5 === 0 || ($sum - 9) % 5 === 0;
}
// 第 7 位非 7,可被 5 整除即正確
return $sum % 5 === 0;
}
export function checkVAT(vat: string): boolean {
// 共八位,全部為數字型態
if (!/^\d{8}$/.test(vat)) {
return false;
}
// 邏輯乘數
const constants = [1, 2, 1, 2, 1, 2, 4, 1];
// 轉成數字陣列
const chars = vat.split('').map(Number);
// 兩數對應相乘並計算各位數和
const sum = chars.reduce((acc, char, index) => {
const product = char * constants[index];
return acc + product.toString().split('').reduce((sum, num) => sum + parseInt(num, 10), 0);
}, 0);
// 第 7 位為 7,取 0 or 1 相加後其中之一可被 5 整除即正確
if (vat[6] === '7') {
return (sum - 10) % 5 === 0 || (sum - 9) % 5 === 0;
}
// 第 7 位非 7,可被 5 整除即正確
return sum % 5 === 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment