标签:
首先先了解 身份证号码的编码规则,从百度经验上找到了别人的分享
:http://jingyan.baidu.com/article/7f41ececff944a593d095c8c.html
感谢。
15位长度的验证正则是从网上找的,但发现并不是万能的(月份可以出现00,日期可以出现00等),
所以做了如下改良,但仍旧存在一些问题,如880231这样的生日也可以验证功过
所以可以考虑将身份证号码的年月日单独判断,在此略去。
18位长度的就按校验规则来校验即可。
function chkIdNo($idNo)
{
//身份证正则表达式(15位)
//isIDCard1=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
////身份证正则表达式(18位)
//isIDCard2=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
$len = strlen($idNo);
//十五位身份证1999 10 01不再办理
if($len == 15) {
//13 04 03 991001 002
//$pattern = ‘/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{2}[Xx0-9]$/‘;
//修复 月份 天 不能同时为00
$pattern = ‘/^[1-9]\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|3[0-1])\d{2}[Xx0-9]$/‘;
$res = preg_match($pattern, $idNo);
if($res) return true;
return false;
}
if($len == 18){
//前17位对应的权重数字算法 (2<<($len - 2 - n)%11
$bits = str_split($idNo);
//每位对应的权重数字
$weights = array();
//求和
$sum = 0;
for($i = 0; $i < 17; $i++) {
//计算权重
$weights[$i] = (2 << ($len - 2 - $i)) % 11;
$sum += $bits[$i] * $weights[$i];
}
$mod = $sum % 11;
//校验码array(1, 0, ‘X‘, 9, 8, 7, 6, 5, 4, 3, 2);
$chkCodes = array(1, 0, ‘X‘, 9, 8, 7, 6, 5, 4, 3, 2);
$code = isset($chkCodes[$mod]) ? $chkCodes[$mod].‘‘ : ‘‘;
if($code !== $bits[$len - 1]) {
return false;
}
return true;
}
return false;
}
标签:
原文地址:http://www.cnblogs.com/the-moving-ear/p/4346939.html