程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#實現中國身份證驗證問題

C#實現中國身份證驗證問題

編輯:C#入門知識

C#中國身份證驗證,包括省份驗證和校驗碼驗證,符合GB11643-1999標准...

 

今天寫的

C#中國身份證驗證,包括省份驗證和校驗碼驗證,符合GB11643-1999標准...


理論部分:

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     河南   41     重慶   50  
    甘肅   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


下面是C#的校驗過程:

我將15位和18位的身份證號校驗過程分開了,為了好看。

private bool CheckIDCard(string Id)

{

if (Id.Length == 18)

{

bool check = CheckIDCard18(Id);

return check;

}

else if (Id.Length == 15)

{

bool check = CheckIDCard15(Id);

return check;

}

else

{

return false;

}

}



private bool CheckIDCard18(string Id)

{

long n = 0;

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)

{

return false;//數字驗證

}

string address="11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";

if (address.IndexOf(Id.Remove(2)) == -1)

{

return false;//省份驗證

}

string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");

DateTime time = new DateTime();

if (DateTime.TryParse(birth, out time) == false)

{

return false;//生日驗證

}

string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(,);

string[] Wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(,);

char[] Ai = Id.Remove(17).ToCharArray();

int sum = 0;

for (int i = 0; i < 17; i++)

{

sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString());

}

int y = -1;

Math.DivRem(sum, 11, out y);

if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())

{

return false;//校驗碼驗證

}

return true;//符合GB11643-1999標准

}



private bool CheckIDCard15(string Id)

{

long n = 0;

if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))

{

return false;//數字驗證

}

string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";

if (address.IndexOf(Id.Remove(2)) == -1)

{

return false;//省份驗證

}

string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");

DateTime time = new DateTime();

if (DateTime.TryParse(birth, out time) == false)

{

return false;//生日驗證

}

return true;//符合15位身份證標准

}
注:數據庫是根據中華人民共和國國家統計局截至2003年6月30號的數據,但是之前有修改過的數據,所以,假如是太早頒發的身份證在地區代碼上可能有出入。可以參考國家統計局的數據。


如果有哪裡不妥請提出,我會盡快改進。校驗成功並不能說明是真的身份證號碼,因為市、縣編碼的校驗沒有,也沒能查到含有此編碼的資料。

忽略末尾X的大小寫。用560個身份證號測試,只有2個未通過,應該是身份證號登記錯誤的。驗證過程應該是沒有問題了。

    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved