最严格身份证号码验证,支持15位和19世纪出生的人的身份证号码
# 计算身份证校验码,根据国家标准GB 11643-1999
function idcard_verify_number($idcard_base){
if(strlen($idcard_base)!=17){
return false;
}
//加权因子
$factor=array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
//校验码对应值
$verify_number_list=array('1','0','X','9','8','7','6','5','4','3','2');
$checksum=0;
for($i=0;$i<strlen($idcard_base);$i++){< p="">
$checksum += substr($idcard_base,$i,1) * $factor[$i];
}
$mod=$checksum % 11;
$verify_number=$verify_number_list[$mod];
return $verify_number;
}
# 将15位身份证升级到18位
function idcard_15to18($idcard){
if(strlen($idcard)!=15){
return false;
}else{
// 如果身份证顺序码是996 997 998 999,这些是为百岁以上老人的特殊编码
if(array_search(substr($idcard,12,3),array('996','997','998','999')) !== false){
$idcard=substr($idcard,0,6).'18'.substr($idcard,6,9);
}else{
$idcard=substr($idcard,0,6).'19'.substr($idcard,6,9);
}
}
$idcard=$idcard.idcard_verify_number($idcard);
return $idcard;
}
/****身份证验证结束*****/
function checkIdCard($idCard){
$regIdCard="/^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/";
$idCard = strtoupper($idCard);// 强制转化大写
if(!preg_match($regIdCard, $idCard))
{
return false;
}
if ( 18==strlen($idCard) ) {
$idCardWi = array( 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ); //将前17位加权因子保存在数组里
// $idCardY = array( 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ); //
$idCardY = array( 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ); //强制转化大写问题
$idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
for($i=0;$i<17;$i++){
// $idCardWiSum += substr($idCard,$i,1) * $idCardWi[$i];
$idCardWiSum += $idCard{$i} * $idCardWi[$i];
}
$idCardMod = $idCardWiSum%11;//计算出校验码所在数组的位置
$idCardLast = $idCard{17};//得到最后一位身份证号码
//如果等于2,则说明校验码是10,身份证号码最后一位应该是X
//用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
if($idCardLast==$idCardY[$idCardMod]){
return true;
}else{
return false;
}
}elseif( 15 == strlen($idCard) ){
$NewIdCard = idcard_15to18($idCard);
return checkIdCard($NewIdCard);
}else{
return false;
}
}