背景
- 1984年4月6日:国务院发布《中华人民共和国居民身份证试行条例》,并且开始颁发第一代居民身份证。此时的身份证号码为 15 位数
- 1999年7月1日:从国家质量技术监督局批准发布强制性国家标准《公民身份号码》并于1999年7月1日起实施开始。身份证号码将由原来的 15 位数升至 18 位数
- 2001年:第二代身份证上线
- 2004年3月29日:中国大陆正式开始为居民换发内置非接触式IC卡智能芯片的第二代居民身份证,二代身份证表面采用防伪膜和印刷防伪技术,使用个人彩色照片,并可用机器读取数字芯片内的信息。身份证号码依旧为 18 位数
- 2013年1月1日:第一代居民身份证正式退出
- 第三代身份证截止目前(2022.9.1) 还处于概念设计阶段
身份证编排规则
- 前 1 - 2 位数字表示:所在省份的代码
- 第 3 - 4 位数字表示:所在城市的代码
- 第 5 - 6 位数字表示:所在区县的代码
- 第 7 - 14 位数字表示:出生年( 4 位)、月( 2 位)、日( 2 位)
- 第 15 - 16 位数字表示:所在地的派出所的代码
- 第 17 位数字表示性别:奇数标识男性、偶数表示女性
- 第 18 位数字表示校验位、用来校验身份证的正确性
上述规则是 18 位身份证的规则相比较 15 位有两个变化:
- 出生年区别:18位的是 yyyy、15 位的是 yy
- 校验位区别:15 位没有校验位
第18位校验位规则(根据国家标准GB 11643-1999)
- 将前面的身份证号码17位数分别乘以不同的系数。从第 1 位到第 17 位的系数分别为 7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2
- 将这17位数字和系数相乘的结果相加。
- 用加出来和除以11,得出余数
- 余数只可能有 0-1-2-3-4-5-6-7-8-9-10 这 11 个数字。
- 其分别对应的最后一位身份证的号码为 1-0-X -9-8-7-6-5-4-3-2。
例如:
上面得知如果余数是 3,就会在身份证的第 18 位数字上出现的是 9;
如果对应的数字是 10,身份证的最后一位号码就是罗马数字 x
代码检查身份证号是否合法
public function checkIdCard(String $idCard = ""): bool
{
$idCard = strtoupper($idCard);
$regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
if (!preg_match($regx, $idCard)) {
return false;
}
$splitArr = [];
/*
* 校验 15 位
*/
if (strlen($idCard) == 15) {
$regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";
@preg_match($regx, $idCard, $splitArr);
$birth = "19" . $splitArr[2] . '/' . $splitArr[3] . '/' . $splitArr[4];
//检查生日日期是否正确
return (bool)strtotime($birth);
}
/*
* 校验 18 位
*/
$regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
@preg_match($regx, $idCard, $splitArr);
$birth = $splitArr[2] . '/' . $splitArr[3] . '/' . $splitArr[4];
// 校验生日
if (!strtotime($birth)) {
return false;
}
// 加权因子
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校验码对应值
$code = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
// 校验最后一位校验码
// 计算身份证的最后一位验证码,根据国家标准GB 11643-1999
$sign = 0;
for ($i = 0; $i < 17; $i++) {
$sign += $idCard[$i] * $factor[$i];
}
$calcNum = $code[$sign % 11];
if ($calcNum != substr($idCard, -1)) {
return false;
} else {
return true;
}
}
获取更多信息
身份证号包含了很多信息,包括省市区,生日,性别,以及通过出生年月计算出来的年龄,星座,生肖等
# 获取省市区需要全量的省市区数据源
# 或者使用阿里云 openAPI或者其他第三方开放api
获取年龄
public function age(string $idCard = ""): int
{
// 身份证号合法性校验
if (!$this->checkIdCard($idCard)) return '';
if (strlen($idCard) == 15) { # 15 位身份证
$year = (int)("19" . substr($idCard, 6, 2));
$monthDay = (int)substr($idCard, 8, 4);
} else { # 18 位身份证
$year = (int)substr($idCard, 6, 4);
$monthDay = (int)substr($idCard, 10, 4);
}
$age = date('Y') - $year;
if ($monthDay > date('md')) {
$age--;
}
return $age;
}
获取性别
public function gender(String $idCard = ""): String
{
// 身份证号合法性校验
// checkIdCard 方法在上面示例中
if(!$this->checkIdCard($idCard)) return '';
if(strlen($idCard) == 15) { # 15 位身份证
$sex = (int)substr($idCard,14,1);
} else { # 18 位身份证
$sex = (int)substr($idCard,16,1);
}
return $sex % 2 === 0 ? '女' : '男';
}
获取星座
public function constellation(String $idCard = ""): string
{
// 身份证号合法性校验
if (!$this->checkIdCard($idCard)) return '';
if(strlen($idCard) == 15) {
$birthday = substr($idCard,8,4);
} else {
$birthday = substr($idCard,10,4);
}
$month = (int)substr($birthday,0,2);
$day = (int)substr($birthday,2);
$constellation = '';
if(($month == 1 && $day <= 21) || ($month == 2 && $day <= 19)) {
$constellation = "水瓶座";
}else if(($month == 2 && $day > 20) || ($month == 3 && $day <= 20)) {
$constellation = "双鱼座";
}else if (($month == 3 && $day > 20) || ($month == 4 && $day <= 20)) {
$constellation = "白羊座";
}else if (($month == 4 && $day > 20) || ($month == 5 && $day <= 21)) {
$constellation = "金牛座";
}else if (($month == 5 && $day > 21) || ($month == 6 && $day <= 21)) {
$constellation = "双子座";
}else if (($month == 6 && $day > 21) || ($month == 7 && $day <= 22)) {
$constellation = "巨蟹座";
}else if (($month == 7 && $day > 22) || ($month == 8 && $day <= 23)) {
$constellation = "狮子座";
}else if (($month == 8 && $day > 23) || ($month == 9 && $day <= 23)) {
$constellation = "处女座";
}else if (($month == 9 && $day > 23) || ($month == 10 && $day <= 23)) {
$constellation = "天秤座";
}else if (($month == 10 && $day > 23) || ($month == 11 && $day <= 22)) {
$constellation = "天蝎座";
}else if (($month == 11 && $day > 22) || ($month == 12 && $day <= 21)) {
$constellation = "射手座";
}else if (($month == 12 && $day > 21) || ($month == 1 && $day <= 20)) {
$constellation = "魔羯座";
}
return $constellation;
}
获取属相
function getZodiac(String $idCard = ""): string
{
// 身份证号合法性校验
if(!$this->checkIdCard($idCard)) return '';
// 获取年份
if(strlen($idCard) == 15) {
$year = "19" . substr($idCard,6,2);
} else {
$year = substr($idCard,6,4);
}
$animals = array('子鼠','丑牛','寅虎','卯兔','辰龙','巳蛇','午马','未羊','申猴','酉鸡','戌狗','亥猪');
$key = ($year - 1900) % 12;
return $animals[$key];
}
叼茂SEO.bfbikes.com
想想你的文章写的特别好https://www.jiwenlaw.com/
叼茂SEO.bfbikes.com
想想你的文章写的特别好https://www.237fa.com/
看的我热血沸腾啊www.jiwenlaw.com
看的我热血沸腾啊www.jiwenlaw.com
文章的确不错啊https://www.cscnn.com/
《猛鬼食人胎国语》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/49875.html