身份证号编排规则及获取更多身份信息

Faria 2022-11-14 PM 1627℃ 3条

背景

  1. 1984年4月6日:国务院发布《中华人民共和国居民身份证试行条例》,并且开始颁发第一代居民身份证。此时的身份证号码为 15 位数
  2. 1999年7月1日:从国家质量技术监督局批准发布强制性国家标准《公民身份号码》并于1999年7月1日起实施开始。身份证号码将由原来的 15 位数升至 18 位数
  3. 2001年:第二代身份证上线
  4. 2004年3月29日:中国大陆正式开始为居民换发内置非接触式IC卡智能芯片的第二代居民身份证,二代身份证表面采用防伪膜和印刷防伪技术,使用个人彩色照片,并可用机器读取数字芯片内的信息。身份证号码依旧为 18 位数
  5. 2013年1月1日:第一代居民身份证正式退出
  6. 第三代身份证截止目前(2022.9.1) 还处于概念设计阶段

身份证编排规则

  • 前 1 - 2 位数字表示:所在省份的代码
  • 第 3 - 4 位数字表示:所在城市的代码
  • 第 5 - 6 位数字表示:所在区县的代码
  • 第 7 - 14 位数字表示:出生年( 4 位)、月( 2 位)、日( 2 位)
  • 第 15 - 16 位数字表示:所在地的派出所的代码
  • 第 17 位数字表示性别:奇数标识男性、偶数表示女性
  • 第 18 位数字表示校验位、用来校验身份证的正确性

上述规则是 18 位身份证的规则相比较 15 位有两个变化:

  1. 出生年区别:18位的是 yyyy、15 位的是 yy
  2. 校验位区别:15 位没有校验位

第18位校验位规则(根据国家标准GB 11643-1999)

  1. 将前面的身份证号码17位数分别乘以不同的系数。从第 1 位到第 17 位的系数分别为 7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2
  2. 将这17位数字和系数相乘的结果相加。
  3. 用加出来和除以11,得出余数
  4. 余数只可能有 0-1-2-3-4-5-6-7-8-9-10 这 11 个数字。
  5. 其分别对应的最后一位身份证的号码为 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];
    }
标签: none

非特殊说明,本博所有文章均为博主原创。

评论啦~



已有 3 条评论


  1. iwyzzyabtu
    iwyzzyabtu

    叼茂SEO.bfbikes.com

    回复 2024-09-23 00:12
  2. xhpcdsfgxq
    xhpcdsfgxq

    想想你的文章写的特别好https://www.jiwenlaw.com/

    回复 2024-09-23 09:58
  3. iwfzaazyzr
    iwfzaazyzr

    叼茂SEO.bfbikes.com

    回复 2024-09-23 16:54