Java版通用身份证验证
生活随笔
收集整理的這篇文章主要介紹了
Java版通用身份证验证
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Java版通用身份證驗(yàn)證
轉(zhuǎn)自:此大佬
package com.jdkj.detectSystem.Util;import lombok.SneakyThrows;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;/*** @program: jdkj_detectSystem* @description: 身份證校驗(yàn)* @author: WQ* @create: **/ public class IdCardUtil {/*** <p>* 身份證合法性校驗(yàn)* </p>* <pre>* --15位身份證號(hào)碼:第7、8位為出生年份(兩位數(shù)),第9、10位為出生月份,第11、12位代表出生日期,第15位代表性別,奇數(shù)為男,偶數(shù)為女。* --18位身份證號(hào)碼:第7、8、9、10位為出生年份(四位數(shù)),第11、第12位為出生月份,第13、14位代表出生日期,第17位代表性別,奇數(shù)為男,偶數(shù)為女。* 最后一位為校驗(yàn)位* </pre>* @author WQ*//*** <pre>* 省、直轄市代碼表:* 11 : 北京 12 : 天津 13 : 河北 14 : 山西 15 : 內(nèi)蒙古* 21 : 遼寧 22 : 吉林 23 : 黑龍江 31 : 上海 32 : 江蘇* 33 : 浙江 34 : 安徽 35 : 福建 36 : 江西 37 : 山東* 41 : 河南 42 : 湖北 43 : 湖南 44 : 廣東 45 : 廣西 46 : 海南* 50 : 重慶 51 : 四川 52 : 貴州 53 : 云南 54 : 西藏* 61 : 陜西 62 : 甘肅 63 : 青海 64 : 寧夏 65 : 新疆* 71 : 臺(tái)灣* 81 : 香港 82 : 澳門* 91 : 國(guó)外* </pre>*/private static final String[] cityCode = {"11", "12", "13", "14", "15", "21","22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42","43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62","63", "64", "65", "71", "81", "82", "91"};/*** 每位加權(quán)因子*/private static final int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5,8, 4, 2};/*** 驗(yàn)證所有的身份證的合法性** @param idcard 身份證* @return 合法返回true,否則返回false*/public static boolean isValidatedAllIdcard(String idcard) {if (idcard == null || "".equals(idcard)) {return false;}int s = 15;if (idcard.length() == s) {return validate15IDCard(idcard);}int s1 = 18;if (idcard.length() == s1) {return validate18Idcard(idcard);}return false;}/*** <p>* 判斷18位身份證的合法性* </p>* 根據(jù)〖中華人民共和國(guó)國(guó)家標(biāo)準(zhǔn)GB11643-1999〗中有關(guān)公民身份號(hào)碼的規(guī)定,公民身份號(hào)碼是特征組合碼,由十七位數(shù)字本體碼和一位數(shù)字校驗(yàn)碼組成。* 排列順序從左至右依次為:六位數(shù)字地址碼,八位數(shù)字出生日期碼,三位數(shù)字順序碼和一位數(shù)字校驗(yàn)碼。* <p>* 順序碼: 表示在同一地址碼所標(biāo)識(shí)的區(qū)域范圍內(nèi),對(duì)同年、同月、同 日出生的人編定的順序號(hào),順序碼的奇數(shù)分配給男性,偶數(shù)分配 給女性。* </p>* <p>* 1.前1、2位數(shù)字表示:所在省份的代碼; 2.第3、4位數(shù)字表示:所在城市的代碼; 3.第5、6位數(shù)字表示:所在區(qū)縣的代碼;* 4.第7~14位數(shù)字表示:出生年、月、日; 5.第15、16位數(shù)字表示:所在地的派出所的代碼;* 6.第17位數(shù)字表示性別:奇數(shù)表示男性,偶數(shù)表示女性;* 7.第18位數(shù)字是校檢碼:也有的說(shuō)是個(gè)人信息碼,一般是隨計(jì)算機(jī)的隨機(jī)產(chǎn)生,用來(lái)檢驗(yàn)身份證的正確性。校檢碼可以是0~9的數(shù)字,有時(shí)也用x表示。* </p>* <p>* 第十八位數(shù)字(校驗(yàn)碼)的計(jì)算方法為: 1.將前面的身份證號(hào)碼17位數(shù)分別乘以不同的系數(shù)。從第一位到第十七位的系數(shù)分別為:7 9 10 5 8 4* 2 1 6 3 7 9 10 5 8 4 2* </p>* <p>* 2.將這17位數(shù)字和系數(shù)相乘的結(jié)果相加。* </p>* <p>* 3.用加出來(lái)和除以11,看余數(shù)是多少* </p>* 4.余數(shù)只可能有0 1 2 3 4 5 6 7 8 9 10這11個(gè)數(shù)字。其分別對(duì)應(yīng)的最后一位身份證的號(hào)碼為1 0 X 9 8 7 6 5 4 3* 2。* <p>* 5.通過(guò)上面得知如果余數(shù)是2,就會(huì)在身份證的第18位數(shù)字上出現(xiàn)羅馬數(shù)字的Ⅹ。如果余數(shù)是10,身份證的最后一位號(hào)碼就是2。* </p>** @param idcard* @return*/@SneakyThrowspublic static boolean validate18Idcard(String idcard) {if (idcard == null) {return false;}// 非18位為假int s = 18;if (idcard.length() != s) { // logger.error("身份證位數(shù)不正確!");return false;}// 獲取前17位String idcard17 = idcard.substring(0, 17);// 前17位全部為數(shù)字if (!isDigital(idcard17)) {return false;}String provinceid = idcard.substring(0, 2);// 校驗(yàn)省份if (!checkProvinceid(provinceid)) {return false;}// 校驗(yàn)出生日期String birthday = idcard.substring(6, 14);SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");try {Date birthDate = sdf.parse(birthday);String tmpDate = sdf.format(birthDate);// 出生年月日不正確if (!tmpDate.equals(birthday)) {return false;}} catch (ParseException e1) {return false;}// 獲取第18位String idcard18Code = idcard.substring(17, 18);char c[] = idcard17.toCharArray();int bit[] = converCharToInt(c);int sum17 = 0;sum17 = getPowerSum(bit);// 將和值與11取模得到余數(shù)進(jìn)行校驗(yàn)碼判斷String checkCode = getCheckCodeBySum(sum17);if (null == checkCode) {return false;}// 將身份證的第18位與算出來(lái)的校碼進(jìn)行匹配,不相等就為假if (!idcard18Code.equalsIgnoreCase(checkCode)) {return false;}//System.out.println("正確");return true;}/*** 校驗(yàn)15位身份證** <pre>* 只校驗(yàn)省份和出生年月日* </pre>** @param idcard* @return*/public static boolean validate15IDCard(String idcard) {if (idcard == null) {return false;}// 非15位為假int s = 15;if (idcard.length() != s) {return false;}// 15全部為數(shù)字if (!isDigital(idcard)) {return false;}String provinceid = idcard.substring(0, 2);// 校驗(yàn)省份if (!checkProvinceid(provinceid)) {return false;}String birthday = idcard.substring(6, 12);SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");try {Date birthDate = sdf.parse(birthday);String tmpDate = sdf.format(birthDate);// 身份證日期錯(cuò)誤if (!tmpDate.equals(birthday)) {return false;}} catch (ParseException e1) {return false;}return true;}/*** 將15位的身份證轉(zhuǎn)成18位身份證** @param idcard* @return*/public static String convertIdcarBy15bit(String idcard) {if (idcard == null) {return null;}// 非15位身份證int s = 15;if (idcard.length() != s) {return null;}// 15全部為數(shù)字if (!isDigital(idcard)) {return null;}String provinceid = idcard.substring(0, 2);// 校驗(yàn)省份if (!checkProvinceid(provinceid)) {return null;}String birthday = idcard.substring(6, 12);SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");Date birthdate = null;try {birthdate = sdf.parse(birthday);String tmpDate = sdf.format(birthdate);// 身份證日期錯(cuò)誤if (!tmpDate.equals(birthday)) {return null;}} catch (ParseException e1) {return null;}Calendar cday = Calendar.getInstance();cday.setTime(birthdate);String year = String.valueOf(cday.get(Calendar.YEAR));String idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);char c[] = idcard17.toCharArray();String checkCode = "";// 將字符數(shù)組轉(zhuǎn)為整型數(shù)組int bit[] = converCharToInt(c);int sum17 = 0;sum17 = getPowerSum(bit);// 獲取和值與11取模得到余數(shù)進(jìn)行校驗(yàn)碼checkCode = getCheckCodeBySum(sum17);// 獲取不到校驗(yàn)位if (null == checkCode) {return null;}// 將前17位與第18位校驗(yàn)碼拼接idcard17 += checkCode;return idcard17;}/*** 校驗(yàn)省份** @param provinceid* @return 合法返回TRUE,否則返回FALSE*/private static boolean checkProvinceid(String provinceid) {for (String id : cityCode) {if (id.equals(provinceid)) {return true;}}return false;}/*** 數(shù)字驗(yàn)證** @param str* @return*/private static boolean isDigital(String str) {return str.matches("^[0-9]*$");}/*** 將身份證的每位和對(duì)應(yīng)位的加權(quán)因子相乘之后,再得到和值** @param bit* @return*/private static int getPowerSum(int[] bit) {int sum = 0;if (power.length != bit.length) {return sum;}for (int i = 0; i < bit.length; i++) {for (int j = 0; j < power.length; j++) {if (i == j) {sum = sum + bit[i] * power[j];}}}return sum;}/*** 將和值與11取模得到余數(shù)進(jìn)行校驗(yàn)碼判斷** @param sum17* @return 校驗(yàn)位*/private static String getCheckCodeBySum(int sum17) {String checkCode = null;switch (sum17 % 11) {case 10:checkCode = "2";break;case 9:checkCode = "3";break;case 8:checkCode = "4";break;case 7:checkCode = "5";break;case 6:checkCode = "6";break;case 5:checkCode = "7";break;case 4:checkCode = "8";break;case 3:checkCode = "9";break;case 2:checkCode = "x";break;case 1:checkCode = "0";break;case 0:checkCode = "1";break;default:}return checkCode;}/*** 將字符數(shù)組轉(zhuǎn)為整型數(shù)組** @param c* @return* @throws NumberFormatException*/private static int[] converCharToInt(char[] c) throws NumberFormatException {int[] a = new int[c.length];int k = 0;for (char temp : c) {a[k++] = Integer.parseInt(String.valueOf(temp));}return a;}}?
總結(jié)
以上是生活随笔為你收集整理的Java版通用身份证验证的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: namespace! 报错
- 下一篇: java美元兑换,(Java实现) 美元