身份证编码规则如下
根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
1、地址码(身份证前六位)表示编码对象第一次申领居民身份证时的常住户口所在县(市、旗、区)的行政区划代码。(所有区域的编码可以到网站查询到最新的县及县以上的行政编码资料);
2、生日期码(身份证第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
3、顺序码(身份证第十五位到十七位)是县、区级政府所辖派出所的分配码,每个派出所分配码为10个连续号码,例如“000-009”或“060-069”,其中单数为男性分配码,双数为女性分配码,如遇同年同月同日有两人以上时顺延第二、第三、第四、第五个分配码;
4、校验码(身份证最后一位)是根据前面十七位数字码,按照ISO7064:1983.MOD11-2校验码计算出来的检验码;
示例身份证号:410426198708273118
[0-1] 41: 河南省
[2-3] 04: 平顶山市
[4-5] 26: 襄城县
[6-9] 1987:出生年份
[10-11] 08: 出生月份
[12-13] 27: 出生日
[14-15] 31: 户籍所在地派出所编码
[16] 1 : 性别、奇数代表男、偶数代表女
[17] 8 : 身份证校验位、标识身份证真假
身份证号算法
十七位数字本体码加权求和公式
S = Sum(Ai * Wi) i = 0, ... , 16
Ai: 表示第 i 位置上的身份证号码数字值(0~9)
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2(表示第 i 位置上的加权因子)
计算模/求余
Y = mod(S, 11)
根据模,查找得到对应的校验码
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
代码主题实现
package com.card;
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.*;
/*
* Created by JFormDesigner on Tue Jun 14 10:48:32 CST 2022
*/
/**
* @author unknown
*/
public class Card extends JFrame {
public Card(String title) {
super(title);
initComponents();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner Evaluation license - unknown
dialogPane = new JPanel();
contentPanel = new JPanel();
label1 = new JLabel();
textField1 = new JTextField();
label2 = new JLabel();
scrollPane1 = new JScrollPane();
textArea1 = new JTextArea();
buttonBar = new JPanel();
okButton = new JButton();
//======== this ========
var contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
//======== dialogPane ========
{
dialogPane.setBorder(new EmptyBorder(12, 12, 12, 12));
dialogPane.setLayout(new BorderLayout());
//======== contentPanel ========
{
contentPanel.setLayout(new GridBagLayout());
((GridBagLayout)contentPanel.getLayout()).columnWidths = new int[] {0, 0, 0, 0};
((GridBagLayout)contentPanel.getLayout()).rowHeights = new int[] {0, 0, 0, 0, 0};
((GridBagLayout)contentPanel.getLayout()).columnWeights = new double[] {0.0, 0.0, 0.0, 1.0E-4};
((GridBagLayout)contentPanel.getLayout()).rowWeights = new double[] {0.0, 0.0, 0.0, 0.0, 1.0E-4};
//---- label1 ----
label1.setText("\u8eab\u4efd\u8bc1\u53f7\uff1a");
contentPanel.add(label1, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
contentPanel.add(textField1, new GridBagConstraints(2, 0, 1, 1, 10.0, 1.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//---- label2 ----
label2.setText("\u5224\u65ad\uff1a");
contentPanel.add(label2, new GridBagConstraints(0, 1, 2, 1, 0.0, 5.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//======== scrollPane1 ========
{
scrollPane1.setViewportView(textArea1);
}
contentPanel.add(scrollPane1, new GridBagConstraints(2, 1, 1, 1, 0.0, 5.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
}
dialogPane.add(contentPanel, BorderLayout.CENTER);
//======== buttonBar ========
{
buttonBar.setBorder(new EmptyBorder(12, 0, 0, 0));
buttonBar.setLayout(new GridBagLayout());
((GridBagLayout)buttonBar.getLayout()).columnWidths = new int[] {0, 80};
((GridBagLayout)buttonBar.getLayout()).columnWeights = new double[] {1.0, 0.0};
//---- okButton ----
okButton.setText("校验");
okButton.addActionListener(this::checkCardNum);
buttonBar.add(okButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
}
dialogPane.add(buttonBar, BorderLayout.SOUTH);
}
setLocationRelativeTo(null);
setSize(400, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.add(dialogPane, BorderLayout.CENTER);
// pack();
// setLocationRelativeTo(getOwner());
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
/**
* 实现身份证校验的方法
* @param actionEvent
*/
private void checkCardNum(ActionEvent actionEvent) {
// 获取 用户 输入的身份证号
String cardNum = textField1.getText();
// 如果 没有输入身份证号
if ("".equals(cardNum)) {
textArea1.setText("");
return ;
}
// 判断 长度 是否是 18 位
if (cardNum.length() != 18) {
textArea1.setText("身份证号%s不正确、期待18位、实际上长度为%d位".formatted(cardNum, cardNum.length()));
return ;
}
// 调用身份证算法、校验身份证号是否合法
if (CardUtils.checkCard(cardNum)) { // 如果身份证校验成功
// 获取 身份证号中的 性别
char sex = cardNum.charAt(16) ;
String sexText = sex % 2 == 1 ? "男" : "女" ;
// 获取 出生日期
String year = cardNum.substring(6, 10) ;
String month = cardNum.substring(10, 12);
String day = cardNum.substring(12,14) ;
// 将 信息 写入到 结果中
textArea1.setText("身份证号%s是真的\n性别是:%s\n出生日期:%s年%s月%s日".formatted(cardNum, sexText, year, month, day));
return ;
}
// 如果 校验失败
textArea1.setText("身份证号是假的");
}
private static int[] w = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
private static char[] sha = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' } ;
public static boolean checkCard(String cardNum) {
if (cardNum.length() !=18) return false ;
int sum = 0 ;
for(int i= 0 ; i < w.length; i++) {
sum += w[i] * (cardNum.charAt(i) - 48 );
}
// 和 11 进行 求余
int index = sum % 11 ;
// 通过程序 计算出来的身份证号的最后以为是
char ln = sha[index] ;
return ln == cardNum.charAt(17) ;
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
// Generated using JFormDesigner Evaluation license - unknown
private JPanel dialogPane;
private JPanel contentPanel;
private JLabel label1;
private JTextField textField1;
private JLabel label2;
private JScrollPane scrollPane1;
private JTextArea textArea1;
private JPanel buttonBar;
private JButton okButton;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
检验身份证号的真假
package com.card;
public class CardUtils {
private static int[] w = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
private static char[] sha = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' } ;
/**
* 用来校验身份证号的真假
* @param cardNum
* @return
*/
public static boolean checkCard(String cardNum) {
if (cardNum.length() !=18) return false ;
int sum = 0 ;
for(int i= 0 ; i < w.length; i++) {
sum += w[i] * (cardNum.charAt(i) - 48 );
}
// 和 11 进行 求余
int index = sum % 11 ;
// 通过程序 计算出来的身份证号的最后以为是
char ln = sha[index] ;
return ln == cardNum.charAt(17) ;
}
}
调用方法
package com.card;
public class CardText {
public static void main(String[] args) {
new Card(" 身份证校验");
}
}
效果图
身份证号正确 显示
如果身份证号不正确 显示