背景:前一陣子遇到了【舊】香港的身份證校驗的問題,分享出來,希望能幫助需要的人
一、校驗身份證
IdVerify::verifyHKIdCard($number)
二、檢驗身份證演算法
namespace App\Services;
class IdVerify
{
//香港身份證首字母對應的數字
private static $capitalNum = array(
'A'=>10,
'B'=>11,
'C'=>12,
'D'=>13,
'E'=>14,
'F'=>15,
'G'=>16,
'H'=>17,
'I'=>18,
'J'=>19,
'K'=>20,
'L'=>21,
'M'=>22,
'N'=>23,
'O'=>24,
'P'=>25,
'Q'=>26,
'R'=>27,
'S'=>28,
'T'=>29,
'U'=>30,
'V'=>31,
'W'=>32,
'X'=>33,
'Y'=>34,
'Z'=>35,
' '=>36,
);
/**
* 香港身份證驗證
* @param $number
* @return bool
*/
public static function verifyHKIdCard($number)
{
//將中文括號全部替換成英文括號
if (strpos($number, "(") || strpos($number, ")")) {
$number = str_replace('(', '(', $number);
$number = str_replace(')', ')', $number);
}
$number_num = strlen($number);
if (!in_array($number_num, array(10, 11))) {
return false;
}
$first_num = substr($number, 0, 1);//取首字母
$number_num == 10 && $number = ' ' . $number;
$checkCode = substr($number, -2, 1);//取括號內的校驗碼
if ((!preg_match('/^[A-Z]+$/', $first_num)) || !is_numeric(substr($number, 2, 6))) {
return false;
}
$number_ex = explode('(', $number);
$number_arr = str_split($number_ex[0]);
$number_sum = 0;
$i = 9;
foreach ($number_arr as $k => $v) {
if (isset(static::$capitalNum[$v]) || is_numeric($v)) {
if (isset(static::$capitalNum[$v])) {
$number_total = (static::$capitalNum[$v] % 11) * $i % 11;
} else {
$number_total = $v * $i % 11;
}
$i -= 1;
$number_sum += $number_total;
}
}
$result = $number_sum % 11;
switch ($result) {
case 1:
$result = 'A';
break;
case 0:
$result = 0;
break;
default:
$result = 11 - $result;
break;
}
if ($checkCode == $result) {
return true;
} else {
return false;
}
}
}