<?php
/*
* 校验规则是:
* (1)十七位数字本体码加权求和公式
* S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
* Ai:表示第i位置上的身份证号码数字值
* Wi:表示第i位置上的加权因子
* Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
* (2)计算模
* Y = mod(S, 11)
* (3)通过模得到对应的校验码
* Y: 0 1 2 3 4 5 6 7 8 9 10
* 校验码: 1 0 X 9 8 7 6 5 4 3 2
* 也就是说,如果得到余数为1则最后的校验位p应该为对应的0.如果校验位不是,则该身份证号码不正确。
* */
class cardCheack{
static private $powers = array('7','9','10','5','8','4','2','1','6','3','7','9','10','5','8','4','2'); #17
static private $parityBit = array('1','0','X','9','8','7','6','5','4','3','2');
static public function validId($cardno='')
{
$ret = array('isvalid'=>'', 'msg'=>'');
if(empty($cardno)){
return $ret;
}
switch(strlen($cardno)){
case 15:
$ret= self::validId15($cardno); break;
case 18:
$ret= self::validId18($cardno); break;
default:
return array(
'isvalid'=>false,
'msg'=>'',
);
}
return $ret;
}
#18bit身份证号校验
#@param: cardno 身份证号
#@return: true, false
static public function validId18($cardno='')
{
$_ret = array();
$_cardno = $cardno.'';
$_num = substr($cardno, 0, 17);
$_parityBit = (int)substr($cardno, 17);
$_powers = 0;
for($i = 0; $i < 17; $i++){
if($_num[$i] < '0' || $_num[$i] > '9'){
return array(
'isvalid'=>false,
'msg'=>'',
);
break;
}else{
#加权
$_powers += intval($_num[$i])*intval(self::$powers[$i]);
#性别
if($i==16 && intval($_num[$i])%2==0){
$_ret['msg'] = 'female';
}else{
$_ret['msg'] = 'male';
}
}
}
#校验
$mod = intval($_powers)%11;
$_ret['isvalid'] = (strtoupper(self::$parityBit[$mod])==$_parityBit) ? true: false;
return $_ret;
}
#15bit身份证号校验
#@param: cardno 身份证号
#@return: true, false
public function validId15($cardno=''){
$cardno = $cardno.'';
$len = strlen($cardno);
for($i=0; $i<$len; $i++){
if($cardno[$i] < '0' || $carno[$i] > '9'){
return array(
'isvalid'=>false,
'msg'=>'',
);
break;
}
}
$_year = substr($cardno, 6, 2);
$_month = substr($cardno, 8, 2);
$_day = substr($cardno, 10, 2);
$_sexbit= substr($cardno, 14);
#校验年份
if($_year < '01' || $_year > '90'){
return array(
'isvalid'=>false,
'msg'=>'',
);
}
if($_month < '01' || $_month > '12'){
return array(
'isvalid'=>false,
'msg'=>'',
);
}
if($_day < '01' || $_day> '31') {
return array(
'isvalid'=>false,
'msg'=>'',
);
}
#设置性别
return array(
'isvalid'=>true,
'msg'=>!!$_sexbit%2? 'male': 'felmale',
);
}
}
/*$obj = new cardCheack();
var_dump($obj->validId('412728198610110071'));
*/
var_dump(cardCheack::validId('412728198610110071'));