因做專案需要,參考網路資料寫了一個身分證驗證的C#方法,本方法是在VS2005[C/S] 下寫的。
/*
* 理論部分:
* 15位身分證號碼=6位地區代碼+6位生日+3位編號
* 18位身分證號碼=6位地區代碼+8位生日+3位編號+1位檢驗碼
*
* 各省市地區國家代碼前兩位代碼是:
* 北京11 吉林22 福建35 廣東44 雲南53 天津12 黑龍江23 江西36 廣西45 西藏54 河北13 上海31 山東37 海南46 陝西61 山西14 江蘇32 山東37 海南46 陝西61 山西14 江蘇32 河南慶
甘肅62 內蒙古15 浙江33 湖北42 四川51 青海63 遼寧21 安徽34 湖南43 貴州52 寧夏64 新疆65 台灣71 香港81 澳門82 國外91
*18位身分證標準在國家品質技術監督局於1999年7月1日實施的GB11643-1999《公民身份號碼》中做了明確規定。
*GB11643-1999《公民身份號碼》為GB11643-1989《社會安全號碼》的修訂版,其中指出將原標準名稱“社會安全號碼”更名為“公民身份號碼”,另外GB11643-1999《公民身份號碼》從實施之日起代替GB11643-1989。
*公民身份號碼是特徵組合碼,由十七位數本體碼和一位校驗碼組成。排列順序由左至右依序為:六位數字位址碼,八位數字出生日期碼,三位數字順序碼及一位校驗碼。其意義如下:
*1. 位址碼:表示編碼物件常住戶口所在縣(市、旗、區)的行政區劃代碼,依GB/T2260的規定執行。
*2. 出生日期碼:表示編碼對像出生的年、月、日,依GB/T7408的規定執行,年、月、日分別以4位、2位、2位數字表示,之間不用分隔符號。
*3. 順序碼:表示在同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人編定的順序號,順序碼的奇數分配給男性,偶數分配給女性。
*校驗的計算方式:
*1. 對前17位數字本體碼加權求和
*公式為:S = Sum(Ai * Wi), i = 0, ... , 16
*其中Ai表示第i位置上的身分證號碼數字值,Wi表示第i位置上的加權因子,其各位對應的值依序為:
*7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
*2. 以11對計算結果取模
*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
*/
程式碼
1 ///
2 /// 身分證驗證
3 ///
4 /// 身分證號
5 ///
6 public bool CheckIDCard(string Id)
7 {
8 if (Id.Length == 18)
9 {
10 bool check = CheckIDCard18(Id);
11 return check;
12 }
13 else if (Id.Length == 15)
14 {
15 bool check = CheckIDCard15(Id);
16 return check;
17 }
18 else
19 {
20 return false;
21 }
22 }
23 ///
24 /// 18位身分證驗證
25 ///
26 /// 身分證號
27 ///
28 private bool CheckIDCard18(string Id)
29 {
30 long n = 0;
31 if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0') .Replace('X', '0'), out n) == false)
32 {
33 return false;//數字驗證
34 }
35 string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x63x2114x63x2114x85x5x
36 if (address.IndexOf(Id.Remove(2)) == -1)
37 {
38 return false;//省份驗證
39 }
40 string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");
41 DateTime time = new DateTime();
42 if (DateTime.TryParse(birth, out time) == false)
43 {
44 return false;//生日驗證
45 }
46 string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
47 string[] Wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',') ;
48 char[] Ai = Id.Remove(17).ToCharArray();
49 int sum = 0;
50 for (int i = 0; i < 17; i++)
51 {
52 sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString());
53 }
54 int y = -1;
55 Math.DivRem(sum, 11, out y);
56 if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())
57 {
58 return false;//校驗碼驗證
59 }
60 return true;//符合GB11643-1999標準
61 }
62 ///
63 /// 15位身分證驗證
64 ///
65 /// 身分證號
66 ///
67 private bool CheckIDCard15(string Id)
68 {
69 long n = 0;
70 if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))
71 {
72 return false;//數字驗證
73 }
74 string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x63x2114x63x2114x85x5x
75 if (address.IndexOf(Id.Remove(2)) == -1)
76 {
77 return false;//省份驗證
78 }
79 string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");
80 DateTime time = new DateTime();
81 if (DateTime.TryParse(birth, out time) == false)
82 {
83 return false;//生日驗證
84 }
85 return true;//符合15位元身分證標準