package shengFenYanzheng;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//以上两个包与正则表达式有关
import java.util.zip.Inflater;
public class ShengFenYanZheng {
/*
* 身份证号码验证
* 采用检验地址码,生日码,顺序码,检验码来检验身份证号码的正确性
* 地址码
* 生日码
* 顺序码
* 检验码
*
* 作者: 逗号
* 来源于逗号工作室
*/
private static boolean shuZiYanZheng(String shenFenZheng){
/*
* 数字验证(前十七位本体码必须位整形,且最后一位可能是数字或字符串“x”)
* 返回值是布尔型值yes
* 参数是字符串型身份证号码
*/
boolean yes = false;
if(shenFenZheng.length()==18){
//必须满足十八位
Pattern pattern = Pattern.compile("[0-9]*"); // 全部是数字正则表达式
Matcher isNum = pattern.matcher(shenFenZheng.substring(0, 17));
//前十七位必须全是数字
if(isNum.matches()){
String s = new String("x");
if( s.equals(shenFenZheng.substring(17))||Character.isDigit(shenFenZheng.charAt(17))){
yes = true;
//第十八位只有两种可能,其一是字符串型数字,其二是字符串型的x
}else{
yes = false;
}
}
else{
yes = false;
System.out.println("身份证初步检查出错!");
}
}else{
yes = false;
System.out.println("身份证没有满十八位!");
}
return yes;
}
private static boolean chuShengRiQi(String shenFenZheng){
/*
* 出生日期的有效性验证(满足一定的格式)
* 用来简单验证出生日期的有效性
* 返回值是布尔值
* 参数是字符串型的身份证号码
*/
boolean resulting= false;
Pattern pattern = Pattern.compile("[1-2][0-9]{3}[0-1][0-9][0-3][0-9]");
//正则表达式
Matcher isNum = pattern.matcher(shenFenZheng.substring(6, 14));
//取字符串身份证中的第六到十三位,参与正则表达式的验证
if(isNum.matches()){
resulting = true;
}else{
resulting = false;
System.out.println("出生日期格式初步检查有错!");
}
return resulting ;
}
private static boolean yanZhengMa(String shenFenZheng){
/*
* 验证码验证,通过加权求和,对十一取余后参照验证码字符值得到正确的值
* 与传递过来的字符串中的最后一位对比,返回布尔型的值
* 返回值是布尔型
* 参数值是字符串
*/
boolean result = false;
final int [] jiaQuanYinZi = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1}; //加权因子,为整形
final int [] jianYanMaZiFuZhi = {1,0,'x',9,8,7,6,5,4,3,2};//检验码字符值,为整形
String jianYanMa = "x";//检验码,将这个值与第十八位判等,它为字符串,因为身份证是字符串,初始化之
int yuShu = 0;//余数,是加权之和与11的余数,是检验码的重要依据,初始化之
int sum = 0;//加权之和
for(int i= 0;i<17;i++){
sum += jiaQuanYinZi[i]*Integer.parseInt(shenFenZheng.substring(i, i+1));
//依次将加权因子与通过转整的字符串中的数字相乘,再累加
}
yuShu = sum % 11;//对11取余
//System.out.println(yuShu);通过这句来测试是否正确
jianYanMa = (yuShu==2 ? "x":String.valueOf(jianYanMaZiFuZhi[yuShu]));
//如果是整形值2,则位字符串值x,否则为对应的通过将整形变位字符串的检验码字符值
//System.out.println(jianYanMa);此句用来测试
if(jianYanMa.equals(shenFenZheng.substring(17))){
//如果通过公式得到的正确的检验码与传递过来的身份证字符串的最后一位相等
result = true;
}else{
result = false;
}
return result;
}
private static boolean yanZheng(String shenFenZheng){
/*
* 验证身份证的方法,通过调用数字验证,出生日期验证,验证码验证
* 返回值位布尔型 duiCuo
* 参数是字符串(身份证号码)
*/
boolean duiCuo = false;
if(shuZiYanZheng(shenFenZheng )){
//数字验证
if(chuShengRiQi(shenFenZheng)){
//出生日期有效性的验证
if(yanZhengMa(shenFenZheng)){
//验证码验证
duiCuo = true;
}
else{
duiCuo = false;
System.out.println("验证码没有通过!");
//这些输出在调试程序中很有作用
}
}else{
duiCuo = false;
System.out.println("出生日期没通过!");
}
}else{
duiCuo = false;
System.out.println("数字验证没过关!");
}
return duiCuo;
}
private static String ChaXunChuShengDi(int diZhi) {
/*
* 查询办理身份证地址的方法,一旦通过验证,调用此方法输出
* 返回值是字符串
* 参数是整形,由身份证的前两位而得
*/
String DiZhi = "";
switch (diZhi){
case (11):DiZhi = "北京";break;
case (12):DiZhi = "天津";break;
case (13):DiZhi = "河北";break;
case (14):DiZhi = "山西";break;
case (15):DiZhi = "内蒙古";break;
case (21):DiZhi = "辽宁";break;
case (22):DiZhi = "吉林";break;
case (23):DiZhi = "黑龙江";break;
case (31):DiZhi = "上海";break;
case (32):DiZhi = "江苏";break;
case (33):DiZhi = "浙江";break;
case (34):DiZhi = "安徽";break;
case (35):DiZhi = "福建";break;
case (36):DiZhi = "江西";break;
case (37):DiZhi = "山东";break;
case (41):DiZhi = "河南";break;
case (42):DiZhi = "湖北";break;
case (43):DiZhi = "湖南";break;
case (44):DiZhi = "广东";break;
case (45):DiZhi = "广西";break;
case (46):DiZhi = "海南";break;
case (50):DiZhi = "重庆";break;
case (51):DiZhi = "四川";break;
case (52):DiZhi = "贵州";break;
case (53):DiZhi = "云南";break;
case (54):DiZhi = "西藏";break;
case (61):DiZhi = "陕西";break;
case (62):DiZhi = "甘肃";break;
case (63):DiZhi = "青海";break;
case (64):DiZhi = "宁夏";break;
case (65):DiZhi = "新疆";break;
case (71):DiZhi = "台湾";break;
case (81):DiZhi = "香港";break;
case (82):DiZhi = "澳门";break;
case (91):DiZhi = "国外";break;
default: DiZhi = "不存在!";
break;
}
return DiZhi;
}
private static String shuChuXingBie(String shenFenZheng){
int a = Integer.parseInt(shenFenZheng.substring(16,17));
if(a%2 == 1)
return "男";
else
return "女";
}
public static void main(String[] args) {
String shengFenZheng = new String("430181198803291455");
int xingBie = Integer.parseInt(shengFenZheng.substring(16,17));
//取身份证的倒数第二位字符,它是性别的决定码,奇数为男,偶数为女
if( yanZheng(shengFenZheng)){
//如果验证通过的话,输出地址和性别
int diZhi = new Integer(shengFenZheng.substring(0, 2)).intValue();
//地址码位前六个数,这里只取前两位,将前两位转成整形,传给ChaXunChuShengDi(int diZhi)
System.out.println("此人的身份证有效。");
System.out.println("此人身份证办理地址是:"+ChaXunChuShengDi(diZhi));
System.out.println("性别是:" +shuChuXingBie(shengFenZheng));
}
else {
//如果没通过
System.out.println("此人身份证号码不对!");
}
}
}