PHP验证身份证格式
互联网公司对身份证验证的需求越来越多,然而普通的小公司是无法对接公安部门的身份认证系统的。几乎都是在网上买一些大的互联网公司的一些认证服务。即使是便宜一些的认证价格也达到了10万次/万元。也就是一角钱一次了,还是挺贵哈。所以为了减少公司的开支,我们在拿到用户提交的身份证信息去认证前应该自己先检验一下身份证的格式,如果连最基本的身份证格式就不满足的话,我们完全可以直接驳回,不必走接下来的花钱认证流程了,而且也可以建立一个用户身份证表,把每次认证通过的数据存起来,以后每次都先从自己系统里的用户身份证表查询,查不到再去走认证流程,最大化节省公司开支。
这里提供一个初步验证身份证格式的PHP身份证验证类。该类只提供一个静态方法isValid接口,使用起来也很简单,只需要使用IdentityCard::isValid即可验证。可以放到自己项目中当做工具类。该方法可以同时验证15位的老身份证和18位的新身份证格式
PHP版本: >=7.0.0
注: 如果PHP版本低于7.0版本只需要把类中方法的参数限制取消掉即可使用。
class IdentityCard
{
/**
* 校验身份证号是否合法
* @param string $num 待校验的身份证号
* @return bool
*/
public static function isValid(string $num)
{
//老身份证长度15位,新身份证长度18位
$length = strlen($num);
if ($length == 15) { //如果是15位身份证
//15位身份证没有字母
if (!is_numeric($num)) {
return false;
}
// 省市县(6位)
$areaNum = substr($num, 0, 6);
// 出生年月(6位)
$dateNum = substr($num, 6, 6);
} else if ($length == 18) { //如果是18位身份证
//基本格式校验
if (!preg_match('/^\d{17}[0-9xX]$/', $num)) {
return false;
}
// 省市县(6位)
$areaNum = substr($num, 0, 6);
// 出生年月日(8位)
$dateNum = substr($num, 6, 8);
} else { //假身份证
return false;
}
//验证地区
if (!self::isAreaCodeValid($areaNum)) {
return false;
}
//验证日期
if (!self::isDateValid($dateNum)) {
return false;
}
//验证最后一位
if (!self::isVerifyCodeValid($num)) {
return false;
}
return true;
}
/**
* 省市自治区校验
* @param string $area 省、直辖市代码
* @return bool
*/
private static function isAreaCodeValid(string $area) {
$provinceCode = substr($area, 0, 2);
// 根据GB/T2260—999,省市代码11到65
if (11 <= $provinceCode && $provinceCode <= 65) {
return true;
} else {
return false;
}
}
/**
* 验证出生日期合法性
* @param string $date 日期
* @return bool
*/
private static function isDateValid(string $date) {
if (strlen($date) == 6) { //15位身份证号没有年份,这里拼上年份
$date = '19'.$date;
}
$year = intval(substr($date, 0, 4));
$month = intval(substr($date, 4, 2));
$day = intval(substr($date, 6, 2));
//日期基本格式校验
if (!checkdate($month, $day, $year)) {
return false;
}
//日期格式正确,但是逻辑存在问题(如:年份大于当前年)
$currYear = date('Y');
if ($year > $currYear) {
return false;
}
return true;
}
/**
* 验证18位身份证最后一位
* @param string $num 待校验的身份证号
* @return bool
*/
private static function isVerifyCodeValid(string $num)
{
if (strlen($num) == 18) {
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$tokens = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$checkSum = 0;
for ($i = 0; $i < 17; $i++) {
$checkSum += intval($num{$i}) * $factor[$i];
}
$mod = $checkSum % 11;
$token = $tokens[$mod];
$lastChar = strtoupper($num{17});
if ($lastChar != $token) {
return false;
}
}
return true;
}
}
使用示例:
// 测试
$num = '33071919610920021X';
if (IdentityCard::isValid($num)) {
echo '身份证格式正确';
} else {
echo '身份证格式不正确';
}
下面是身份证编码各个部分的含义:
//=============新的18位身份证号码各位的含义:=======================
//1-2位省、自治区、直辖市代码;11-65
//3-4位地级市、盟、自治州代码;
//5-6位县、县级市、区代码;
//7-14位出生年月日,比如19670401代表1967年4月1日;
//15-17位为顺序号,其中17位男为单数,女为双数;
//18位为校验码,0-9和X,由公式随机产生。
//举例:
//130503 19670401 0012这个身份证号的含义: 13为河北,05为邢台,03为桥西区,出生日期为1967年4月1日,顺序号为001,2为验证码
//===========15位身份证号码各位的含义:=======================
//1-2位省、自治区、直辖市代码;
//3-4位地级市、盟、自治州代码;
//5-6位县、县级市、区代码;
//7-12位出生年月日,比如670401代表1967年4月1日,这是和18位号码的第一个区别;
//13-15位为顺序号,其中15位男为单数,女为双数;
//与18位身份证号的第二个区别:没有最后一位的验证码。
//举例:
//130503 670401 001的含义; 13为河北,05为邢台,03为桥西区,出生日期为1967年4月1日,顺序号为001。
PHP验证身份证格式的更多相关文章
- JAVA验证身份证格式及合法性
旅游电子商务中,预订酒店或订购门票时会以身份证作为消费凭证,为了防止客户误填身份证带来不必要麻烦,需要验证码格式及合法性,代码如下: /** * 判断身份证格式 * * @param idNum * ...
- js验证身份证格式
(function(){ Validate={ data:{ // 加权因子 Wi : [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ...
- js使用正则表达式验证身份证格式
function checkIdentity(identity){ var reg = /^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/; i ...
- js 精确验证身份证(地址编码、出生日期、校验位验证)
//身份证号合法性验证 //支持15位和18位身份证号 //支持地址编码.出生日期.校验位验证 function IdentityCodeValid(code) { ::::::::::::::::: ...
- JS验证身份证号码合法性
<html><head><script type="text/javascript"> function validateCard(){ ...
- jQuery validation学习(2)验证身份证
验证邮编 jQuery.validator.addMethod("isZipCode", function(value, element) { -]{}$/; return thi ...
- JS验证身份证的合法性
//验证身份证的合法性 function IdentityCodeValid(code) { var city={11:"北京",12:"天津",13:&quo ...
- bootstrap-validator基本使用(自定义验证身份证号和手机号)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- js验证身份证号码是否合规
需求:最近要做实名验证的功能,但是验证身份证号码和身份证图片的接口不想短信,比较贵,所以之前我们要验证严谨一点,参考了网上关于验证身份证号码的代码,总结一下 代码: //验证身份证号码 functio ...
随机推荐
- 【python3两小时快速入门】入门笔记03:简单爬虫+多线程爬虫
作用,之间将目标网页保存金本地 1.爬虫代码修改自网络,目前运行平稳,博主需要的是精准爬取,数据量并不大,暂未加多线程. 2.分割策略是通过查询条件进行分类,循环启动多条线程. 1.单线程简单爬虫(第 ...
- PHP输出缓冲及其应用
缓冲(buffer)是为了协调吞吐速度相差很大的设备之间数据传送而采用的技术,用来存放缓冲数据的区域叫缓冲区,在计算机科学领域,当数据从一个地方传送到另一个地方时,缓冲区被用来临时存储数据.与缓冲相似 ...
- @Autowired自动注入失败
新手注意的问题 package cn.ryq.web.controller; import cn.ryq.domain.company.Company;import cn.ryq.service.co ...
- Oracle常用的一些 数据字典 转https://www.cnblogs.com/neozhu/archive/2008/07/22/1248422.html
Oracle常用数据字典表 Oracle常用数据字典表 查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_ ...
- JAVA Stirng.format 使用理解
JAVA Stirng.format 使用理解前言:项目中需要对一些字符串处理发现format方法的神奇之处一.api才是王道第一种二参使用①public static String format(S ...
- 阿里巴巴 -- MySQL DBA 面试题
1.MySQL的复制原理以及流程 (1).先问基本原理流程,3个线程以及之间的关联: (2).再问一致性延时性,数据恢复: (3).再问各种工作遇到的复制bug的解决方法. 2.MySQL中myisa ...
- BZOJ 1085:[SCOI2005]骑士精神(A*算法)
题目链接 题意 中文题意. 思路 首先找到空白的格子,因为空白的格子可以和其他的骑士换.从空白的点开始搜索,每次和其他点交换.因为最多只有十五步,可以做16次搜索,搜索的时候,记录走过的步数和至少剩余 ...
- Codeforces 755D:PolandBall and Polygon(思维+线段树)
http://codeforces.com/problemset/problem/755/D 题意:给出一个n正多边形,还有k,一开始从1出发,向第 1 + k 个点连一条边,然后以此类推,直到走完 ...
- flask高级编程 LocalStack 线程隔离
转:https://www.cnblogs.com/wangmingtao/p/9372611.html 30.LocalStack作为线程隔离对象的意义 30.1 数据结构 限制了某些能力 30 ...
- 在?MySQL事务隔离级别了解一下?
事务的四大ACID 属性:Atomicity 原子性.Consistency 一致性.Isolation 隔离性.Durability 持久性. 原子性: 事务是最小的执行单位不可分割,强调事务的不可 ...