天天看點

C# 身份證驗證程式

理論部分:

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 42

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#的校驗過程:

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位身份證标準

        }