java 根据省份证号-判断省份-性别-生日

package com.nf147.manage.Test;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;public class IdcardValidator {private String province;    //省份private String city;        //城市private String region;      //区县private int year;           // 年份private int month;          //月份private int day;            //日期private String gender;      //性别private Date birthday;      //出生日期public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getRegion() {return region;}public void setRegion(String region) {this.region = region;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public IdcardValidator() {}public String toString() {return "省份:" + this.province + "-性别:" + this.gender + ",出生日期:" + new SimpleDateFormat("yyyy-MM-dd").format(this.birthday);}private Map<String, String> cityCodeMap = new HashMap<String, String>() {{this.put("11", "北京");this.put("12", "天津");this.put("13", "河北");this.put("14", "山西");this.put("15", "内蒙古");this.put("21", "辽宁");this.put("22", "吉林");this.put("23", "黑龙江");this.put("31", "上海");this.put("32", "江苏");this.put("33", "浙江");this.put("34", "安徽");this.put("35", "福建");this.put("36", "江西");this.put("37", "山东");this.put("41", "河南");this.put("42", "湖北");this.put("43", "湖南");this.put("44", "广东");this.put("45", "广西");this.put("46", "海南");this.put("50", "重庆");this.put("51", "四川");this.put("52", "贵州");this.put("53", "云南");this.put("54", "西藏");this.put("61", "陕西");this.put("62", "甘肃");this.put("63", "青海");this.put("64", "宁夏");this.put("65", "新疆");this.put("71", "台湾");this.put("81", "香港");this.put("82", "澳门");this.put("91", "国外");}};private IdcardValidator validator = null;/*** 077* 通过构造方法初始化各个成员属性* 078*/public IdcardValidator(String idcard) {try {validator = new IdcardValidator();if (validator.isValidatedAllIdcard(idcard)) {if (idcard.length() == 15) {idcard = validator.convertIdcarBy15bit(idcard);}// 获取省份String provinceId = idcard.substring(0, 2);Set<String> key = this.cityCodeMap.keySet();for (String id : key) {if (id.equals(provinceId)) {this.province = this.cityCodeMap.get(id);break;}}// 获取性别String id17 = idcard.substring(16, 17);if (Integer.parseInt(id17) % 2 != 0) {this.gender = "男";} else {this.gender = "女";}// 获取出生日期String birthday = idcard.substring(6, 14);Date birthdate = new SimpleDateFormat("yyyyMMdd").parse(birthday);this.birthday = birthdate;GregorianCalendar currentDay = new GregorianCalendar();currentDay.setTime(birthdate);this.year = currentDay.get(Calendar.YEAR);this.month = currentDay.get(Calendar.MONTH) + 1;this.day = currentDay.get(Calendar.DAY_OF_MONTH);}} catch (Exception e) {e.printStackTrace();}}protected String codeAndCity[][] = {{"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", "新疆"}, {"71", "台湾"}, {"81", "香港"}, {"82", "澳门"},{"91", "国外"}};private String cityCode[] = {"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", "71", "81", "82", "91"};// 每位加权因子private int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};// 第18位校检码private String verifyCode[] = {"1", "0", "X", "9", "8", "7", "6", "5","4", "3", "2"};/*** 072* 验证所有的身份证的合法性* 073* <p>* 074** @param idcard 075* @return 076*/public boolean isValidatedAllIdcard(String idcard) {if (idcard.length() == 15) {idcard = this.convertIdcarBy15bit(idcard);}return this.isValidate18Idcard(idcard);}/*** 085* <p>* 086* 判断18位身份证的合法性* 087* </p>* 088* 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。* 089* 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。* 090* <p>* 091* 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。* 092* </p>* 093* <p>* 094* 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码;* 095* 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码;* 096* 6.第17位数字表示性别:奇数表示男性,偶数表示女性;* 097* 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。* 098* </p>* 099* <p>* 100* 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4* 101* 2 1 6 3 7 9 10 5 8 4 2* 102* </p>* 103* <p>* 104* 2.将这17位数字和系数相乘的结果相加。* 105* </p>* 106* <p>* 107* 3.用加出来和除以11,看余数是多少?* 108* </p>* 109* 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3* 110* 2。* 111* <p>* 112* 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。* 113* </p>* 114* <p>* 115*/public boolean isValidate18Idcard(String idcard) {// 非18位为假if (idcard.length() != 18) {return false;}// 获取前17位String idcard17 = idcard.substring(0, 17);// 获取第18位String idcard18Code = idcard.substring(17, 18);char c[] = null;String checkCode = "";// 是否都为数字if (isDigital(idcard17)) {c = idcard17.toCharArray();} else {return false;}if (null != c) {int bit[] = new int[idcard17.length()];bit = converCharToInt(c);int sum17 = 0;sum17 = getPowerSum(bit);// 将和值与11取模得到余数进行校验码判断checkCode = getCheckCodeBySum(sum17);if (null == checkCode) {return false;}// 将身份证的第18位与算出来的校码进行匹配,不相等就为假if (!idcard18Code.equalsIgnoreCase(checkCode)) {return false;}}return true;}/*** 159* 验证15位身份证的合法性,该方法验证不准确,最好是将15转为18位后再判断,该类中已提供。* 160* <p>* 161** @param idcard 162* @return 163*/public boolean isValidate15Idcard(String idcard) {// 非15位为假if (idcard.length() != 15) {return false;}// 是否全都为数字if (isDigital(idcard)) {String provinceid = idcard.substring(0, 2);String birthday = idcard.substring(6, 12);int year = Integer.parseInt(idcard.substring(6, 8));int month = Integer.parseInt(idcard.substring(8, 10));int day = Integer.parseInt(idcard.substring(10, 12));// 判断是否为合法的省份boolean flag = false;for (String id : cityCode) {if (id.equals(provinceid)) {flag = true;break;}}if (!flag) {return false;}// 该身份证生出日期在当前日期之后时为假Date birthdate = null;try {birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);} catch (ParseException e) {e.printStackTrace();}if (birthdate == null || new Date().before(birthdate)) {return false;}// 判断是否为合法的年份GregorianCalendar curDay = new GregorianCalendar();int curYear = curDay.get(Calendar.YEAR);int year2bit = Integer.parseInt(String.valueOf(curYear).substring(2));// 判断该年份的两位表示法,小于50的和大于当前年份的,为假if ((year < 50 && year > year2bit)) {return false;}// 判断是否为合法的月份if (month < 1 || month > 12) {return false;}// 判断是否为合法的日期boolean mflag = false;curDay.setTime(birthdate); // 将该身份证的出生日期赋于对象curDayswitch (month) {case 1:case 3:case 5:case 7:case 8:case 10:case 12:mflag = (day >= 1 && day <= 31);break;case 2: // 公历的2月非闰年有28天,闰年的2月是29天。if (curDay.isLeapYear(curDay.get(Calendar.YEAR))) {mflag = (day >= 1 && day <= 29);} else {mflag = (day >= 1 && day <= 28);}break;case 4:case 6:case 9:case 11:mflag = (day >= 1 && day <= 30);break;}if (!mflag) {return false;}} else {return false;}return true;}/*** 253* 将15位的身份证转成18位身份证* 254* <p>* 255** @param idcard 256* @return 257*/public String convertIdcarBy15bit(String idcard) {String idcard17 = null;// 非15位身份证if (idcard.length() != 15) {return null;}if (isDigital(idcard)) {// 获取出生年月日String birthday = idcard.substring(6, 12);Date birthdate = null;try {birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);} catch (ParseException e) {e.printStackTrace();}Calendar cday = Calendar.getInstance();cday.setTime(birthdate);String year = String.valueOf(cday.get(Calendar.YEAR));idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);char c[] = idcard17.toCharArray();String checkCode = "";if (null != c) {int bit[] = new int[idcard17.length()];// 将字符数组转为整型数组bit = converCharToInt(c);int sum17 = 0;sum17 = getPowerSum(bit);// 获取和值与11取模得到余数进行校验码checkCode = getCheckCodeBySum(sum17);// 获取不到校验位if (null == checkCode) {return null;}// 将前17位与第18位校验码拼接idcard17 += checkCode;}} else { // 身份证包含数字return null;}return idcard17;}/*** 308* 15位和18位身份证号码的基本数字和位数验校* 309* <p>* 310** @param idcard 311* @return 312*/public boolean isIdcard(String idcard) {return idcard == null || "".equals(idcard) ? false : Pattern.matches("(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)", idcard);}/*** 319* 15位身份证号码的基本数字和位数验校* 320* <p>* 321** @param idcard 322* @return 323*/public boolean is15Idcard(String idcard) {return idcard == null || "".equals(idcard) ? false : Pattern.matches("^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$",idcard);}/*** 331* 18位身份证号码的基本数字和位数验校* 332* <p>* 333** @param idcard 334* @return 335*/public boolean is18Idcard(String idcard) {return Pattern.matches("^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([\\d|x|X]{1})$",idcard);}/*** 344* 数字验证* 345* <p>* 346** @param str 347* @return 348*/public boolean isDigital(String str) {return str == null || "".equals(str) ? false : str.matches("^[0-9]*$");}/*** 354* 将身份证的每位和对应位的加权因子相乘之后,再得到和值* 355* <p>* 356** @param bit 357* @return 358*/public int getPowerSum(int[] bit) {int sum = 0;if (power.length != bit.length) {return sum;}for (int i = 0; i < bit.length; i++) {for (int j = 0; j < power.length; j++) {if (i == j) {sum = sum + bit[i] * power[j];}}}return sum;}/*** 378* 将和值与11取模得到余数进行校验码判断* 379* <p>* 380** @param checkCode 381* @param sum17     382* @return 校验位* 383*/public String getCheckCodeBySum(int sum17) {String checkCode = null;switch (sum17 % 11) {case 10:checkCode = "2";break;case 9:checkCode = "3";break;case 8:checkCode = "4";break;case 7:checkCode = "5";break;case 6:checkCode = "6";break;case 5:checkCode = "7";break;case 4:checkCode = "8";break;case 3:checkCode = "9";break;case 2:checkCode = "x";break;case 1:checkCode = "0";break;case 0:checkCode = "1";break;}return checkCode;}/*** 将字符数组转为整型数组** @param c* @return 429* @throws NumberFormatException*/public int[] converCharToInt(char[] c) throws NumberFormatException {int[] a = new int[c.length];int k = 0;for (char temp : c) {a[k++] = Integer.parseInt(String.valueOf(temp));}return a;}}

测试:

    public static void main(String[] args) throws Exception {String idcard15 = "370283790911703";//15位String idcard18 = "37078119790127719x";//18位IdcardValidator ie15 = new IdcardValidator(idcard15);IdcardValidator ie18 = new IdcardValidator(idcard18);System.out.println(ie15.toString());System.out.println(ie18.toString());}

结果:

posted @ 2018-12-23 23:57 梓鸿 阅读(...) 评论(...) 编辑 收藏

java 根据省份证号-判断省份-性别-生日相关推荐

  1. js截取字符串的后几位数 省份证号*隐藏

    js截取字符串的后几位数 代码如下: var str="abcdefghhhh";//截取后4位 str.substring(str.length-4): js  *  代替 va ...

  2. 根据省份证号前6位数字生成的三级联动下拉菜单

    <Script language="JavaScript"> // 定义一级数组 var D0=new Array('("北京市","11 ...

  3. 通过身份证号判断是否合法、省份、性别、出生日期、生肖、星座

    由于这个代码有点长,我就不放这里了.要具体代码的可以打开下面这个链接 https://blog.csdn.net/weixin_61961580/article/details/124131596?s ...

  4. python 身份证号的有效性、生日(阴历阳历)、星座、生肖、性别、年龄、户籍所在地测试

    python 身份证号的有效性.生日(阴历阳历).星座.生肖.性别.年龄.户籍所在地测试 0x01 前言 0x02 身份证号码格式 0x03 地区 0x04 代码 0x05 效果 0x01 前言 本项 ...

  5. vue 身份证校验、识别性别/生日/年龄

    vue 身份证格式校验_chen_ai_tao的博客-CSDN博客_vue 身份证校验 Vue中根据输入的身份证号识别年龄.性别_cx&lavender的博客-CSDN博客_vue中根据省份证 ...

  6. java手机号判断运营商_根据手机号 判断省份和运营商

    移动号段: 134 135 136 137 138 139 147 148 150 151 152 157 158 159 165 172 178 182 183 184 187 188 198 联通 ...

  7. mysql 手机号省份_根据手机号 判断省份和运营商

    移动号段: 134 135 136 137 138 139 147 148 150 151 152 157 158 159 165 172 178 182 183 184 187 188 198 联通 ...

  8. 根据身份证号判断性别、年龄、生日

    根据身份证号判断证件持有人的性别.年龄.生日.废话不多说,直接上代码. public class IdentifyCard {private static final Integer[] ODD_NU ...

  9. java通过单号判断快递公司的示例代码

    通过单号判断快递公司的示例代码有很多种,以下是快递100Java智能单号判断功能接入. 不过首先要拿到快递100的测试账号和密钥,获取方式只需要去官网注册后,登录后台进入用户信息模块就能看到了. ht ...

  10. 免费省份证信息归属地查询接口,ASPI,WDL,webservice

    免费使用接口,省份证,归属地,年龄,星座,出生日期,生日,ASPI,WDL,webservice,接口 { "area":"云南省牟定县", "bir ...

最新文章

  1. 语言翻译成汇编语言_学习编程有没有必要从C语言和C++学起?应该怎么学?
  2. 从汗水物流到智慧物流,物流产业智能化
  3. mybatis转义反斜杠_mybatis like 的坑
  4. 设计模式复习-策略模式
  5. 如何修改maven默认jdk配置
  6. Android Gson的使用总结
  7. appium--每次启动会重新安装的问题(没试过)
  8. crontab执行shell脚本日志中出现乱码
  9. 平衡二叉树、二叉排序树-数据结构
  10. SQL Server添加索引
  11. 单击选定单元格后输入新内容_2015年计算机一级msoffice考前简答题练习
  12. AS中突然找不到svn选项了。
  13. 英文pdf翻译为中文(word+google浏览器即可)
  14. 如何突破QQ邮箱超大附件只能下载200次的限制
  15. httpwatch初级使用
  16. 【 MATLAB 】mod 函数介绍
  17. 常用单片机模块(五)
  18. Xcode直接安装ipa
  19. java单词排序_java中实现将输入的单词按首字母排序
  20. SBUF数据缓冲寄存器

热门文章

  1. Linux系统——sqlist数据库
  2. Tarjan 算法解决 LCA 问题
  3. arduino秒退解决方法
  4. 【数学模型】银行贷款计算系统含Matlab源码
  5. 机器学习最常用的算法
  6. Android Studio ADB 命令大全
  7. python数学篇(经典算法题)
  8. 制作一个简单HTML个人网页网页(HTML+CSS)大话西游之大圣娶亲电影网页设计
  9. python词频统计排序小demo
  10. 华为星环大数据_大数据平台-华为和星环