感谢b站的穆哥学堂老师

19-验证特定格式(下)_哔哩哔哩_bilibili

/**
     * 身份证号码最后一位的取值数组
     */
    public static final String[] CHECK_CODE_ARR = new String[] {"1","0","X","9","8","7","6","5","4","3","2"};
    /**
     * 身份证号码最后一位数计算的时候的加权因子
     */
    public static final int[] POWER_ID_ARR = new int[] {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    
    /**
     * 身份证号码正则校验
     * 
     * @author zhengzhenglei
     */
    @Test
    public void testIDRegExp() {
        String ID = "a81428198921244532";
        //1、校验前17位为数字,第18位为x或者数字
        boolean flag = Pattern.matches("^\\d{17}[\\dxX]$", ID);
        if(!flag) {
            System.out.println("格式错误1");
            return;
        }
//        2、
//        第1个数字,代表的就是所在的大区,共6大区划,分别如下:
//        1-华北局;2-东北局;3-华东局;4-中南局;5-西南局;6-西北局;
//        中国大陆的公民,目前就排到6,而7是给台湾预留的,8代表香港澳门地区(81-香港,82-澳门),9代表海外地区
//        第2位数字代表大区所在的省份,具体如下:
//        华北:11北京;12天津;13河北;14山西;15内蒙;
//        东北:21辽宁;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新疆。
        String part = ID.substring(0, 2);
        String regexp = "(1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5])";
        flag = part.matches(regexp);
        if(!flag) {
            System.out.println("格式错误2");
            return;
        }
        //3、
//        第3、4位数字表示:所在城市的代码;第5、6位数字表示:所在区县的代码 。这两种代码都不包含00。下面为简易校验,如需详细校验,需要查询三级联动类型的代码集 
        part = ID.substring(2, 4);
        regexp = "0[1-9]|[1-9][0-9]";
        flag = part.matches(regexp);
        if(!flag) {
            System.out.println("格式错误3");
            return;
        }
        //4、
        part = ID.substring(4, 6);
        regexp = "0[1-9]|[1-9][0-9]";
        flag = part.matches(regexp);
        if(!flag) {
            System.out.println("格式错误4");
            return;
        }
        //5、生日部分
        part = ID.substring(6, 14);
        flag = checkBirthDay(part);
        if(!flag) {
            System.out.println("格式错误5");
            return;
        }
        //6
//        身份证最后1位的计算方法
//        明确前提:身份证最左边的数字为第1位
//        计算本体码加权求和值S
//        S=第1位号码*第1位加权因子+第2位号码*第2位加权因子+···+第17位号码*第17位加权因子
//        第n位加权因子 =( 2^18-n)%11【2的(18-n)次方然后再用11求模】,加权因子只与位置有关,故是一组固定数值,即上边所写 POWER_ID_ARR
//        计算校验码数组下标 i= S%11
//        校验码数组["1""0""X""9","8""7""6""5""4""3""2")
//        最后一位字符就是根据计算出的下标取自该数组,该字符叫做身份证的校验码
        flag = checkLast(ID);
        if(!flag) {
            System.out.println("格式错误6");
            return;
        }
        System.out.println("格式正确");
        
    }
    boolean checkLast(String ID) {
        int sum = sumMethod(ID);
        String lastCal = getLastCharFromArr(sum);
        return ID.endsWith(lastCal);
    }
    public int sumMethod(String ID) {
        int sum = 0;
        String str = ID.substring(0, 17);
        for(int i=0;i<str.length();i++) {
            int s = Integer.parseInt(str.substring(i, i+1));
            sum += s*POWER_ID_ARR[i];
        }
        return sum;
    }
    //根据身份证本体码加权求和的值取出最后一个字符
    public String getLastCharFromArr(int sum) {
        return CHECK_CODE_ARR[sum%11];
    }
    //1880-2040
    boolean checkBirthDay(String b) {
        int year = Integer.parseInt(b.substring(0, 4));
        String mStr = b.substring(4, 6);
        int month = Integer.parseInt(mStr);
        int day = Integer.parseInt(b.substring(6));
        if(year<1880 || year>2040) {
            System.out.println("出生年超纲");
            return false;
        }
        if(month<1 || month>12) {
            System.out.println("月份不对");
            return false;
        }
        if(day>31) {
            System.out.println("每月日期不可超过31天");
            return false;
        }
        //1\3\5\7\8\10\12
        if(mStr.matches("04|06|09|11") && day>30) {
            System.out.println("平月日期不可超过30天");
            return false;
        }
        if( month ==2) {
            if(checkYear(year)) {
                if(day>29) {
                    System.out.println("闰年二月日期不可超过29天");
                    return false;
                }
            } else {
                if(day>28) {
                    System.out.println("平年二月日期不可超过28天");
                    return false;
                }
            }
        }
        return true;
    }
    //判断平年闰年,true为闰年,false为平年

//闰年分为普通闰年和世纪闰年,其判断方法为:公历年份是4的倍数,且不是100的倍数,为普通闰年。公历年份是整百数,且必须是400的倍数才是世纪闰年。归结起来就是通常说的:四年一闰;百年不闰,四百年再闰。
    boolean checkYear(int year) {
        if((year%100!=0&& year%4==0)||(year%100==0 && year%400==0)){
            return true;
        }
        return false;
    }

大陆二代居民身份证校验代码相关推荐

  1. 中国大陆18位身份证校验算法(附JS实现)

    大陆18位身份证(第二代身份证)结构:(如下图所示) 身份号码是一组具有特征组合码,由十七位数字本体码和一位校验码组成. 排列顺序从左至右依次为:六位数字地区码,八位数字生日码,三位数字顺序码和一位数 ...

  2. mysql身份证校验码_用sql实现18位身份证校验代码分享 身份证校验位计算

    身份证校验码的计算方法 1.将前面的身份证号码17位数分别乘以不同的系数.第i位对应的数为[2^(18-i)]mod11.从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 ...

  3. 新中新a16d二代居民身份证阅读器Python示例

    为什么80%的码农都做不了架构师?>>>    发现酒店.网吧.公家单位好多都是使用的这种蓝色的身份证读取盒子,所以我研究了一下也写个Python示例 网上搜了搜关于这款机器的SDK ...

  4. 【转】则表达式匹配居民身份证

    http://blog.sina.com.cn/s/blog_491997ee0100avd2.html 简单写法 身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或 ...

  5. 正则表达式匹配居民身份证

    大陆的居民身份证号码有两种:18位和15位,15位的身份证号码是老一代身份证号码. 18位和15位的区别在于两个部分:第一,18位号码的年份以4位计而15位号码的年份为2位,如1987年在18位号码中 ...

  6. 第二代居民身份证安全策略研究

    第二代居民身份证安全策略研究 问题背景 居民身份证是我国能够证明证件持有人身份并可据此从事各种经济社会活动的法定证件.随着社会和技术的发展,原有的第一代居民身份证已不能完全满足现实需要.根据国务院的要 ...

  7. ASP.Net: EshineASPNet教程-身份证校验与正则

    完整教程链接:ASP.Net: EshineASPNet-基于ASP.Net敏捷开发开源框架 很多应用都会涉及到用户身份证的输入,严格的程序并不会接受用户随便输入一串字符,而应该检查身份证是否合法,这 ...

  8. 申请居民身份证网上副本

    from  http://blog.sina.com.cn/s/blog_7ba936790102w0ms.html 居民身份证网上副本是居民身份证在网络上的一种数字存在形式,以居民身份证制证信息为基 ...

  9. 二代身份证编码规则及校验代码实现

    本文主要讨论的是二代身份证编码规则及其Java代码实现,下面的校验方式还不是特别严谨,由于只校验了前两位的省份信息,中间六位的出生日期信息和最后一位的校验码信息,故对于部分不满足要求的证件号码刚好同时 ...

最新文章

  1. yii mysql 事务处理_Yii2中事务的使用实例代码详解
  2. C语言经典例84-一个偶数总能表示为两个素数之和
  3. 一、华为云ModelArts环配置
  4. StroyBoard中UICollectionView中添加Header和footer
  5. linux系统安装arcsde,Linux操作系统安装ArcSDE10
  6. community 计算模块度_燃气模块炉使用信息采集表
  7. LogBack 打印 ES的DSL日志信息
  8. 【快速入门Linux】3_Linux命令—终端命令格式、命令帮助信息、bash标准输入输出
  9. 笨办法学 Python · 续 引言
  10. 马云:用 10% 大脑创造出来的机器不可能毁灭人类
  11. 1.2.4 List.contains方法——判断列表中是否包含指定元素
  12. jar打包 剔除第三方依赖以及它的依赖_spring boot + gradle 打包 bootJar 瘦身分离 lib...
  13. 群晖python导股票数据_群晖系统中运行python爬虫程序
  14. 第二章 一元函数的导数与微分概念及其计算
  15. html5 电子白板 直播,基于HTML5技术的智能终端电子白板软件的设计与实现
  16. SAP PLM CVAPI_DOC_VIEW 获取DMS文档原件URL地址示例(Originals File)
  17. 1-5(中文版)听力积累
  18. 第14章 垃圾回收概述
  19. 讲了这么多年的CPU频率,到底是什么?
  20. mermaid sequenceDiagram使用指南

热门文章

  1. 笔记本光驱在计算机里不显示器,电脑开机硬盘灯一直亮不闪的 光驱没反应显示器不显示 风扇都转的...
  2. Composer开启多线程组件改变composer缓慢问题
  3. 用isalpha函数来判断一个字符串中的字符是否是字母
  4. Redis的内存碎片
  5. windows下cmd命令行显示UTF8字符设置(CHCP命令)
  6. 短信验证码、短信服务商接口---PHP---对接创蓝253云通讯平台
  7. 网站长尾关键词的挖掘与优化
  8. Python鼠标连续点击事件
  9. 三维空间中的旋转--旋转向量
  10. qt在window实现调取本机摄像头或者外设摄像头二维码识别升级版