PHP Function for Validating Chinese ID Card Numbers
This article explains the structure of Chinese citizen ID numbers and provides a PHP function that validates both 15‑digit and 18‑digit IDs by checking format, birthdate correctness, and computing the checksum according to ISO 7064, accompanied by example usage.
Chinese citizen ID numbers consist of a 17‑digit body code and a final checksum digit. The body code is composed of a six‑digit address code, an eight‑digit birthdate (YYYYMMDD), a three‑digit sequence code (odd for males, even for females), and the checksum digit.
The validation process includes:
Verifying the overall format with regular expressions for 15‑digit and 18‑digit IDs.
Extracting and checking the birthdate part using strtotime to ensure it represents a real date.
For 18‑digit IDs, calculating the checksum according to ISO 7064:1983.MOD 11‑2, where the weighting factors are 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 and the possible check characters are 0‑9 and X.
The following PHP function implements these steps:
<?php
function is_idcard($id)
{
$id = strtoupper($id);
$regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
$arr_split = array();
if (!preg_match($regx, $id)) {
return FALSE;
}
// 15‑digit handling
if (15 == strlen($id)) {
$regx = "/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/";
@preg_match($regx, $id, $arr_split);
$dtm_birth = "19".$arr_split[2]."/".$arr_split[3]."/".$arr_split[4];
if (!strtotime($dtm_birth)) {
return FALSE;
} else {
return TRUE;
}
} else {
// 18‑digit handling
$regx = "/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/";
@preg_match($regx, $id, $arr_split);
$dtm_birth = $arr_split[2]."/".$arr_split[3]."/".$arr_split[4];
if (!strtotime($dtm_birth)) {
return FALSE;
}
// checksum calculation
$arr_int = array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
$arr_ch = array('1','0','X','9','8','7','6','5','4','3','2');
$sign = 0;
for ($i = 0; $i < 17; $i++) {
$b = (int)$id{$i};
$w = $arr_int[$i];
$sign += $b * $w;
}
$n = $sign % 11;
$val_num = $arr_ch[$n];
if ($val_num != substr($id, 17, 1)) {
return FALSE;
} else {
return TRUE;
}
}
}
?>Example usage:
<?php
$rest = is_idcard('123456789012345678');
var_dump($rest); // bool(false)
?>Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
