身份证验证合法性及是否需要防沉迷检测

    jeff
  • 发表于2018-09-18 09:11
  • 阅读(399)
身份证验证合法性及是否需要防沉迷检测
<?php 
/**
 * 身份证验证合法性及是否需要防沉迷检测
 * my.hemh@gmail.com
 * @example ChineseIdCardNumberValidator::check_id_card_enthrallment_status('idcard_number');
 * @example ChineseIdCardNumberValidator::check_id_card_base_format('idcard_number');
 * 2010-01-20
 */
 class ChineseIdCardNumberValidator{
  private static $adult_age = 18; //成年的年龄,低于此年龄列为防沉迷用户
  private static  $id_card_length = 0; //身份证的长度
  private static  $id_card_number = ''; //身份证号码
/**
* 验证身份证是否防沉迷(false)需要防沉迷,true不需要防沉迷
*/
public static function check_id_card_enthrallment_status($id_card_number){
$verify_result = self::check_id_card_base_format($id_card_number) && self::_check_user_age();
return $verify_result;
}
  
  
/**
* 检测身份证的基本格式
*/
public static  function check_id_card_base_format($id_card_number){
self::$id_card_length = strlen($id_card_number);
self::$id_card_number = $id_card_number;
$verify_result = self::_check_id_card_length() && self::_check_id_card_is_number() 
&& self::_check_id_card_date_format() && self::_check_id_card_last_check_code() && self::_check_id_card_area_code();
return $verify_result;
}
/**
*检测身份证号码的长度,是否为15位或18位
* @param int $card_number 身份证号码
* @return bool
*/
private static function _check_id_card_length(){
if(self::$id_card_length==15||self::$id_card_length==18){
return true;
}
return false;
}
/**
* 检测身份证的前两位地区码,是否正确
*/
private static function _check_id_card_area_code(){
$fore_two_char = substr(self::$id_card_number,0,2);
if(!in_array($fore_two_char,self::$id_card_area_code_config)){
return false;
}
return true;
}
/**
* 检测身份证的基本格式前17位必须为数字
* @param int $card_number 身份证号码
* @return bool
*/
private  static function _check_id_card_is_number(){
if(self::$id_card_length == 18){
$card_number = substr(self::$id_card_number,0,-1);
}else {
$card_number = self::$id_card_number;
}
if(!is_numeric($card_number)||$card_number<0){
return false;
}
return true;
}
/**
* 检测日期格式是否有误
*/
private static  function _check_id_card_date_format(){
$year =  substr(self::$id_card_number,6,4);
$month = substr(self::$id_card_number,10,2);
$day = substr(self::$id_card_number,12,2);
if(($year<1910) || ($year>date('Y')) || ($month<1) || ($month>12) || ($day<1) || ($day>31)){
return false;
}
return true;
}
/**
* 验证用户的年龄是否大于18岁
* @param string $card_number 
*/
private  static function _check_user_age(){
$year =  substr(self::$id_card_number,6,4);
$month = substr(self::$id_card_number,10,2);
$day = substr(self::$id_card_number,12,2);
$birthday = "{$year}-{$month}-$day";
$adult_age = self::$adult_age;
$last_eighteen_year = strtotime("{$birthday}+{$adult_age} year"); 
$now_timestamp = time();
if($now_timestamp<$last_eighteen_year){
//未成年,小于18岁
return false;
}
return true;
}
/**
* 检测最后一位校验码
*/
private static function _check_id_card_last_check_code(){
$get_last_check_code = self::_get_id_card_check_code();
$id_card_last_char = substr(self::$id_card_number,-1);
if(!is_numeric($id_card_last_char)){
$id_card_last_char = strtoupper($id_card_last_char);
}
if($get_last_check_code != $id_card_last_char){
return false;
}
return true;
}
/**
* 获取身份证的校验码 
*/
private  static function _get_id_card_check_code(){
$temp_card_number = self::$id_card_number;
if(self::$id_card_length==18){
$temp_card_number = substr(self::$id_card_number,0,-1);
}
if(self::$id_card_length==15){
//前6个后9个中间为19
$temp_card_number = substr(self::$id_card_number,6).'19'.substr(self::$id_card_number,-9);
}
$s = self::_get_id_card_s($temp_card_number);
$id_card_check_code = (12-($s%11))%11;
if($id_card_check_code==10){
$id_card_check_code = 'X';
}
return $id_card_check_code;
}
/**
* 计算ai()*wi(权重系数)的总和
* @param int $card_number 身份证号码,只能前17位
*
*/
private static function _get_id_card_s($card_number){
$sum = 0;
$reverse_id_card_arr = self::_get_reverse_id_card_arr($card_number);
if(!empty($reverse_id_card_arr)){
for ($i=0;$i<strlen($card_number);$i++){
$s = self::_get_id_card_check_code_w($i+2);
$sum += $reverse_id_card_arr[$i]*$s;
}
}
return $sum;
}
/**
* 获取权重系统W
*/
private static function _get_id_card_check_code_w($i){
return  pow(2,$i-1)%11;
}
/**
* 将身份证号码生成一个逆向的数组
* @param int $card_number 身份证号码
*/
private static function _get_reverse_id_card_arr($card_number){
$reverse_arr = array();
$card_length = strlen($card_number);
if($card_length>0){
for ($i=1;$i<=$card_length;$i++){
$start = $card_length-$i;
$reverse_arr[$i-1] = substr($card_number,$start,1);
}
}
return $reverse_arr;
}
/**
* 设置地区码,身份证的前两位
*/
private static $id_card_area_code_config =  array(
'11', //北京市
'12', //天津市
'13', //河北省
'14', //山西省
'15', //内蒙古自治区
'21', //辽宁省
'22', //吉林省
'22', //吉林省
'23', //黑龙江省
'31', //上海市
'32', //江苏省
'33', //浙江省
'34', //安徽省
'35', //福建省
'36', //江西省
'37', //山东省
'41', //河南省
'42', //湖北省
'43', //湖南省
'44', //广东省
'45', //广西壮族自治区
'46', //海南省
'50', //重庆市
'51', //四川省
'52', //贵州省
'53', //云南省
'54', //西藏自治区
'61', //陕西省
'62', //甘肃省
'63', //青海省
'64', //宁夏回族自治区
'65', //新疆维吾尔自治区
'71', //台湾省
'81', //香港特别行政区
'82', //澳门特别行政区
  
);
}
?>

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
不写代码的码农
jeff

3 篇文章

作家榜 »

  1. jeff 3 文章
  2. zero 1 文章
  3. Liang 1 文章
  4. ding 0 文章