输入身份证号,判断其地区、出生年月日、性别

一、首先弄清楚一些东西:

15位的旧身份证,最后一个数是单数的为男,双数的为女

18位的新身份证,倒数第二位是单数的为男,双数的为女。

校验的计算方式:

  1. 对前17位数字本体码加权求和

  公式为:S = Sum(Ai * Wi),  i = 0, ... , 16

  其中Ai表示第i位置上的身份证号码数字值,Wi表示第i位置上的加权因子,其各位对应的值依次为: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

  2. 以11对计算结果取模

  Y = mod(S, 11)

  3. 根据模的值得到对应的校验码

  对应关系为:

    Y值: 0 1 2 3 4 5 6 7 8 9 10

  校验码: 1 0 X 9 8 7 6 5 4 3 2


二、怎么得到出生地区?

因为身份证前6位代表的是其出生地方,而且都有一一对应的关系,所以直接拿着去比对就可以。

三、代码实现

package j8;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

public class IdCardParser {

	public static void main(String[] args) {
		try {
			System.out.println("请输入您要查询的身份证号码:");
			InputStreamReader reader = new InputStreamReader(System.in);
			String str = new BufferedReader(reader).readLine();
			IdCard ic = IdCardParser.parse(str);
			if(ic != null){
				System.out.println(ic);
			}else{
				System.out.println("您输入的有误");
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static final byte[] factor = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9,
			10, 5, 8, 4, 2, 1 };
	private static final char[] ch = { '1', '0', 'X', '9', '8', '7', '6', '5',
			'4', '3', '2' };

	/**
	 * 15位身份证转18位身份证.失败返回null
	 * 
	 * @param $15
	 * @return
	 */
	private static String $15to18(String $15) {
		if ($15 == null) {
			return null;
		}
		if ($15.length() == 18) {
			return $15;
		}
		if ($15.length() != 15) {
			return null;
		}
		StringBuilder sb = new StringBuilder($15);
		sb.insert(6, "19");// 加入年两位
		int result = 0;
		for (int i = 0; i < sb.length(); i++) {
			result += (Integer.parseInt(sb.charAt(i) + "")) * factor[i];
		}
		return sb.append(ch[result % 11]).toString();// 加入效验码
	}

	/**
	 * 验证第18位效验码
	 * 
	 * @param idCardNumber
	 * @return
	 */
	private static boolean check18(String idCardNumber) {
		if (idCardNumber == null || idCardNumber.length() != 18) {
			return false;
		}
		int result = 0;
		for (int i = 0; i < idCardNumber.length() - 1; i++) {
			result += (Integer.parseInt(idCardNumber.charAt(i) + ""))
					* factor[i];
		}
		return ch[result % 11] == idCardNumber.charAt(17);
	}

	/**
	 * 验证出生日期是否合法
	 * 
	 * @param idCardNumber
	 * @return
	 */
	private static boolean checkBirthDay(int year, int month, int day) {
		if (year < 1900 || year > 2013) {
			return false;
		}
		if (month > 12 || month < 1) {
			return false;
		}
		if (day < 1) {
			return false;
		}
		byte[] dayOfMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
			dayOfMonth[1] = 29;
		}
		return day <= dayOfMonth[month - 1];
	}

	public static IdCard parse(String idCardNumber) {
		// 检查字符串
		if (!idCardNumber.matches("\\d{15}|\\d{18}|\\d{17}(?i)X")) {
			return null;
		}
		IdCard ic = new IdCard();
		// 15->18
		idCardNumber = $15to18(idCardNumber);
		// 检查效验码
		if (idCardNumber == null || !check18(idCardNumber)) {
			return null;
		}
		// 检查出生年月
		int year = Integer.parseInt(idCardNumber.substring(6, 10));
		int month = Integer.parseInt(idCardNumber.substring(10, 12));
		int day = Integer.parseInt(idCardNumber.substring(12, 14));
		if (!checkBirthDay(year, month, day)) {
			return null;
		}
		ic.setNumber(idCardNumber);
		// 查询身份证归属地
		ic.setAddress(info.getProperty(idCardNumber.substring(0, 6)));
		ic.setBirthday(String.format("%d-%d-%d",year, month, day));
		ic.setSex(1 == (Integer.parseInt(idCardNumber.charAt(16) + "") & 1));
		return ic;
	}

	private static final Properties info;
	static {
		info = new Properties();
		try {
			info.load(new InputStreamReader(new FileInputStream(
					"IdCard.properties"), "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

身份证实体类:

package j8;


public class IdCard {
	
	private String number;
	private String address;
	private String birthday;
	private boolean sex;//true男.false女
	
	public IdCard(){
		
	}
	
	public IdCard(String number, String address, String birthday, boolean sex) {
		this.number = number;
		this.address = address;
		this.birthday = birthday;
		this.sex = sex;
	}
	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}
	public boolean isSex() {
		return sex;
	}
	public void setSex(boolean sex) {
		this.sex = sex;
	}
	
	public String toString(){
		return String.format("[号码:%s,地址:%s,出生:%s,性别:%s]",number,address,birthday,sex ? '男' : '女');
	}
	
}

四、结果



五、源代码下载地址:下载地址

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值