import java.util.Calendar;
import java.util.Scanner;
public class ValidateID {
/*
* 我國現行使用公民身份證號碼有兩種尊循兩個國家標準,〖GB 11643-1989〗和〖GB 11643-1999〗。
* 〖GB 11643-1989〗中規定的是15位身份證號碼:排列順序從左至右依次爲:六位數字地址碼,六位數字出生日期碼,三位數字順序碼,其中出生日期碼不包含世紀數。
* 〖GB 11643-1999〗中規定的是18位身份證號碼:公民身份號碼是特徵組合碼,由十七位數字本體碼和一位數字校驗碼組成。
* 排列順序從左至右依次爲:六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。
* 地址碼:表示編碼對象常住戶口所在縣(市、旗、區)的行政區劃代碼。
* 出生日期碼:表示編碼對象出生的年、月、日,其中年份用四位數字表示,年、月、日之間不用分隔符。
* 順序碼:表示同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人員編定的順序號。
* 順序碼的奇數分給男性,偶數分給女性。
* 校驗碼:是根據前面十七位數字碼,按照ISO 7064:1983.MOD 11-2校驗碼計算出來的檢驗碼。
*/
// 記錄信息
private String info = "地區:";
public static void main(String[] args) {
new ValidateID().validateId();
}
public void validateId() {
System.out.println("輸入身份證號碼:");
Scanner sc = new Scanner(System.in);
String id = sc.nextLine();
// 判斷是不是18位數字
if (id.length() != 18) {
System.out.println("輸入的位數不對");
return;
}
// 如果含有非數字,則直接返回退出
try {
Long.parseLong(id);
} catch (Exception e) {
System.out.println("輸入非數字");
return;
}
// 身份證代表省份的數字
int shengfen = Integer.parseInt(id.substring(0, 2));
//判斷是否有該省份,有則獲得相應信息
if(!isArea(shengfen)){
System.out.println("省份不對");
return;
}
// 獲得身份證年份
int nianfen = Integer.parseInt(id.substring(6, 10));
info += "出生日期:" + nianfen + "年";
// 獲得日期實例
Calendar rightNow = Calendar.getInstance();
// 獲得當前年份
int MaxYear = rightNow.get(Calendar.YEAR);
if ((nianfen < 1949) && (nianfen > MaxYear)) {
System.out.println("年份不對");
return;
}
// 獲得身份證月份
int yuefen = Integer.parseInt(id.substring(10, 12));
info += yuefen + "月";
// 判斷月份是否正確
if ((yuefen <= 0) && (yuefen > 12)) {
System.out.println("月份錯誤");
return;
}
// 獲得身份證日期
int riqi = Integer.parseInt(id.substring(12, 14));
info += riqi + "日";
// 判斷日期是否正確
if (riqi <= 0 && riqi > 31) {
System.out.println("日期錯誤");
return;
}
// 獲得身份證性別數字
int sex = Integer.parseInt(id.substring(16, 17));
// 奇數爲男,偶數爲女
if (sex % 2 == 0) {
info += " 性別:女";
} else {
info += " 性別:男";
}
//調用驗證身份證最後一位校驗碼函數
if (!validateLastNum(id)) {
System.out.println("該身份證未能通過驗證");
return;
}
System.out.println("該身份證通過驗證");
// 打印身份證信息
System.out.println("信息如下");
System.out.println(info);
}
//判斷該省份,並獲得省份信息
public boolean isArea(int shengfen){
// 判斷該省份是否存在,其中下列代碼代表不同省份,可到網上查找獲得
if (!((shengfen == 11) || (shengfen == 12) || (shengfen == 13)
|| (shengfen == 14) || (shengfen == 15) || (shengfen == 21)
|| (shengfen == 22) || (shengfen == 23) || (shengfen == 31)
|| (shengfen == 32) || (shengfen == 33) || (shengfen == 34)
|| (shengfen == 35) || (shengfen == 36) || (shengfen == 37)
|| (shengfen == 41) || (shengfen == 42) || (shengfen == 43)
|| (shengfen == 44) || (shengfen == 45) || (shengfen == 46)
|| (shengfen == 50) || (shengfen == 51) || (shengfen == 52)
|| (shengfen == 53) || (shengfen == 54) || (shengfen == 61)
|| (shengfen == 62) || (shengfen == 63) || (shengfen == 64)
|| (shengfen == 65) || (shengfen == 71) || (shengfen == 81) || (shengfen == 82))) {
System.out.println("省份不對");
return false;
}
if (shengfen == 11) {
info += "北京 ";
}
if (shengfen == 12) {
info += "天津 ";
}
if (shengfen == 13) {
info += "河北 ";
}
if (shengfen == 14) {
info += "山西 ";
}
if (shengfen == 15) {
info += "內蒙古 ";
}
if (shengfen == 21) {
info += "遼寧 ";
}
if (shengfen == 22) {
info += "吉林 ";
}
if (shengfen == 23) {
info += "黑龍江 ";
}
if (shengfen == 31) {
info += "上海 ";
}
if (shengfen == 32) {
info += "江蘇 ";
}
if (shengfen == 33) {
info += "浙江 ";
}
if (shengfen == 34) {
info += "安徽 ";
}
if (shengfen == 35) {
info += "福建 ";
}
if (shengfen == 36) {
info += "江西 ";
}
if (shengfen == 37) {
info += "山東 ";
}
if (shengfen == 41) {
info += "河南 ";
}
if (shengfen == 42) {
info += "湖北 ";
}
if (shengfen == 43) {
info += "湖南 ";
}
if (shengfen == 44) {
info += "廣東 ";
}
if (shengfen == 45) {
info += "廣西壯族自治區 ";
}
if (shengfen == 46) {
info += "海南 ";
}
if (shengfen == 50) {
info += "重慶 ";
}
if (shengfen == 51) {
info += "四川 ";
}
if (shengfen == 52) {
info += "貴州 ";
}
if (shengfen == 53) {
info += "雲南 ";
}
if (shengfen == 54) {
info += "西藏自治區 ";
}
if (shengfen == 61) {
info += "陝西 ";
}
if (shengfen == 62) {
info += "甘肅 ";
}
if (shengfen == 63) {
info += "青海 ";
}
if (shengfen == 64) {
info += "寧夏回族自治區 ";
}
if (shengfen == 65) {
info += "新疆維吾爾族自治區 ";
}
if (shengfen == 71) {
info += "臺灣 ";
}
if (shengfen == 81) {
info += "香港特別行政區 ";
}
if (shengfen == 82) {
info += "澳門特別行政區 ";
}
return true;
}
/*
* 關於身份證號碼最後一位的校驗碼的算法如下: ∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) "*" :
* 表示乘號 i: 表示身份證號碼每一位的序號,從右至左,最左側爲18,最右側爲1。 a[i]: 表示身份證號碼第 i 位上的號碼 W[i]: 表示第
* i 位上的權值 W[i] = 2^(i-1) mod 11 設:R = ∑(a[i]*W[i]) mod 11 ( i = 2, 3, ...,
* 18 ) C = 身份證號碼的校驗碼 則R和C之間的對應關係如下表: R:0 1 2 3 4 5 6 7 8 9 10 C:1 0 X 9 8 7
* 6 5 4 3 2 由此看出 X 就是 10,羅馬數字中的 10 就是X,所以在新標準的身份證號碼中可能含有非數字的字母X。
*/
public boolean validateLastNum(String strId) {
// 判斷身份證是否爲18位
if (strId.length() != 18) {
return false;
}
// 把String轉換爲StringBuffer是爲了用到reverse()方法
StringBuffer sb = new StringBuffer(strId);
// 字符串反轉
sb.reverse();
// 轉回來,便於操作
String id = new String(sb);
// 如果含有非數字,則直接返回false退出
try {
Long.parseLong(id);
} catch (Exception e) {
// System.out.println("該字符串只能是數字");
return false;
}
// 下面算法遵照上面的公式
int sum = 0;
int C = 0;
int[] W = new int[17];
int[] a = new int[17];
for (int i = 2; i < 19; i++) {
W[i - 2] = (int) (Math.pow(2, i - 1) % 11);
a[i - 2] = Integer.parseInt(id.substring(i - 1, i));
sum += (a[i - 2] * W[i - 2]);
}
int R = sum % 11;
// 將上面得到的結果,根據R:C對應關係,做如下轉換
if (R == 0) {
C = 1;
}
if (R == 1) {
C = 0;
}
if (R == 2) {
C = 10;
}
if (R > 2) {
C = 12 - R;
}
// 截取第一個字符,即轉換前的最後一個字符
String lastChar = id.substring(0, 1);
// 將截取的字符轉換成數字
int lastNum = Integer.parseInt(lastChar);
// 判斷身份證的最後個字符和計算得到的數據做比較,如果相等則正確,反之錯誤
if (lastNum != C) {
// 由於R=2對應C=10,而10在身份證中用X表示,所以可通過驗證下面兩個條件是否同時滿足來判斷
if (C == 10 && lastChar.equals("X")) {
// System.out.println("身份證通過校驗碼驗證");
return true;
}
// System.out.println("身份證未能通過校驗碼驗證");
return false;
}
// System.out.println("身份證通過校驗碼驗證");
return true;
}
}
身份驗證之絕對驗證
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.