中国的身份证号码(居民身份证号码)由 18 位数字组成,每个位置都有特定的含义和校验规则。以下是身份证号码的基本规则:
- 前 1 - 6 位 :地址码,表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
- 第 7 -14 位 :出生日期码,表示编码对象出生的年、月、日,按 GB/T 7408 的规定执行,年、月、日代码之间不用分隔符。
- 第 15-17 位 :顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
- 第 18 位 :校验码,根据前面 17 位数字码,按照 ISO 7064:1983,MOD 11- 2 校验码计算出来的检验码。
校验码的计算方法
校验码的计算步骤如下:
- 将身份证号码的前 17 位数字分别乘以一个系数(从右到左依次为:7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)。
- 将得到的乘积求和。
- 将和除以 11,得到余数。
- 根据余数,通过查找对应表(0-10 分别对应 1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2),得到校验码。
PHP 校验身份证号合规的代码示例
以下是一个 PHP 代码示例,用于校验身份证号码的合规性:
<?php
function isValidIDCard($idCard) {
// 检查长度
if (strlen($idCard) != 18) {return false;}
// 检查地址码(前 6 位)是否为数字
if (!preg_match('/^\d{6}/', $idCard)) {return false;}
// 检查出生日期码(第 7 -14 位)是否为合法日期
$birthDate = substr($idCard, 6, 8);
$dateTime = DateTime::createFromFormat('Ymd', $birthDate);
$errors = DateTime::getLastErrors();
if ($errors['warning_count'] + $errors['error_count'] > 0 || $dateTime->format('Ymd') != $birthDate) {return false;}
// 检查顺序码(第 15-17 位)是否为数字
if (!preg_match('/\d{3}/', substr($idCard, 14, 3))) {return false;}
// 校验校验码(第 18 位)$factors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$checkMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$sum = 0;
for ($i = 0; $i < 17; $i++) {$sum += intval(substr($idCard, $i, 1)) * $factors[$i];
}
$mod = $sum % 11;
$expectedCheckDigit = $checkMap[$mod];
return $expectedCheckDigit === strtoupper(substr($idCard, 17, 1));
}
// 测试
$idCard = "11010519491231002X"; // 示例身份证号
if (isValidIDCard($idCard)) {echo "身份证号合法 \n";} else {echo "身份证号不合法 \n";}
?>
正文完
有偿技术支持加微信