本文提供三個核心 PHP 函數,依據國家標準 GB 11643-1999 實現身份證校驗碼計算、15 位升級 18 位、以及 18 位身份證有效性驗證。代碼結構清晰,可直接整合至專案中使用。
idcard_verify_number()輸入 17 位本體碼,返回對應的校驗碼(數字或 X):
function idcard_verify_number($idcard_base) {
if (strlen($idcard_base) != 17) return false;
// 加權因子
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校驗碼對應表
$verify_number_list = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$checksum = 0;
for ($i = 0; $i < 17; $i++) {
$checksum += (int)$idcard_base[$i] * $factor[$i];
}
$mod = $checksum % 11;
return $verify_number_list[$mod];
}
idcard_15to18()處理出生年份補全(19/20 世紀)及百歲老人特殊編碼:
function idcard_15to18($idcard) {
if (strlen($idcard) != 15) return false;
// 百歲以上老人特殊順序碼處理
$special_codes = ['996', '997', '998', '999'];
$seq = substr($idcard, 12, 3);
if (in_array($seq, $special_codes)) {
$idcard = substr($idcard, 0, 6) . '18' . substr($idcard, 6, 9);
} else {
$idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6, 9);
}
// 附加校驗碼
return $idcard . idcard_verify_number($idcard);
}
idcard_checksum18()核對最後一位校驗碼是否正確:
function idcard_checksum18($idcard) {
if (strlen($idcard) != 18) return false;
$base = substr($idcard, 0, 17);
$provided = strtoupper(substr($idcard, 17, 1));
$calculated = idcard_verify_number($base);
return $calculated === $provided;
}
idcard_verify_number 為底層核心適用於用戶註冊實名認證、表單驗證、資料清洗等需要身份證合法性校驗的業務場景。