package com.wxrem.common.http;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Calendar;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author wxb
* 身份证号解析demo
*
* 根据《中华人民共和国国家标准GB 11643-1999》中有关公民身份号码的规定,
* 公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:
* 六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
* 顺序码的奇数分给男性,偶数分给女性。校验码是根据前面十七位数字码,
* 按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
*
* 最后一位:18位数据计算规则:
* 居民身份证是国家法定的证明公民个人身份的有效证件.身份证号码由十七位数字本体码和一位数字校验码组成.
* 第1-6位是地址码,第7-14位是出生日期码,第15-17位是顺序码,即是县、区级政府所辖派出所的分配码.
* 第18位也就是最后一位是数字校验码,是根据前面十七位数字码,按一定规则计算出来的校验码.算法如下:
* 规定第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种情况.其分别对应身份证号码的第18位数字如表所示.
* 余数 0 1 2 3 4 5 6 7 8 9 10
* 第18位 1 0 x 9 8 7 6 5 4 3 2
* 通过上面得知如果余数是3,则身份证的第18位数字就是9.如果余数是2,则身份证的第18位号码就是x.若
* 某人的身份证号码的前17位依次是11010219600302011,则他身份证号码的第18位数字是3.
* @date 2020-08-10 16:13
*/
public class IDCard {
static List<String> allLines = null;
private static int CHINA_ID_MAX_LENGTH;
static {
try {
File directory = new File("src/main/resources/身份证地址码对照表.txt");
String courseFile = directory.getCanonicalPath();
Path p = Paths.get(courseFile);
allLines = Files.readAllLines(p);
}catch (IOException e){
e.printStackTrace();
}
}
/**
* 根据身份编号获取年龄
*
* @param idCard
* 身份编号
* @return 年龄
*/
public static int getAgeByIdCard(String idCard) {
int iAge = 0;
Calendar cal = Calendar.getInstance();
String year = idCard.substring(6, 10);
int iCurrYear = cal.get(Calendar.YEAR);
iAge = iCurrYear - Integer.valueOf(year);
return iAge;
}
/**
* 根据身份编号获取生日
*
* @param idCard 身份编号
* @return 生日(yyyyMMdd)
*/
public static String getBirthByIdCard(String idCard) {
return idCard.substring(6, 14);
}
/**
* 根据身份编号获取生日年
*
* @param idCard 身份编号
* @return 生日(yyyy)
*/
public static Short getYearByIdCard(String idCard) {
return Short.valueOf(idCard.substring(6, 10));
}
/**
* 根据身份编号获取生日月
*
* @param idCard
* 身份编号
* @return 生日(MM)
*/
public static Short getMonthByIdCard(String idCard) {
return Short.valueOf(idCard.substring(10, 12));
}
/**
* 根据身份编号获取生日天
*
* @param idCard
* 身份编号
* @return 生日(dd)
*/
public static Short getDateByIdCard(String idCard) {
return Short.valueOf(idCard.substring(12, 14));
}
/**
* 根据身份编号获取性别
*
* @param idCard 身份编号
* @return 性别(M-男,F-女,N-未知)
*/
public static String getGenderByIdCard(String idCard) {
String sGender = "未知";
String sCardNum = idCard.substring(16, 17);
if (Integer.parseInt(sCardNum) % 2 != 0) {
sGender = "1";//男
} else {
sGender = "2";//女
}
return sGender.equals("1")?"男":"女";
}
public static String getAddressByCardId(String idCard){
String sAddress = "未知";
String sCardNum = idCard.substring(0,6);
Optional<String> firstValue = allLines.stream().filter(line -> line.split(" ")[0].equals(sCardNum)).findFirst();
if (firstValue.isPresent()){
String lineStr= firstValue.get();
if (!lineStr.equals("")) {
sAddress = lineStr.split(" ")[1];
}
}
return sAddress;
}
public static void main(String [] a){
String idcard = "460001199209275127";
String sr = getBirthByIdCard(idcard);
System.out.println("生日:" + sr);
System.out.println("所属地:" + getAddressByCardId(idcard));
String sex = getGenderByIdCard(idcard);
System.out.println("性别:" + sex);
int age = getAgeByIdCard(idcard);
System.out.println("年龄:" + age);
Short nian = getYearByIdCard(idcard);
Short yue = getMonthByIdCard(idcard);
Short ri = getDateByIdCard(idcard);
System.out.print(nian+"年"+yue+"月"+ri+"日");
}
}
生日:19920927
所属地:海南省三亚市通什市
性别:女
年龄:28
1992年9月27日
身份证地址码对照表