c#實現的18位身份證格式驗證算法
18位身份證標準在國家質量技術監督局於1999年7月1日實施的GB11643-1999《公民身份號碼》中做了明確的規定。 GB11643-1999《公民身份號碼》爲GB11643-1989《社會保障號碼》的修訂版,其中指出將原標準名稱"社會保障號碼"更名爲"公民身份號碼",另外GB11643-1999《公民身份號碼》從實施之日起代替GB11643-1989。GB11643-1999《公民身份號碼》主要內容如下:
一、範圍
該標準規定了公民身份號碼的編碼對象、號碼的結構和表現形式,使每個編碼對象獲得一個唯一的、不變的法定號碼。
二、編碼對象
公民身份號碼的編碼對象是具有中華人民共和國國籍的公民。
三、號碼的結構和表示形式
1、號碼的結構
公民身份號碼是特徵組合碼,由十七位數字本體碼和一位校驗碼組成。排列順序從左至右依次爲:六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。
2、地址碼
表示編碼對象常住戶口所在縣(市、旗、區)的行政區劃代碼,按GB/T2260的規定執行。
3、出生日期碼
表示編碼對象出生的年、月、日,按GB/T7408的規定執行,年、月、日代碼之間不用分隔符。
4、順序碼
表示在同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人編定的順序號,順序碼的奇數分配給男性,偶數分配給女性。
5、校驗碼
(1)十七位數字本體碼加權求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先對前17位數字的權求和
Ai:表示第i位置上的身份證號碼數字值
Wi:表示第i位置上的加權因子
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(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
四、舉例如下:
北京市朝陽區: 11010519491231002X
廣東省汕頭市: 440524188001010014
根據〖中華人民共和國國家標準 GB 11643-1999〗中有關公民身份號碼的規定,公民身份號碼是特徵組合碼,由十七位數字本體碼和一位數字校驗碼組成。排列順序從左至右依次爲:六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。
地址碼錶示編碼對象常住戶口所在縣(市、旗、區)的行政區劃代碼。生日期碼錶示編碼對象出生的年、月、日,其中年份用四位數字表示,年、月、日之間不用分隔符。順序碼錶示同一地址碼所標識的區域範圍內,對同年、月、日出生的人員編定的順序號。順序碼的奇數分給男性,偶數分給女性。校驗碼是根據前面十七位數字碼,按照ISO 7064:1983.MOD 11-2校驗碼計算出來的檢驗碼。下面舉例說明該計算方法。
15位的身份證編碼首先把出生年擴展爲4位,簡單的就是增加一個19,但是這對於1900年出生的人不使用(這樣的壽星不多了)
某男性公民身份號碼本體碼爲34052419800101001,首先按照公式⑴計算:
∑(ai×Wi)(mod 11)……………………………………(1)
公式(1)中:
i----表示號碼字符從由至左包括校驗碼在內的位置序號;
ai----表示第i位置上的號碼字符值;
Wi----示第i位置上的加權因子,其數值依據公式Wi=2(n-1)(mod 11)計算得出。
i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
ai 3 4 0 5 2 4 1 9 8 0 0 1 0 1 0 0 1 a1
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
ai×Wi 21 36 0 25 16 16 2 9 48 0 0 9 0 5 0 0 2 a1
根據公式(1)進行計算:
∑(ai×Wi) =(21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189
189 ÷ 11 = 17 + 2/11
∑(ai×Wi)(mod 11) = 2
然後根據計算的結果,從下面的表中查出相應的校驗碼,其中X表示計算結果爲10:
∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
校驗碼字符值ai 1 0 X 9 8 7 6 5 4 3 2
根據上表,查出計算結果爲2的校驗碼爲所以該人員的公民身份號碼應該爲 34052419800101001X。
以上是轉載的(sorry忘了哪裏找過來的),以下是根據原文寫的一個校驗類,並自動將15位轉換成18位.
CODE(C#)
using System;
using System.Text;
using System.Text.RegularExpressions;
namespace Leisang
{
/// <summary>
/// CID 的摘要說明。
/// </summary>
public class IdentityCard
{
private string cid_;
private string errmsg;
private string[] aCity;
public IdentityCard()
{
aCity = new string[]{null,null,null,null,null,null,null,null,null,null,null,
"北京","天津 ","河北","山西","內蒙古",
null,null,null,null,null,
"遼寧","吉林","黑龍江",
null,null, null,null,null,null,null,
"上海","江蘇","浙江","安微","福建","江西","山東",
null,null, null,
"河南","湖北","湖南","廣東","廣西","海南",
null,null,null,
"重慶","四川","貴州","雲南","西藏",
null,null,null,null,null,null,
"陝西","甘肅","青海","寧夏","新疆",
null,null, null,null,null,
"臺灣",
null,null,null,null,null,null,null,null,null,
"香港","澳門",
null,null,null,null,null,null,null,null,
"國外"};
}
public bool Check(string CardID)
{
CID=CardID;
return Check();
}
public bool Check()
{
//判斷位數
if(CID.Length==15)
{
return Check15();
}
else if(CID.Length==18)
{
return Check18(CID);
}
else
{
ErrMsg="身份證位數不正確";
return false;
}
}
public bool Check18(string cid)
{
double iSum=0;
//string info="";
System.Text.RegularExpressions.Regex rg = new System.Text.RegularExpressions.Regex(@"^/d{17}(/d|x)$");
System.Text.RegularExpressions.Match mc = rg.Match(cid);
if(!mc.Success)
{
ErrMsg="身份證輸入錯誤";
return false;
}
cid = cid.ToLower();
cid = cid.Replace("x","a");
if(aCity[int.Parse(cid.Substring(0,2))]==null)
{
ErrMsg= "非法地區";
return false;
}
try
{
DateTime.Parse(cid.Substring(6,4)+"-"+cid.Substring(10,2)+"-"+cid.Substring(12,2));
}
catch
{
ErrMsg= "非法生日";
return false;
}
for(int i=17;i>=0;i--)
{
iSum +=(System.Math.Pow(2,i)%11)*int.Parse(cid[17-i].ToString(),System.Globalization.NumberStyles.HexNumber);
}
if(iSum%11!=1)
{
ErrMsg="非法證號";
return false;
}
//return "";
string xx;
int sex=int.Parse(cid.Substring(16,1))%2;
if(sex==1)
{
xx="男";
}
else
{
xx="女";
}
ErrMsg=(aCity [int.Parse(cid.Substring(0,2))]+","+cid.Substring(6,4)+"-"+cid.Substring(10,2) +"-"+cid.Substring(12,2)+","+xx);
return true;
}
public bool Check15()
{
string[] verifyID=new string[]{"0","1","2","3","4","5","6","7","8","9","x"};
CID=CID.Substring(0,6)+"19"+CID.Substring(6,9);
foreach(string vid in verifyID)
{
bool result=Check18(CID+vid);
if(result)
{
ErrMsg+=" your Card ID:"+CID+vid;
return true;
}
}
return false;
}
public string CID
{
get{return cid_;}
set{cid_=value;}
}
public string ErrMsg
{
get{return errmsg;}
set{errmsg=value;}
}
}
}