* @version : HUOSDK 8.0 */ namespace huolib\utils; use huolib\constant\IdentifyConst; use huolib\status\IdentifyStatus; class IdentifyUtils { CONST ID_CARD_MIN_LEN = 4; CONST ID_CARD_MAX_LEN = 32; CONST REAL_NAME_MIN_LEN = 1; CONST REAL_NAME_MAX_LEN = 32; /** * 校验认证 * * @param string $type * @param string $real_name * @param string $id_card * * @return int */ public static function checkIdentify($type = '', $real_name = '', $id_card = '') { if (empty($type)) { return IdentifyStatus::TYPE_EMPTY; } if (empty($real_name)) { return IdentifyStatus::REALNAME_EMPTY; } if (empty($id_card)) { return IdentifyStatus::IDCARD_EMPTY; } if (false == IdentifyConst::getMsg($type)) { return IdentifyStatus::TYPE_ERROR; } if (strlen($real_name) > self::REAL_NAME_MAX_LEN) { return IdentifyStatus::REALNAME_TOO_LONG; } if (strlen($real_name) < self::REAL_NAME_MIN_LEN) { return IdentifyStatus::REALNAME_TOO_SHORT; } if (strlen($id_card) > self::ID_CARD_MAX_LEN) { return IdentifyStatus::IDCARD_TOO_LONG; } if (strlen($id_card) < self::ID_CARD_MIN_LEN) { return IdentifyStatus::IDCARD_TOO_SHORT; } if (IdentifyConst::ITYPE_MAINLAND == $type && false == self::validateIDCard($id_card)) { return IdentifyStatus::IDCARD_ERROR; } return IdentifyStatus::NO_ERROR; } /** * 验证身份证是否有效 * * @param $id_card * * @return bool */ public static function validateIDCard($id_card) { $_id_card = $id_card; if (strlen($_id_card) == 18) { return self::check18IDCard($_id_card); } elseif ((strlen($_id_card) == 15)) { $_id_card = self::convertIDCard15to18($_id_card); return self::check18IDCard($_id_card); } else { return false; } } /** * 计算身份证的最后一位验证码,根据国家标准GB 11643-1999 * * @param $id_card_body * * @return bool|mixed */ public static function calcIDCardCode($id_card_body) { if (!is_numeric($id_card_body)) { /* 必须为数字 */ return -1; } $_id_card_body = $id_card_body; if (strlen($_id_card_body) != 17) { return false; } //加权因子 $_factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); //校验码对应值 $_code = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'); $_check_sum = 0; for ($_i = 0; $_i < strlen($_id_card_body); $_i++) { $_check_sum += substr($_id_card_body, $_i, 1) * $_factor[$_i]; } return $_code[$_check_sum % 11]; } /** * 将15位身份证升级到18位 * * @param $id_card * * @return bool|string */ public static function convertIDCard15to18($id_card) { $_id_card = $id_card; if (15 != strlen($_id_card)) { return false; } else { // 如果身份证顺序码是996 997 998 999,这些是为百岁以上老人的特殊编码 if (array_search(substr($_id_card, 12, 3), array('996', '997', '998', '999')) !== false) { $_id_card = substr($_id_card, 0, 6).'18'.substr($_id_card, 6, 9); } else { $_id_card = substr($_id_card, 0, 6).'19'.substr($_id_card, 6, 9); } } $_id_card = $_id_card.self::calcIDCardCode($_id_card); return $_id_card; } /** * 18位身份证校验码有效性检查 * * @param $id_card * * @return bool */ public static function check18IDCard($id_card) { $_id_card = $id_card; if (18 != strlen($_id_card)) { return false; } $_id_card_body = substr($_id_card, 0, 17); //身份证主体 $_id_card_code = strtoupper(substr($_id_card, 17, 1)); //身份证最后一位的验证码 if (self::calcIDCardCode($_id_card_body) != $_id_card_code) { return false; } else { return true; } } /** * 从身份证号码获取生日 * * @param string $id_card 身份证号码 * @param string $glue 连接符 * * @return string : string */ public static function getBirthday($id_card, $glue = '') { if (empty($id_card)) { return ''; } $_date = strlen($id_card) == 15 ? ('19'.substr($id_card, 6, 6)) : substr($id_card, 6, 8); $_year = substr($_date, 0, 4); $_moth = substr($_date, 4, 2); $_day = substr($_date, 6, 2); $_birthday = implode($glue, [$_year, $_moth, $_day]); return $_birthday; } /** * 根据身份证号获取年龄(周岁) * * @param string $id_card 身份证号 * * @return int */ public static function getAgeById($id_card) { $_birthday = self::getBirthday($id_card, '-'); $_age = self::getAge($_birthday); return $_age; } /** * 根据身份证号码计算年龄 * * @param string $birthday 出生年月日 * * @return int $age */ public static function getAge($birthday) { if (empty($birthday)) { return 0; } $_birthday = date('Y-m-d', strtotime($birthday)); list($_birth_year, $_birth_month, $_birth_day) = explode('-', $_birthday); list($_current_year, $_current_month, $_current_day) = explode('-', date('Y-m-d')); $_age = $_current_year - $_birth_year - 1; if ($_current_month > $_birth_month || ($_current_month == $_birth_month && $_current_day >= $_birth_day)) { $_age++; } return $_age; } }