由于课程设计的缘故,提前做了个身份证查询小工具。
技术含量并不高,"出生日期、性别、年龄"都是根据身份证的算法算出来的,身份证号码18位数对应不同的含义,大家百度查一下即可。
"发证地区"理论上也可以算出来,但是地区数据过于庞大,短时间内写出来是不可能的,看了下java的网络编程和爬虫技术,也参考了网上一些代码,抓取的是ip138的网页,然后返回地区结果。
对于正则表达式和网络编程方面的知识只学了两条天时间,因为还没有深入,正则表达式写得特别烂,但是能正确抓取所要的信息,见谅
GUI方面,为了方便,安装了WindowBuilder插件。
代码引用了两个图片,一个是icon,一个是label定义的背景图片,在此不上传了,大家进行替换或者删减即可
package Idcard;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window.Type;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import javax.swing.JTextField;
import java.awt.Font;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
public class IdIdentify {
private JFrame frame;
private JTextField tf_idInput;
private JLabel lb_background;
private JLabel lb_idTips;
private JLabel lb_birth1;
private JLabel lb_birth2;
private JLabel lb_sex1;
private JLabel lb_sex2;
private JLabel lb_age1;
private JLabel lb_age2;
private JLabel lb_adress1;
private JLabel lb_adress2;
String id_String_18;//身份证最后一位数
int id_int_18;
int[] id_int=new int[17];//身份证前17位
int[] id_digit={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
IdIdentify window = new IdIdentify();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public IdIdentify() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(IdIdentify.class.getResource("/Idcard/icon.png")));
frame.setResizable(false);
frame.setTitle("身份证号码查询工具");
frame.setBounds(100, 100, 571, 405);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
//窗口居中
Toolkit tk=frame.getToolkit();
Dimension dm=tk.getScreenSize();
frame.setLocation((int)(dm.getWidth()-frame.getWidth())/2, (int)(dm.getHeight()-frame.getHeight())/2);
JLabel lb_idNumber = new JLabel("身份证号码:");
lb_idNumber.setForeground(Color.WHITE);
lb_idNumber.setFont(new Font("宋体", Font.BOLD, 20));
lb_idNumber.setBounds(91, 49, 126, 18);
frame.getContentPane().add(lb_idNumber);
tf_idInput = new JTextField();
tf_idInput.setBounds(236, 42, 223, 33);
frame.getContentPane().add(tf_idInput);
tf_idInput.setColumns(10);
//限制输入长度,且只能输入0-9的数字或者大小写X
tf_idInput.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if(e.getKeyChar()==KeyEvent.VK_ENTER){
if(rekonInput()){
if(rekonLastNumber()){
lb_idTips.setText(null);
lb_birth2.setText(getbirthDay());
lb_age2.setText(getAge()+"");
lb_sex2.setText(getSex());
lb_adress2.setText(getIdLocation());
}
else{
lb_idTips.setText("身份证号码有误");
lb_birth2.setText(null);
lb_age2.setText(null);
lb_sex2.setText(null);
lb_adress2.setText(null);
}
}
}
char c=e.getKeyChar();
if(tf_idInput.getText().length()<17){
if(c>'9'||c<'0')
e.consume();
}
else if(tf_idInput.getText().length()==17){
if(!(c=='X'||c=='x'||(c>='0'&&c<='9'))){
e.consume();
}
}
else e.consume();
}
});
tf_idInput.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
rekonInput();
lb_idTips.setText(null);
}
public void focusGained(FocusEvent e) {
lb_idTips.setText(null);
}
});
JButton bt_check = new JButton("查询");
bt_check.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(rekonInput()){
if(rekonLastNumber()){
lb_idTips.setText(null);
lb_birth2.setText(getbirthDay());
lb_age2.setText(getAge()+"");
lb_sex2.setText(getSex());
lb_adress2.setText(getIdLocation());
}
else{
lb_idTips.setText("身份证号码有误");
lb_birth2.setText(null);
lb_age2.setText(null);
lb_sex2.setText(null);
lb_adress2.setText(null);
}
}
}
});
bt_check.setBounds(137, 300, 113, 27);
frame.getContentPane().add(bt_check);
lb_idTips = new JLabel("");
lb_idTips.setFont(new Font("宋体", Font.BOLD, 17));
lb_idTips.setForeground(Color.RED);
lb_idTips.setBounds(236, 76, 240, 24);
frame.getContentPane().add(lb_idTips);
lb_birth1 = new JLabel("出生日期:");
lb_birth1.setForeground(Color.WHITE);
lb_birth1.setFont(new Font("宋体", Font.BOLD, 20));
lb_birth1.setBounds(112, 112, 113, 18);
frame.getContentPane().add(lb_birth1);
lb_birth2 = new JLabel("");
lb_birth2.setForeground(Color.WHITE);
lb_birth2.setFont(new Font("宋体", Font.BOLD, 18));
lb_birth2.setBounds(236, 112, 223, 18);
frame.getContentPane().add(lb_birth2);
lb_sex1 = new JLabel("性 别:");
lb_sex1.setForeground(Color.WHITE);
lb_sex1.setFont(new Font("宋体", Font.BOLD, 20));
lb_sex1.setBounds(110, 152, 113, 18);
frame.getContentPane().add(lb_sex1);
lb_sex2 = new JLabel("");
lb_sex2.setForeground(Color.WHITE);
lb_sex2.setFont(new Font("宋体", Font.BOLD, 18));
lb_sex2.setBounds(236, 152, 223, 18);
frame.getContentPane().add(lb_sex2);
lb_age1 = new JLabel("年 龄:");
lb_age1.setForeground(Color.WHITE);
lb_age1.setFont(new Font("宋体", Font.BOLD, 20));
lb_age1.setBounds(110, 192, 113, 18);
frame.getContentPane().add(lb_age1);
lb_age2 = new JLabel("");
lb_age2.setForeground(Color.WHITE);
lb_age2.setFont(new Font("宋体", Font.BOLD, 18));
lb_age2.setBounds(236, 192, 223, 18);
frame.getContentPane().add(lb_age2);
lb_adress1 = new JLabel("发证地区:");
lb_adress1.setForeground(Color.WHITE);
lb_adress1.setFont(new Font("宋体", Font.BOLD, 20));
lb_adress1.setBounds(112, 232, 113, 18);
frame.getContentPane().add(lb_adress1);
lb_adress2 = new JLabel("");
lb_adress2.setForeground(Color.WHITE);
lb_adress2.setFont(new Font("宋体", Font.BOLD, 18));
lb_adress2.setBounds(236, 232, 315, 18);
frame.getContentPane().add(lb_adress2);
JButton bt_clear = new JButton("\u6E05\u7A7A");
bt_clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tf_idInput.setText(null);
lb_birth2.setText(null);
lb_age2.setText(null);
lb_sex2.setText(null);
lb_adress2.setText(null);
}
});
bt_clear.setBounds(316, 300, 113, 27);
frame.getContentPane().add(bt_clear);
lb_background = new JLabel("");
lb_background.setIcon(new ImageIcon(IdIdentify.class.getResource("/Idcard/background.jpg")));
lb_background.setBounds(0, -21, 573, 398);
frame.getContentPane().add(lb_background);
}
//判断身份证号码最后一位是否正确
public boolean rekonLastNumber(){
int sum=0;
String lastNum="";
for(int i=0;i<id_int.length;i++){
sum+=id_int[i]*id_digit[i];
}
switch(sum%11){
case 0:lastNum="1";break;
case 1:lastNum="0";break;
case 2:lastNum="X";break;
case 3:lastNum="9";break;
case 4:lastNum="8";break;
case 5:lastNum="7";break;
case 6:lastNum="6";break;
case 7:lastNum="5";break;
case 8:lastNum="4";break;
case 9:lastNum="3";break;
case 10:lastNum="2";break;
}
if(lastNum.equalsIgnoreCase(id_String_18))
return true;
else return false;
}
//输入判断
public boolean rekonInput(){
String id=tf_idInput.getText();
if(id.length()!=18){
lb_idTips.setText("输入长度有误!");
lb_birth2.setText(null);
lb_age2.setText(null);
lb_sex2.setText(null);
lb_adress2.setText(null);
return false;
}
else{
String[] id_String=id.split("");//将输入的身份证号转为长度为18的字符串数组
for(int i=0;i<id_String.length;i++){
try{
if(i<17){
id_int[i]=Integer.parseInt(id_String[i]);
}
else{
if(id_String[i].equalsIgnoreCase("X")){
id_String_18=id_String[i].toUpperCase();
}
else{
id_int_18=Integer.parseInt(id_String[i]);
id_String_18=id_String[i].toUpperCase();
}
}
}
catch(NumberFormatException e1){
lb_idTips.setText("请输入正确的身份证号码!");
return false;
}
}
return true;
}
}
//获取出生日期
public String getbirthDay(){
String date=tf_idInput.getText().substring(6, 14);
String year=date.substring(0, 4);
String month=date.substring(4, 6);
String day=date.substring(6, 8);
return year+"年"+month+"月"+day+"日";
}
//获取年龄
public int getAge(){
Calendar c=Calendar.getInstance();
int birth_Year=Integer.parseInt(tf_idInput.getText().substring(6, 10));
return c.get(Calendar.YEAR)-birth_Year;
}
//获取性别
public String getSex(){
int sex=Integer.parseInt(tf_idInput.getText().substring(16,17));
if(sex%2==1) return "男";
else return "女";
}
//爬虫:抓取ip138的查询结果
String getIdLocation(){
String result ="";
try{
URL url = new URL("http://qq.ip138.com/idsearch/index.asp?action=idcard&userid="+tf_idInput.getText());
HttpURLConnection httpuc=(HttpURLConnection)url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(httpuc.getInputStream(),"gb2312")) ;
String html_Content="";
String content;
while((content=br.readLine())!=null){
html_Content+=content;
}
//利用正则表达式获取户籍信息
String regex="\\u53D1 \\u8BC1 \u5730\\uFF1A</td><td class=\"tdc2\">([\u4e00-\u9fa5]*\\s*[\u4e00-\u9fa5]*\\s*[\u4e00-\u9fa5]*\\s*[\u4e00-\u9fa5]*\\s*)";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(html_Content);
if(matcher.find()){
result=matcher.group(1);
}
else result="查询失败";
br.close();
}catch(Exception e){
result="未联网状态下,无法查询发证地区!";
}
return result;
}
}