java 身份证号验证,java身份证校验代码
这篇文章给你带来了一些关于java的知识。很多项目业务都会设计人员信息,所以身份证号是必不可少的核对项目。下面这篇文章主要介绍一些关于JAVA验证身份证号有效性的信息,希望对你有所帮助。
如何解决写爬虫IP受阻的问题?立即使用。
一、身份证结构和形式
在通用身份证号中有15位和18位;
15位身份证号码各位的含义:
1、省、自治区、直辖市代码1-2位;
2、地级市、盟、自治州3-4位代码;
3、5-6位县、县级市、区代码;
4.7-12位数字的出生日期,例如670401代表1967年4月1日,这是与18位数字的第一个区别;
5.数字13-15为顺序号,其中15为男性奇数,女性偶数;
18位身份证号码各位的含义:
1.1-2位数字表示省(自治区、直辖市、特别行政区)。
2、3-4位数字表示城市(地区、自治州、盟、直辖市的市辖区县汇总代码)。其中01-20、51-70为省、直辖市;20-50表示地区(自治州、盟)。
3.5-6位数字表示县(市辖区、县级市、旗)。01-18表示市辖区或地区(自治州、盟)管辖县级市;21-80表示县(旗);81-99指省直管县级市。
4.7-14位[出生日期代码]表示编码对象出生的年月日,其中年份用四位数字表示,年月日之间不使用分隔符。例如,1981年5月11日由1981年5月11日表示。
5.15-17位数字【顺序码】表示地址码所标识区域内同年、月、日出生的人的顺序号。第十七个奇数给男人,偶数给女人。
6.18位[校验码]作为尾号的校验码,由编号单位按照统一公式计算。如果某人的尾号是0-9,那么就不会有X,但是如果尾号是10,那么就要用X来代替,因为如果用10作为尾号,那么这个人的身份证就变成了19位,而19位数字违反了国家标准,中国计算机应用系统是不识别的。是罗马数字10。用X代替10可以保证公民身份证符合国家标准。
:
二、 18位身份证号码计算方法
1.将之前身份证号的17位乘以不同的系数。第一位到第十七位的系数分别是:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
2.将这17位数乘以系数的结果相加。
3.加起来除以11,看看余数是多少?
4.余数只能有0-1-2-3-4-5-6-7-8-9-10这11个数字。最后对应的身份证号码是1-0-X-9-8-7-6-5-4-3-2。
5.从上面可知,如果余数是3,身份证的第18位就会出现9。如果对应的数字是2,身份证的最后一个数字就是罗马数字x。
比如一个男的身份证号是【53010219200508011x】。我们来看看这个ID是不是合法ID。
首先我们得到前17位的乘积和[(57)(39)(010)(15)(08)(24)(12)(91)(26)(03)(07)(59)(010)(85)(08)(14)最后通过对应的规则可以知道余数2对应的校验码是X。所以可以判断这是一个正确的身份证号。
三、JAVA 校验身份证号码
包cn . wje . international;
导入Java . text . date format;
导入Java . text . parse exception;
导入Java . text . simple date format;
导入Java . util . calendar;
导入Java . util . date;
导入Java . util . hashmap;
导入Java . util . map;
导入Java . util . regex . pattern;
/**
* @作者齐峰罗
*/
公共类IdCardUtil {
/**
*数字
*/
public final静态模式编号=Pattern . compile( \ \ d );
/**
*中国公民身份证号码的最小长度。
*/
private static final int CHINA _ ID _ MIN _ LENGTH=15;
/**
*中国公民身份证号码的最大长度。
*/
private static final int CHINA _ ID _ MAX _ LENGTH=18;
公共静态异常isValidatedAllIdcard(字符串id卡)引发异常{
布尔ret=isid卡(身份证);
如果(!ret) {
抛出新异常(身份证格式有误);
}
返回空
}
最后的静态MapInteger,String zoneNum=new HashMap();
/**
* 身份证省份编码
* */
静态{
zoneNum.put(11,北京);
zoneNum.put(12,天津);
zoneNum.put(13,河北);
zoneNum.put(14,山西);
zoneNum.put(15,内蒙古);
zoneNum.put(21,辽宁);
zoneNum.put(22,吉林);
zoneNum.put(23,’黑龙江);
zoneNum.put(31,上海);
zoneNum.put(32,江苏);
zoneNum.put(33,浙江);
zoneNum.put(34,安徽);
zoneNum.put(35,福建);
zoneNum.put(36,江西);
zoneNum.put(37,山东);
zoneNum.put(41,河南);
zoneNum.put(42,湖北);
zoneNum.put(43,湖南);
zoneNum.put(44,广东);
zoneNum.put(45,广西);
zoneNum.put(46,海南);
zoneNum.put(50,重庆);
zoneNum.put(51,四川);
zoneNum.put(52,贵州);
zoneNum.put(53,云南);
zoneNum.put(54,西藏);
zoneNum.put(61,陕西);
zoneNum.put(62,”甘肃);
zoneNum.put(63,青海);
zoneNum.put(64,宁夏);
zoneNum.put(65,新疆);
zoneNum.put(71,台湾);
zoneNum.put(81,香港);
zoneNum.put(82,澳门);
zoneNum.put(91,国外);
}
/**
* 校验码
*/
final static int[] PARITYBIT={ 1 , 0 , X , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 };
/**
* 加权因子wi
*/
最终静态int[] POWER_LIST={ 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 };
/**
* 验证身份证号有效性
*
* @param idCard:身份证号
* @返回真/假
*/
公共静态布尔isIdcard(字符串id卡){
//号码长度应为15位或18位
if(身份证==null (身份证。长度()!=15 idCard.length()!=18)) {
返回错误的
}
//校验区位码
如果(!zonenum。包含键(整数。身份证的价值。substring(0,2))){
返回错误的
}
//校验年份
String year=idCard.length()==15?19 idCard.substring(6,8) : idCard.substring(6,10);
final int iyear=integer。parse int(year);
如果(iyear 1900 iyear日历。getinstance().获取(日历。年份)){
//1900年的通过,超过今年的及格
返回错误的
}
//校验月份
串月=身份证。length()==15?idCard.substring(8,10) : idCard.substring(10,12);
final int imonth=integer。解析int(月);
if (imonth 1 imonth 12) {
返回错误的
}
//校验天数
String day=idCard.length()==15?idCard.substring(10,12) : idCard.substring(12,14);
final int iday=integer。parse int(day);
if (iday 1 iday 31) {
返回错误的
}
//校验一个合法的年月日
如果(!isValidDate(年月日)){
返回错误的
}
//校验位数
int power=0;
最终char[]cs=身份证。图珀案例(1986年).toCharArray();
for(int I=0;cs.lengthi ) {//循环比正则表达式更快
if (i==cs.length - 1 cs[i]==X) {
打破;//最后一位可以是X或者x
}
if (cs[i] 0 cs[i] 9) {
返回错误的
}
如果(计算长度- 1) {
POWER=(cs[I]-0 )* POWER _ LIST[I];
}
}
//校验"校验码"
if (idCard.length()==15) {
返回真实的
}
返回cs[cs。长度-1]==奇偶校验位[幂% 11];
}
/**
* 判断字符串是否为日期格式(合法)
*
* @param inDate:字符串时间
* @返回真/假
*/
验证公共静态布尔值(日期中的字符串){
if (inDate==null) {
返回错误的
}
//或年-月-日
简单日期格式数据格式=新建简单日期格式( yyyyMMdd );
if (inDate.trim().长度()!=dataFormat.toPattern().长度()){
返回错误的
}
//该方法用于设置日历严格解析字符串;默认为没错,宽松解析
数据格式。设置横向(假);
尝试{
数据格式。解析(在日期中。trim());
} catch (ParseException e) {
返回错误的
}
返回真实的
}
/**
* 转换成日期
* @param生日
* @返回
*/
私人静态日期托比什迪(字符串生日){
尝试{
日历日历=日历。getinstance();
日历. set(日历年,Integer.parseInt(生日。子串(0,4));
//月份从0开始,所以减一
日历. set(日历月,Integer.parseInt(生日。子串(4,6))-1);
日历. set(日历. DAY_OF_MONTH,Integer.parseInt(生日。子串(6,8));
//以下设置时分秒,但是对生日的意义不大
日历. set(日历。一天中的小时,0);
日历. set(日历。分钟,0);
日历. set(日历。第二,0);
日历. set(日历。毫秒,0);
返回日历。gettime();
}catch(异常e){
返回空
}
}
/**
* 给定内容是否匹配正则
*
* @param模式模式
* @param内容内容
* @返回正则为空或者则不检查,返回没错,内容为空返回错误的
*/
私有静态布尔isMatch(模式模式,字符序列内容){
if(content==null pattern==null){
//提供空的字符串为不匹配
返回错误的
}
返回模式匹配器(内容)。匹配();
}
/**
* 将字符串转换成指定格式的日期
*
* @param str日期字符串。
* @param日期格式日期格式。如果为空,默认为:yyyy-MM-dd HH:mm:ss
* @返回
*/
私有静态日期strToDate(最终字符串,字符串日期格式){
if (str==null str.trim().length()==0) {
返回空
}
尝试{
if(日期格式==null 日期格式。length()==0){
日期格式= yyyy-MM-DD HH:MM:ss ;
}
日期格式fmt=新的简单日期格式(日期格式);
返回fmt。解析(字符串。trim());
} catch (Exception ex) {
返回空
}
}
/**
* 根据日期获取年
*
* @param date日期
* @返回年的部分
*/
公共静态(同Internationalorganizations)国际组织年(日期日期){
日历ca=日历。getinstance();
ca.setTime(日期);
返回ca.get(日历。年份);
}
/**
* 将力量和值与11取模获得余数进行校验码判断
*
* @param iSum加权和
* @返回校验位
*/
private static char get check code 18(int iSum){
开关(iSum % 11) {
案例10:
返回"2";
案例9:
返回"3";
案例8:
返回"4";
案例7:
返回"5";
案例6:
返回"6";
案例5:
返回"7";
案例4:
返回"8";
案例三:
返回"9";
案例二:
返回”x”;
案例1:
返回"0";
案例0:
返回"1";
默认值:
返回"";
}
}
/**
* 获得18位身份证校验码
* 计算方式:
* 将前面的身份证号码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个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2
* 通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的。如果余数是10,身份证的最后一位号码就是2
* @param code17 18位身份证号中的前17位
* @返回第18位
*/
私有静态字符getCheckCode18(字符串代码17) {
int sum=getPowerSum(代码17。tochararray());
返回get check code 18(sum);
}
/**
* 将身份证的每位和对应位的加权因子相乘之后,再得到和值
*
* @param iArr身份证号码的数组
* @返回身份证编码
*/
private static int getPowerSum(char[]iArr){
int iSum=0;
if(POWER _ list。长度==iarr。长度){
for(int I=0;我很抱歉。长度;i ) {
iSum=整数。(字符串的值。(iArr[I])* POWER _ LIST[I]的值;
}
}
返回理想结构单元法
}
/**
* 将15位身份证号码转换为18位
*
* @param idCard 15位身份编码
* @返回18位身份编码
*/
公共静态字符串转换卡(字符串编号卡){
StringBuilder idCard18
if (idCard.length()!=CHINA_ID_MIN_LENGTH) {
返回空
}
if (isMatch(NUMBERS,idCard)) {
//获取出生年月日
串生日=身份证。子串(6,12);
出生日期=出生日期(生日,‘yyMMdd’);
//获取出生年
int sYear=year(生日);
//理论上2000年之后不存在15位身份证,可以不要此判断
如果(2000年)
sYear-=100;
}
idCard18=新的StringBuilder().append(idCard,0,6).追加(是的).追加(身份证。substring(8));
//获取校验位
char sVal=获取校验码18(身份证18。tostring());
身份证18。append(sVal);
}否则{
返回空
}
返回id卡18。tostring();
}
/**
* 从身份证号码中获取生日
* @param idno
* @返回空表示身份证字号错误,未获取到生日
*/
公共静态日期getBirthDay(字符串idno){
如果(!isIdcard(idno)){
返回空
}
if (idno.length()==15) {
//如果是15位转为18位
idno=convertIdCard(idno);
}
返回到生日(idno。substring(6,14));
}
/**
* 从身份证号码中获取生日
* @param idno
* @返回空表示身份证字号错误,未获取到生日日期格式为:yyyy-MM-dd
*/
公共静态字符串getBirthDayStr(字符串idno){
如果(!isIdcard(idno)){
返回空
}
if (idno.length()==15) {
//如果是15位转为18位
idno=convertIdCard(idno);
}
日期生日=toBirthDay(idno.substring(6,14));
简单日期格式简单日期格式=新建简单日期格式( yyyy-MM-DD );
返回simpleDateFormat.format(生日);
}
/**
* 从身份证号中获取性别
* @param idno
* @return 0:男,1:女,-1:证件号码错误
*/
公共静态字符串getGender(String idno){
如果(!isIdcard(idno)){
return -1 ;
}
if (idno.length()==15) {
//如果是15位转为18位
idno=convertIdCard(idno);
}
//奇男,偶女
return(整数。解析int(idno。substring(16,17)) % 2)==0?1 : 0;
}
/**
* 方法调用测试
* */
公共静态void main(String[] args) {
字符串idc= 130503670401001
//检查身份证是否合规
布尔身份证=isid卡(IDC);
如果(身份证){
System.out.println(身份证号码合规);
//获取身份证号码中的生日
日期生日=获取生日(IDC);
System.out.println(当前身份证的生日为: getBirthDayStr(IDC));
//获取性别
string gender=get gender(IDC);
如果( 0 .等于(性别)){
System.out.println(当前身份证的性别为:男性);
} else if (1 .等于(性别)){
System.out.println(当前身份证的性别为:女性);
}否则{
System.out.println(当前身份证格式不正确);
}
}否则{
System.out.println(身份证格式有误);
}
}
}说明:以上工具中主要的方法是用于测试的,如果放入项目中,不能使用主要的方法测试,可以使用@测试注解测试。此处用主要的方法,只是为了方便贴代码。
结果:
补充:java开发身份证号校验(边输入边校验)
公司最近有个需求,就是边输入边校验身份证号码是否合规。以往的校验都是输完够18位就校验,做起来简单的很,头一次听说要求这样搞的,搞了我一下午。
#代码利用多个正则表达式去校验字符
#判断年月日校验
#大小月校验
#闰年闰月的校验
####以下就是代码部分
/**
* 功能:身份证的有效验证
* @param idStr身份证号
* @返回真实的有效:错误无效
*/
公共静态布尔idcard validate(String idStr){
尝试{
int index=1;
//第一位不能为0
if(idstr。length()=index idstr。的索引( 0 )==0){
返回错误的
}
//地区码
指数;
if (idStr.length()=index) {
哈希表h=geta recode();
if (h.get(idStr.substring(0,index))==null) {
//errorInfo=身份证地区编码错误。;
返回错误的
}
}
//年份
指数=6;
//第一位只能是一和2
如果(!verify(idStr,index,[1,2]){
返回错误的
}
指数;
//第二位跟随第一位只有9或0
如果(!验证(idStr,index,idStr。length()索引idStr。子字符串(6,7).等于( 1 )?[9]:[0])) {
返回错误的
}
指数;
//第三位千禧年后0-?千禧年前0-9
如果(!验证(idStr,index,idStr。length()索引idStr。子字符串(6,7).等于( 1 )?[0-9]:[0-2])) {
返回错误的
}
指数;
//第三位0-9
如果(!verify(idStr,index,[0-9]){
返回错误的
}
if (idStr.length() index) {
//是否比当前年份大
简单日期格式ydf=新建简单日期格式( yyyy );
if (ydf.parse(idStr.substring(6,10)).getTime()新日期()。getTime()) {
返回错误的
}
}
//月份
指数;
//第一位只能是一和0
如果(!verify(idStr,index,[0,1]){
返回错误的
}
指数;
//第二位跟随第一位变化
如果(!验证(idStr,index,idStr。length()索引idStr。substring(索引-1,索引).等于( 1 )?[0-2]:[1-9])) {
返回错误的
}
if (idStr.length() index) {
//是否比当前月份大
简单日期格式ydf=新建简单日期格式( yyyyMM );
if (ydf.parse(idStr.substring(6,12)).getTime()新日期()。getTime()验证月份(idstr。substring(10,12))) {
返回错误的
}
}
//================日份================
指数;
//第一位二月最多是2
如果(!验证(idStr,index,idStr。长度()索引(日月(idStr。substring(10,12))==2)?[0-2]:[0-3])) {
返回错误的
}
指数;
if (idStr.length()index) {
int ten=整数。parse int(idstr。substring(index-1,index));//上一位
字符串筛选器="[0-9]";
开关(日月(idstr。substring(10,12))){
案例1://31天
if(ten==3){
filter="[0,1]";
}
打破;
案例二://2月
if(ten==2){
筛选器="[0-8]";
int year=整数。parse int(idstr。substring(6,10));
//闰年
if(year@0==0 year%4==0){
过滤器="[0-9]";
}
}
打破;
案例3://30天
if(ten==3){
筛选器="[0]";
}
打破;
}
if(ten==0){
filter=[1-9];
}
如果(!verifyIndex(idStr,Index,filter)){
返回错误的
}
}
if (idStr.length() index) {
简单日期格式ydf=新建简单日期格式( yyyyMMdd );
//是否比当前日期大
if (ydf.parse(idStr.substring(6,14)).getTime()新日期()。getTime()) {
返回错误的
}
}
//号码的长度
字符串筛选器="[0-9]{ 0,17 }";
布尔标志=idstr。匹配(过滤器(idstr。length()==18?[0-9,X,X]: ));
如果(!标志){
返回错误的
}
} catch (ParseException e) {
e。printstacktrace();
返回错误的
}
返回真实的
}
/**
*验证
* @param text文本
* @param索引下标
* @param过滤器正则匹配
* @返回
*/
私有静态布尔验证(字符串文本、整数索引、字符串过滤器){
//是否满足长度
if (text.length() index) {
返回验证索引(文本、索引、过滤器);
}
返回真实的
}
/**
*验证
* @param text文本
* @param索引下标
* @param过滤器正则匹配
* @返回
*/
私有静态布尔验证索引(字符串文本、整数索引、字符串过滤器){
String sub=text.substring(index,index 1);
返回子匹配(过滤器);
}
私有静态布尔验证月(字符串月){
返回整数。parse int(month)12;
}
/**
*大小月、二月
* @返回
*/
private static int day month(String month){
开关(整数。解析int(month)){
案例4:
案例6:
案例9:
案例11:
返回3;
情况2:返回2;
默认值:返回1;
}
}
/**
* 功能:设置地区编码
* @返回哈希表对象
*/
私有静态哈希表getarecode(){
哈希表Hashtable=new Hashtable();
hashtable.put(11 ,北京);
hashtable.put(12 ,天津);
hashtable.put(13 ,河北);
hashtable.put(14 ,山西);
hashtable.put(15 ,内蒙古);
hashtable.put(21 ,辽宁);
hashtable.put(22 ,吉林);
hashtable.put(23 ,黑龙江);
hashtable.put(31 ,上海);
hashtable.put(32 ,江苏);
hashtable.put(33 ,浙江);
hashtable.put(34 ,安徽);
hashtable.put(35 ,福建);
hashtable.put(36 ,江
西");
hashtable.put("37", "山东");
hashtable.put("41", "河南");
hashtable.put("42", "湖北");
hashtable.put("43", "湖南");
hashtable.put("44", "广东");
hashtable.put("45", "广西");
hashtable.put("46", "海南");
hashtable.put("50", "重庆");
hashtable.put("51", "四川");
hashtable.put("52", "贵州");
hashtable.put("53", "云南");
hashtable.put("54", "西藏");
hashtable.put("61", "陕西");
hashtable.put("62", "甘肃");
hashtable.put("63", "青海");
hashtable.put("64", "宁夏");
hashtable.put("65", "新疆");
hashtable.put("71", "台湾");
hashtable.put("81", "香港");
hashtable.put("82", "澳门");
hashtable.put("91", "国外");
return hashtable;
}推荐学习:《java视频教程》
以上就是代码实例:JAVA验证身份证号码有效性的详细内容,更多请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。