比尔云BierYun--阿里云最新优惠活动
阿里云优惠码丨阿里云代金券

根据身份证号,使用Java编写程序获取年龄、性别、出生日期

根据身份证号,使用Java编写程序获取年龄、性别、出生日期

程序员必须要有一个好的思想,代码有时候就体现了一个人的灵魂,所以理解需求比技术更重要!

IdcardValidator类

[java] view plain copy

print?

  1. import java.text.ParseException;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Calendar;
  4. import java.util.Date;
  5. import java.util.GregorianCalendar;
  6. import java.util.regex.Pattern;
  7. public class IdcardValidator {
  8.     /**
  9.      * 省,直辖市代码表: { 11:”北京”,12:”天津”,13:”河北”,14:”山西”,15:”内蒙古”,
  10.      * 21:”辽宁”,22:”吉林”,23:”黑龙江”,31:”上海”,32:”江苏”,
  11.      * 33:”浙江”,34:”安徽”,35:”福建”,36:”江西”,37:”山东”,41:”河南”,
  12.      * 42:”湖北”,43:”湖南”,44:”广东”,45:”广西”,46:”海南”,50:”重庆”,
  13.      * 51:”四川”,52:”贵州”,53:”云南”,54:”西藏”,61:”陕西”,62:”甘肃”,
  14.      * 63:”青海”,64:”宁夏”,65:”新疆”,71:”台湾”,81:”香港”,82:”澳门”,91:”国外”}
  15.      */
  16.     protected String codeAndCity[][] = { { “11”“北京” }, { “12”“天津” },
  17.             { “13”“河北” }, { “14”“山西” }, { “15”“内蒙古” }, { “21”“辽宁” },
  18.             { “22”“吉林” }, { “23”“黑龙江” }, { “31”“上海” }, { “32”“江苏” },
  19.             { “33”“浙江” }, { “34”“安徽” }, { “35”“福建” }, { “36”“江西” },
  20.             { “37”“山东” }, { “41”“河南” }, { “42”“湖北” }, { “43”“湖南” },
  21.             { “44”“广东” }, { “45”“广西” }, { “46”“海南” }, { “50”“重庆” },
  22.             { “51”“四川” }, { “52”“贵州” }, { “53”“云南” }, { “54”“西藏” },
  23.             { “61”“陕西” }, { “62”“甘肃” }, { “63”“青海” }, { “64”“宁夏” },
  24.             { “65”“新疆” }, { “71”“台湾” }, { “81”“香港” }, { “82”“澳门” },
  25.             { “91”“国外” } };
  26.     private String cityCode[] = { “11”“12”“13”“14”“15”“21”“22”,
  27.             “23”“31”“32”“33”“34”“35”“36”“37”“41”“42”“43”,
  28.             “44”“45”“46”“50”“51”“52”“53”“54”“61”“62”“63”,
  29.             “64”“65”“71”“81”“82”“91” };
  30.     // 每位加权因子
  31.     private int power[] = { 7910584216379105842 };
  32.     // 第18位校检码
  33.     private String verifyCode[] = { “1”“0”“X”“9”“8”“7”“6”“5”,
  34.             “4”“3”“2” };
  35.     /**
  36.      * 验证所有的身份证的合法性
  37.      * 
  38.      * @param idcard
  39.      * @return
  40.      */
  41.     public boolean isValidatedAllIdcard(String idcard) {
  42.         if (idcard.length() == 15) {
  43.             idcard = this.convertIdcarBy15bit(idcard);
  44.         }
  45.         return this.isValidate18Idcard(idcard);
  46.     }
  47.     /**
  48.      * <p>
  49.      * 判断18位身份证的合法性
  50.      * </p>
  51.      * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
  52.      * 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
  53.      * <p>
  54.      * 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。
  55.      * </p>
  56.      * <p>
  57.      * 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码;
  58.      * 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码;
  59.      * 6.第17位数字表示性别:奇数表示男性,偶数表示女性;
  60.      * 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。
  61.      * </p>
  62.      * <p>
  63.      * 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4
  64.      * 2 1 6 3 7 9 10 5 8 4 2
  65.      * </p>
  66.      * <p>
  67.      * 2.将这17位数字和系数相乘的结果相加。
  68.      * </p>
  69.      * <p>
  70.      * 3.用加出来和除以11,看余数是多少?
  71.      * </p>
  72.      * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3
  73.      * 2。
  74.      * <p>
  75.      * 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。
  76.      * </p>
  77.      * 
  78.      * @param idcard
  79.      * @return
  80.      */
  81.     public boolean isValidate18Idcard(String idcard) {
  82.         // 非18位为假
  83.         if (idcard.length() != 18) {
  84.             return false;
  85.         }
  86.         // 获取前17位
  87.         String idcard17 = idcard.substring(017);
  88.         // 获取第18位
  89.         String idcard18Code = idcard.substring(1718);
  90.         char c[] = null;
  91.         String checkCode = “”;
  92.         // 是否都为数字
  93.         if (isDigital(idcard17)) {
  94.             c = idcard17.toCharArray();
  95.         } else {
  96.             return false;
  97.         }
  98.         if (null != c) {
  99.             int bit[] = new int[idcard17.length()];
  100.             bit = converCharToInt(c);
  101.             int sum17 = 0;
  102.             sum17 = getPowerSum(bit);
  103.             // 将和值与11取模得到余数进行校验码判断
  104.             checkCode = getCheckCodeBySum(sum17);
  105.             if (null == checkCode) {
  106.                 return false;
  107.             }
  108.             // 将身份证的第18位与算出来的校码进行匹配,不相等就为假
  109.             if (!idcard18Code.equalsIgnoreCase(checkCode)) {
  110.                 return false;
  111.             }
  112.         }
  113.         return true;
  114.     }
  115.     /**
  116.      * 验证15位身份证的合法性,该方法验证不准确,最好是将15转为18位后再判断,该类中已提供。
  117.      * 
  118.      * @param idcard
  119.      * @return
  120.      */
  121.     public boolean isValidate15Idcard(String idcard) {
  122.         // 非15位为假
  123.         if (idcard.length() != 15) {
  124.             return false;
  125.         }
  126.         // 是否全都为数字
  127.         if (isDigital(idcard)) {
  128.             String provinceid = idcard.substring(02);
  129.             String birthday = idcard.substring(612);
  130.             int year = Integer.parseInt(idcard.substring(68));
  131.             int month = Integer.parseInt(idcard.substring(810));
  132.             int day = Integer.parseInt(idcard.substring(1012));
  133.             // 判断是否为合法的省份
  134.             boolean flag = false;
  135.             for (String id : cityCode) {
  136.                 if (id.equals(provinceid)) {
  137.                     flag = true;
  138.                     break;
  139.                 }
  140.             }
  141.             if (!flag) {
  142.                 return false;
  143.             }
  144.             // 该身份证生出日期在当前日期之后时为假
  145.             Date birthdate = null;
  146.             try {
  147.                 birthdate = new SimpleDateFormat(“yyMMdd”).parse(birthday);
  148.             } catch (ParseException e) {
  149.                 e.printStackTrace();
  150.             }
  151.             if (birthdate == null || new Date().before(birthdate)) {
  152.                 return false;
  153.             }
  154.             // 判断是否为合法的年份
  155.             GregorianCalendar curDay = new GregorianCalendar();
  156.             int curYear = curDay.get(Calendar.YEAR);
  157.             int year2bit = Integer.parseInt(String.valueOf(curYear)
  158.                     .substring(2));
  159.             // 判断该年份的两位表示法,小于50的和大于当前年份的,为假
  160.             if ((year < 50 && year > year2bit)) {
  161.                 return false;
  162.             }
  163.             // 判断是否为合法的月份
  164.             if (month < 1 || month > 12) {
  165.                 return false;
  166.             }
  167.             // 判断是否为合法的日期
  168.             boolean mflag = false;
  169.             curDay.setTime(birthdate); // 将该身份证的出生日期赋于对象curDay
  170.             switch (month) {
  171.             case 1:
  172.             case 3:
  173.             case 5:
  174.             case 7:
  175.             case 8:
  176.             case 10:
  177.             case 12:
  178.                 mflag = (day >= 1 && day <= 31);
  179.                 break;
  180.             case 2// 公历的2月非闰年有28天,闰年的2月是29天。
  181.                 if (curDay.isLeapYear(curDay.get(Calendar.YEAR))) {
  182.                     mflag = (day >= 1 && day <= 29);
  183.                 } else {
  184.                     mflag = (day >= 1 && day <= 28);
  185.                 }
  186.                 break;
  187.             case 4:
  188.             case 6:
  189.             case 9:
  190.             case 11:
  191.                 mflag = (day >= 1 && day <= 30);
  192.                 break;
  193.             }
  194.             if (!mflag) {
  195.                 return false;
  196.             }
  197.         } else {
  198.             return false;
  199.         }
  200.         return true;
  201.     }
  202.     /**
  203.      * 将15位的身份证转成18位身份证
  204.      * 
  205.      * @param idcard
  206.      * @return
  207.      */
  208.     public String convertIdcarBy15bit(String idcard) {
  209.         String idcard17 = null;
  210.         // 非15位身份证
  211.         if (idcard.length() != 15) {
  212.             return null;
  213.         }
  214.         if (isDigital(idcard)) {
  215.             // 获取出生年月日
  216.             String birthday = idcard.substring(612);
  217.             Date birthdate = null;
  218.             try {
  219.                 birthdate = new SimpleDateFormat(“yyMMdd”).parse(birthday);
  220.             } catch (ParseException e) {
  221.                 e.printStackTrace();
  222.             }
  223.             Calendar cday = Calendar.getInstance();
  224.             cday.setTime(birthdate);
  225.             String year = String.valueOf(cday.get(Calendar.YEAR));
  226.             idcard17 = idcard.substring(06) + year + idcard.substring(8);
  227.             char c[] = idcard17.toCharArray();
  228.             String checkCode = “”;
  229.             if (null != c) {
  230.                 int bit[] = new int[idcard17.length()];
  231.                 // 将字符数组转为整型数组
  232.                 bit = converCharToInt(c);
  233.                 int sum17 = 0;
  234.                 sum17 = getPowerSum(bit);
  235.                 // 获取和值与11取模得到余数进行校验码
  236.                 checkCode = getCheckCodeBySum(sum17);
  237.                 // 获取不到校验位
  238.                 if (null == checkCode) {
  239.                     return null;
  240.                 }
  241.                 // 将前17位与第18位校验码拼接
  242.                 idcard17 += checkCode;
  243.             }
  244.         } else { // 身份证包含数字
  245.             return null;
  246.         }
  247.         return idcard17;
  248.     }
  249.     /**
  250.      * 15位和18位身份证号码的基本数字和位数验校
  251.      * 
  252.      * @param idcard
  253.      * @return
  254.      */
  255.     public boolean isIdcard(String idcard) {
  256.         return idcard == null || “”.equals(idcard) ? false : Pattern.matches(
  257.                 “(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)”, idcard);
  258.     }
  259.     /**
  260.      * 15位身份证号码的基本数字和位数验校
  261.      * 
  262.      * @param idcard
  263.      * @return
  264.      */
  265.     public boolean is15Idcard(String idcard) {
  266.         return idcard == null || “”.equals(idcard) ? false : Pattern.matches(
  267.                 “^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$”,
  268.                 idcard);
  269.     }
  270.     /**
  271.      * 18位身份证号码的基本数字和位数验校
  272.      * 
  273.      * @param idcard
  274.      * @return
  275.      */
  276.     public boolean is18Idcard(String idcard) {
  277.         return Pattern
  278.                 .matches(
  279.                         “^[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})$”,
  280.                         idcard);
  281.     }
  282.     /**
  283.      * 数字验证
  284.      * 
  285.      * @param str
  286.      * @return
  287.      */
  288.     public boolean isDigital(String str) {
  289.         return str == null || “”.equals(str) ? false : str.matches(“^[0-9]*$”);
  290.     }
  291.     /**
  292.      * 将身份证的每位和对应位的加权因子相乘之后,再得到和值
  293.      * 
  294.      * @param bit
  295.      * @return
  296.      */
  297.     public int getPowerSum(int[] bit) {
  298.         int sum = 0;
  299.         if (power.length != bit.length) {
  300.             return sum;
  301.         }
  302.         for (int i = 0; i < bit.length; i++) {
  303.             for (int j = 0; j < power.length; j++) {
  304.                 if (i == j) {
  305.                     sum = sum + bit[i] * power[j];
  306.                 }
  307.             }
  308.         }
  309.         return sum;
  310.     }
  311.     /**
  312.      * 将和值与11取模得到余数进行校验码判断
  313.      * 
  314.      * @param checkCode
  315.      * @param sum17
  316.      * @return 校验位
  317.      */
  318.     public String getCheckCodeBySum(int sum17) {
  319.         String checkCode = null;
  320.         switch (sum17 % 11) {
  321.         case 10:
  322.             checkCode = “2”;
  323.             break;
  324.         case 9:
  325.             checkCode = “3”;
  326.             break;
  327.         case 8:
  328.             checkCode = “4”;
  329.             break;
  330.         case 7:
  331.             checkCode = “5”;
  332.             break;
  333.         case 6:
  334.             checkCode = “6”;
  335.             break;
  336.         case 5:
  337.             checkCode = “7”;
  338.             break;
  339.         case 4:
  340.             checkCode = “8”;
  341.             break;
  342.         case 3:
  343.             checkCode = “9”;
  344.             break;
  345.         case 2:
  346.             checkCode = “x”;
  347.             break;
  348.         case 1:
  349.             checkCode = “0”;
  350.             break;
  351.         case 0:
  352.             checkCode = “1”;
  353.             break;
  354.         }
  355.         return checkCode;
  356.     }
  357.     /**
  358.      * 将字符数组转为整型数组
  359.      * 
  360.      * @param c
  361.      * @return
  362.      * @throws NumberFormatException
  363.      */
  364.     public int[] converCharToInt(char[] c) throws NumberFormatException {
  365.         int[] a = new int[c.length];
  366.         int k = 0;
  367.         for (char temp : c) {
  368.             a[k++] = Integer.parseInt(String.valueOf(temp));
  369.         }
  370.         return a;
  371.     }
  372.     public static void main(String[] args) throws Exception {
  373.         String idcard15 = “”;
  374.         String idcard18 = “”;
  375.         IdcardValidator iv = new IdcardValidator();
  376.         boolean flag = false;
  377.         flag = iv.isValidate18Idcard(idcard18);
  378.         System.out.println(flag);
  379.         flag = iv.isValidate15Idcard(idcard15);
  380.         System.out.println(flag);
  381.         System.out.println(iv.convertIdcarBy15bit(idcard15));
  382.         flag = iv.isValidate18Idcard(iv.convertIdcarBy15bit(idcard15));
  383.         System.out.println(flag);
  384.         System.out.println(iv.isValidatedAllIdcard(idcard18));
  385.     }
  386. }

IdcardInfoExtractor类:

[java] view plain copy

print?

  1. import java.text.SimpleDateFormat;
  2. import java.util.Calendar;
  3. import java.util.Date;
  4. import java.util.GregorianCalendar;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import java.util.Set;
  8. public class IdcardInfoExtractor {
  9.      // 省份  
  10.     private String province;
  11.     // 城市  
  12.     private String city;
  13.     // 区县  
  14.     private String region;
  15.     // 年份  
  16.     private int year;
  17.     // 月份  
  18.     private int month;
  19.     // 日期  
  20.     private int day;
  21.     // 性别  
  22.     private String gender;
  23.     // 出生日期  
  24.     private Date birthday;
  25.     //年龄
  26.     private int age;
  27.     private Map<String, String> cityCodeMap = new HashMap<String, String>() {
  28.         {
  29.             this.put(“11”“北京”);
  30.             this.put(“12”“天津”);
  31.             this.put(“13”“河北”);
  32.             this.put(“14”“山西”);
  33.             this.put(“15”“内蒙古”);
  34.             this.put(“21”“辽宁”);
  35.             this.put(“22”“吉林”);
  36.             this.put(“23”“黑龙江”);
  37.             this.put(“31”“上海”);
  38.             this.put(“32”“江苏”);
  39.             this.put(“33”“浙江”);
  40.             this.put(“34”“安徽”);
  41.             this.put(“35”“福建”);
  42.             this.put(“36”“江西”);
  43.             this.put(“37”“山东”);
  44.             this.put(“41”“河南”);
  45.             this.put(“42”“湖北”);
  46.             this.put(“43”“湖南”);
  47.             this.put(“44”“广东”);
  48.             this.put(“45”“广西”);
  49.             this.put(“46”“海南”);
  50.             this.put(“50”“重庆”);
  51.             this.put(“51”“四川”);
  52.             this.put(“52”“贵州”);
  53.             this.put(“53”“云南”);
  54.             this.put(“54”“西藏”);
  55.             this.put(“61”“陕西”);
  56.             this.put(“62”“甘肃”);
  57.             this.put(“63”“青海”);
  58.             this.put(“64”“宁夏”);
  59.             this.put(“65”“新疆”);
  60.             this.put(“71”“台湾”);
  61.             this.put(“81”“香港”);
  62.             this.put(“82”“澳门”);
  63.             this.put(“91”“国外”);
  64.         }
  65.     };
  66.     private IdcardValidator validator = null;
  67.     /** 
  68.      * 通过构造方法初始化各个成员属性 
  69.      */
  70.     public IdcardInfoExtractor(String idcard) {
  71.         try {
  72.             validator = new IdcardValidator();
  73.             if (validator.isValidatedAllIdcard(idcard)) {
  74.                 if (idcard.length() == 15) {
  75.                     idcard = validator.convertIdcarBy15bit(idcard);
  76.                 }
  77.                 // 获取省份  
  78.                 String provinceId = idcard.substring(02);
  79.                 Set<String> key = this.cityCodeMap.keySet();
  80.                 for (String id : key) {
  81.                     if (id.equals(provinceId)) {
  82.                         this.province = this.cityCodeMap.get(id);
  83.                         break;
  84.                     }
  85.                 }
  86.                 // 获取性别  
  87.                 String id17 = idcard.substring(1617);
  88.                 if (Integer.parseInt(id17) % 2 != 0) {
  89.                     this.gender = “男”;
  90.                 } else {
  91.                     this.gender = “女”;
  92.                 }
  93.                 // 获取出生日期  
  94.                 String birthday = idcard.substring(614);
  95.                 Date birthdate = new SimpleDateFormat(“yyyyMMdd”)
  96.                         .parse(birthday);
  97.                 this.birthday = birthdate;
  98.                 GregorianCalendar currentDay = new GregorianCalendar();
  99.                 currentDay.setTime(birthdate);
  100.                 this.year = currentDay.get(Calendar.YEAR);
  101.                 this.month = currentDay.get(Calendar.MONTH) + 1;
  102.                 this.day = currentDay.get(Calendar.DAY_OF_MONTH);
  103.                 //获取年龄
  104.                 SimpleDateFormat simpleDateFormat=new SimpleDateFormat(“yyyy”);
  105.                 String year=simpleDateFormat.format(new Date());
  106.                 this.age=Integer.parseInt(year)-this.year;
  107.             }
  108.         } catch (Exception e) {
  109.             e.printStackTrace();
  110.         }
  111.     }
  112.     /** 
  113.      * @return the province 
  114.      */
  115.     public String getProvince() {
  116.         return province;
  117.     }
  118.     /** 
  119.      * @return the city 
  120.      */
  121.     public String getCity() {
  122.         return city;
  123.     }
  124.     /** 
  125.      * @return the region 
  126.      */
  127.     public String getRegion() {
  128.         return region;
  129.     }
  130.     /** 
  131.      * @return the year 
  132.      */
  133.     public int getYear() {
  134.         return year;
  135.     }
  136.     /** 
  137.      * @return the month 
  138.      */
  139.     public int getMonth() {
  140.         return month;
  141.     }
  142.     /** 
  143.      * @return the day 
  144.      */
  145.     public int getDay() {
  146.         return day;
  147.     }
  148.     /** 
  149.      * @return the gender 
  150.      */
  151.     public String getGender() {
  152.         return gender;
  153.     }
  154.     /** 
  155.      * @return the birthday 
  156.      */
  157.     public Date getBirthday() {
  158.         return birthday;
  159.     }
  160.     @Override
  161.     public String toString() {
  162.         return “省份:” + this.province + “,性别:” + this.gender + “,出生日期:”
  163.                 + this.birthday;
  164.     }
  165.     public static void main(String[] args) {
  166.         String idcard = “”;
  167.         IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
  168.         System.out.println(ie.toString());
  169.     }
  170.     public int getAge() {
  171.         return age;
  172.     }
  173.     public void setAge(int age) {
  174.         this.age = age;
  175.     }
  176. }

测试类:

[java] view plain copy

print?

  1. import java.util.Date;
  2. public class Test {
  3.     public static void main(String[] args) {
  4.         IdcardInfoExtractor idcardInfo=new IdcardInfoExtractor(“372323199001061825”);
  5.         System.out.println(“出生日期:”+idcardInfo.getYear()+“-“+idcardInfo.getMonth()+“-“+idcardInfo.getDay());
  6.         System.out.println(“性别:”+idcardInfo.getGender());
  7.         System.out.println(“年龄:”+idcardInfo.getAge());
  8.         System.out.println(“省份:”+idcardInfo.getProvince());
  9.     }
  10. }

 

未经允许不得转载:比尔云 » 根据身份证号,使用Java编写程序获取年龄、性别、出生日期
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

强烈推荐

高性能SSD云服务器ECS抗攻击,高可用云数据库RDS