做項目的時候需要對拿到的數據進行“清洗”,比如剔除一些不可能存在的身份證號碼。查閱了網上的身份證號碼驗證算法,自己也總結一下。
(一)18身份證號碼的結構
公民身份號碼是特征組合碼,由十七位數字本體碼和一位校驗碼組成。
排列順序從左至右依次為:六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位校驗碼。
1、地址碼
表示編碼對象常住戶口所在縣(市、旗、區)的行政區域劃分代碼,按GB/T2260的規定執行。
2、出生日期碼
表示編碼對象出生的年、月、日,按GB/T7408的規定執行,年、月、日代碼之間不用分隔符。
3、順序碼
表示在同一地址碼所標識的區域范圍內,對同年、同月、同日出生的人編定的順序號,順序碼的奇數分配給男性,偶數分配給女性。
4、校驗碼計算步驟
(1)十七位數字本體碼加權求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先對前17位數字的權求和
Ai:表示第i位置上的身份證號碼數字值(0~9)
Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 (表示第i位置上的加權因子)
(2)計算模
Y = mod(S, 11)
(3)根據模,查找得到對應的校驗碼
Y: 0 1 2 3 4 5 6 7 8 9 10
校驗碼: 1 0 X 9 8 7 6 5 4 3 2
(二)根據17位數字本體碼獲取最后一位校驗碼程序實例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class Id18 { int [] weight={ 7 , 9 , 10 , 5 , 8 , 4 , 2 , 1 , 6 , 3 , 7 , 9 , 10 , 5 , 8 , 4 , 2 }; //十七位數字本體碼權重 char [] validate={ '1' , '0' , 'X' , '9' , '8' , '7' , '6' , '5' , '4' , '3' , '2' }; //mod11,對應校驗碼字符值 public char getValidateCode(String id17){ int sum= 0 ; int mode= 0 ; for ( int i= 0 ;i<id17.length();i++){ sum=sum+Integer.parseInt(String.valueOf(id17.charAt(i)))*weight[i]; } mode=sum% 11 ; return validate[mode]; } public static void main(String[] args){ Id18 test= new Id18(); System.out.println( "該身份證驗證碼:" +test.getValidateCode( "14230219700101101" )); //該身份證校驗碼:3 } } |
(三)說明
1.程序可以根據已有的17位數字本體碼,獲取對應的驗證碼。
2.該程序可以剔除驗證碼不正確的身份證號碼。
3.15位的身份證出生年份采用年份后2位,沒有最后1位校驗碼。
4.完整的身份證18位,最后一位校驗位可能是非數字。我們的一個項目,數據庫保存前17位數字,這樣對應一些SQL語句(比如inner join)有加速作用的!!!