因項目需要,在綁定銀行卡的時候,需要校驗身份證號碼是否合法,于是去 Google 了一下,現總結如下
18 身份證號碼的結構
公民身份號碼是特征組合碼,由十七位數字本體碼和一位校驗碼組成
排列順序從左至右依次為: 六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位校驗碼
地址碼
表示編碼對象常住戶口所在縣 (市、旗、區) 的行政區劃代碼
最新的行政區劃代碼 在這里
出生日期碼
表示編碼對象出生的年、月、日,年、月、日代碼之間不使用分隔符
順序碼
表示在同一地址碼所標識的區域范圍內,對同年、同月、同日出生的人編定的順序號,順序碼的奇數分配給男性,偶數分配給女性
校驗碼計算步驟
第一步:對十七位數字本體碼加權求和得到 Sum
第二步:對 Sum 取模 11 得到 Y
第四步:根據模 Y ,查找得到對應的校驗碼
簡易代碼如下
public class IdCard {
// 17 位加權因子
private static final int[] RATIO_ARR = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
// 校驗碼列表
private static final char[] CHECK_CODE_LIST = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
private static final int NUM_0 = '0';
private final int ID_LENGTH = 17;
public boolean verifyId18(String idNo) {
if (idNo == null || idNo.isEmpty()) {
return false;
}
idNo = idNo.trim();
if (idNo.length() != 18) {
return false;
}
// 獲取身份證號字符數組
char[] idCharArr = idNo.toCharArray();
// 獲取最后一位(身份證校驗碼)
char verifyCode = idCharArr[ID_LENGTH];
// 身份證號第1-17加權和
int idSum = 0;
// 余數
int residue;
for (int i = 0; i < ID_LENGTH; i++) {
int value = idCharArr[i] - NUM_0;
idSum += value * RATIO_ARR[i];
}
// 取得余數
residue = idSum % 11;
return Character.toUpperCase(verifyCode) == CHECK_CODE_LIST[residue];
}
}
另:15 位身份證出生年份采用年份后 2 位,沒有最后 1 位校驗碼
至于為什么要 mod11 >>>這里<<<