您的位置:首页 > 编程语言 > PHP开发

PHP验证身份证类(包含香港身份证校验)

2016-07-21 15:02 615 查看
<?php
// check
class CheckCard{
// $num为身份证号码,$checkSex:1为男,2为女,不输入为不验证
public function checkIdentity($num,$checkSex=''){
// 不是15位或不是18位都是无效身份证号
if(strlen($num) != 15 && strlen($num) != 18){
return false;
}
// 是数值
if(is_numeric($num)){
// 如果是15位身份证号
if(strlen($num) == 15 ){
// 省市县(6位)
$areaNum = substr($num,0,6);
// 出生年月(6位)
$dateNum = substr($num,6,6);
// 性别(3位)
$sexNum = substr($num,12,3);
}else{
// 如果是18位身份证号
// 省市县(6位)
$areaNum = substr($num,0,6);
// 出生年月(8位)
$dateNum = substr($num,6,8);
// 性别(3位)
$sexNum = substr($num,14,3);
// 校验码(1位)
$endNum = substr($num,17,1);
}
}else{
// 不是数值
if(strlen($num) == 15){
return false;
}else{
// 验证前17位为数值,且18位为字符x
$check17 = substr($num,0,17);
if(!is_numeric($check17)){
return false;
}
// 省市县(6位)
$areaNum = substr($num,0,6);
// 出生年月(8位)
$dateNum = substr($num,6,8);
// 性别(3位)
$sexNum = substr($num,14,3);
// 校验码(1位)
$endNum = substr($num,17,1);
if($endNum != 'x' && $endNum != 'X'){
return false;
}
}
}

if(isset($areaNum)){
if(!$this ->checkArea($areaNum)){
return false;
}
}

if(isset($dateNum)){
if(!$this ->checkDate($dateNum)){
return false;
}
}

// 性别1为男,2为女
if($checkSex == 1){
if(isset($sexNum)){
if(!$this ->checkSex($sexNum)){
return false;
}
}
}else if($checkSex == 2){
if(isset($sexNum)){
if($this ->checkSex($sexNum)){
return false;
}
}
}

if(isset($endNum)){
if(!$this ->checkEnd($endNum,$num)){
return false;
}
}
return true;
}

// 验证城市
private function checkArea($area){
$num1 = substr($area,0,2);
$num2 = substr($area,2,2);
$num3 = substr($area,4,2);
// 根据GB/T2260—999,省市代码11到65
if(10 < $num1 && $num1 < 66){
return true;
}else{
return false;
}
//============
// 对市 区进行验证
//============
}

// 验证出生日期
private function checkDate($date){
if(strlen($date) == 6){
$date1 = substr($date,0,2);
$date2 = substr($date,2,2);
$date3 = substr($date,4,2);
$statusY = $this ->checkY('19'.$date1);
}else{
$date1 = substr($date,0,4);
$date2 = substr($date,4,2);
$date3 = substr($date,6,2);
$nowY = date("Y",time());
if(1900 < $date1 && $date1 <= $nowY){
$statusY = $this ->checkY($date1);
}else{
return false;
}
}
if(0<$date2 && $date2 <13){
if($date2 == 2){
// 润年
if($statusY){
if(0 < $date3 && $date3 <= 29){
return true;
}else{
return false;
}
}else{
// 平年
if(0 < $date3 && $date3 <= 28){
return true;
}else{
return false;
}
}
}else{
$maxDateNum = $this ->getDateNum($date2);
if(0<$date3 && $date3 <=$maxDateNum){
return true;
}else{
return false;
}
}
}else{
return false;
}
}

// 验证性别
private function checkSex($sex){
if($sex % 2 == 0){
return false;
}else{
return true;
}
}

// 验证18位身份证最后一位
private function checkEnd($end,$num){
$checkHou = array(1,0,'x',9,8,7,6,5,4,3,2);
$checkGu = array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
$sum = 0;
for($i = 0;$i < 17; $i++){
$sum += (int)$checkGu[$i] * (int)$num[$i];
}
$checkHouParameter= $sum % 11;
if($checkHou[$checkHouParameter] != $num[17]){
return false;
}else{
return true;
}
}

// 验证平年润年,参数年份,返回 true为润年  false为平年
private function checkY($Y){
if(getType($Y) == 'string'){
$Y = (int)$Y;
}
if($Y % 100 == 0){
if($Y % 400 == 0){
return true;
}else{
return false;
}
}else if($Y % 4 ==  0){
return true;
}else{
return false;
}
}

// 当月天数 参数月份(不包括2月)  返回天数
private function getDateNum($month){
if($month == 1 || $month == 3 || $month == 5 || $month == 7 || $month == 8 || $month == 10 || $month == 12){
return 31;
}else if($month == 2){
}else{
return 30;
}
}

/**
* 香港身份证校验
* @param string $number 香港身份证号码
* @author mosishu
* @return array 正确时返回true状态和身份证号码,错误时返回false状态
*/
public function checkHKIdCard($number){
//将中文括号全部替换成英文括号
if (strpos($number,"(") || strpos($number,")")){
$number = str_replace('(', '(', $number);
$number = str_replace(')', ')', $number);
}
if(strlen($number)!=10){
return array('status'=>false);
}
$one = substr($number,0,1);//取首字母
$two = substr($number,1,1);//取第二位
$three = substr($number,2,1);//取第三位
$four = substr($number,3,1);//取第四位
$five = substr($number,4,1);//取第五位
$six = substr($number,5,1);//取第六位
$seven = substr($number,6,1);//取第七位
$checkCode = substr($number,-2,1);//取括号内的校验码
$sixNum = substr($number, 1,6);//取中间六位数字
if (preg_match('/^[A-Z]+$/', $one)){//第一位要是大写字母
if ( is_numeric($sixNum)){//中间六位要是数字
$sum = $this->letterNum[$one]*8+$two*7+$three*6+$four*5+$five*4+$six*3+$seven*2;
$residue = $sum%11;
if ($residue==1){
$checkIdCode='A';
}
elseif($residue==0){
$checkIdCode=0;
}
else{
$checkIdCode=11-$residue;
}
if ($checkCode==$checkIdCode){
return array('status'=>true,'sfz_id'=>$number);
}else{
return array('status'=>false);
}
}
else{
return array('status'=>false);
}
}
else{
return array('status'=>false);
}
}

//香港身份证首字母对应的数字
private $letterNum = array(
'A'=>1,
'B'=>2,
'C'=>3,
'D'=>4,
'E'=>5,
'F'=>6,
'G'=>7,
'H'=>8,
'I'=>9,
'J'=>10,
'K'=>11,
'L'=>12,
'M'=>13,
'N'=>14,
'O'=>15,
'P'=>16,
'Q'=>17,
'R'=>18,
'S'=>19,
'T'=>20,
'U'=>21,
'V'=>22,
'W'=>23,
'X'=>24,
'Y'=>25,
'Z'=>26,
);

}


调用过程如下,我这里用的是Thinkphp框架:

//验证身份证合法性
vendor('CheckCard.CheckCard');
$CheckCard=new \CheckCard();
$idCode = $CheckCard->checkIdentity($sfz_id);
$HKCode = $CheckCard->checkHKIdCard($sfz_id);
if(!$idCode && !$HKCode['status']){
$this->error('身份证不合法,请重试!');
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息