身份證的驗證無非就是長度地區碼的驗證。關鍵是有一部分的軟件沒有實現對最後一位校驗碼的校驗。這裏主要說這個,也算mark一下。其中最重要的就是最後一位校驗位的計算。其過程如圖:
他的公式是:
一句話就是前17位與其權重(權重:2的i次冪除以11的餘數,i爲從1開始的位置序號)乘積的和相對於11的餘數。
下邊再貼一下JAVA的代碼(此代碼來源於網絡,但是我去除了其他的驗證,文末會貼出其地址):
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
/**
* 身份證驗證的工具(支持5位或18位省份證) 身份證號碼結構: 17位數字和1位校驗碼:6位地址碼數字,8位生日數字,3位出生時間順序號,1位校驗碼。
* 地址碼(前6位):表示對象常住戶口所在縣(市、鎮、區)的行政區劃代碼,按GB/T2260的規定執行。 出生日期碼,(第七位
* 至十四位):表示編碼對象出生年、月、日,按GB按GB/T7408的規定執行,年、月、日代碼之間不用分隔符。
* 順序碼(第十五位至十七位):表示在同一地址碼所標示的區域範圍內,對同年、同月、同日出生的人編訂的順序號, 順序碼的奇數分配給男性,偶數分配給女性。
* 校驗碼(第十八位數): 十七位數字本體碼加權求和公式 s = sum(Ai*Wi), i = 0,,16,先對前17位數字的權求和;
* Ai:表示第i位置上的身份證號碼數字值.Wi:表示第i位置上的加權因.Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2;
* 計算模 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
*/
public class IDCardUtil {
final static int[] PARITYBIT = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
final static int[] POWER_LIST = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
/**
*
* 身份證校驗位驗證
*
*/
public static boolean isIDCard(String certNo) {
if (certNo == null || (certNo.length() != 15 && certNo.length() != 18))
return false;
final char[] cs = certNo.toUpperCase().toCharArray();
// 校驗位數
int power = 0;
for (int i = 0; i < cs.length; i++) {
if (i == cs.length - 1 && cs[i] == 'X')
break;// 最後一位可以 是X或x
if (cs[i] < '0' || cs[i] > '9')
return false;
if (i < cs.length - 1) {
power += (cs[i] - '0') * POWER_LIST[i];
}
}
return cs[cs.length - 1] == PARITYBIT[power % 11];
}
public static void main(String[] args) {
boolean mark = isIDCard("你的身份證");
System.out.println(mark);
}
}
)
最後貼一下所借鑑內容的地址:
代碼:https://www.oschina.net/code/snippet_1859292_39120。
圖片:http://jingyan.baidu.com/album/7f41ececff944a593d095c8c.html?picindex=5。
這篇博客MARK 的意味很強,希望也可以幫到一些剛接觸程序的新人。