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  


以下是程序代码:  
private   string   CheckCidInfo(string   cid)  
{  
string[]   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, "国外 "};  
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)  
{  
return   " ";  
}  
cid   =   cid.ToLower();  
cid   =   cid.Replace( "x ", "a ");  
if(aCity[int.Parse(cid.Substring(0,2))]==null)  
{  
return   "非法地区 ";  
}  
try  
{  
DateTime.Parse(cid.Substring(6,4)+ "- "+cid.Substring(10,2)+ "- "+cid.Substring(12,2));  
}  
catch  
{  
return   "非法生日 ";  
}  
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)  
return( "非法证号 ");  


return(aCity[int.Parse(cid.Substring(0,2))]+ ", "+cid.Substring(6,4)+ "- "+cid.Substring(10,2)+ "- "+cid.Substring(12,2)+ ", "+(int.Parse(cid.Substring(16,1))%2==1¡ "男 ": "女 "));  


}  


调用测试:  
Response.Write(CheckCidInfo( "340524198002300019 "));  
Response.Write(CheckCidInfo( "34052419800101001x "));  


对于15位的身份验证可以先升至18位再进行验证,因为一直很忙,就没有写15-》18的方法  
把规则公布一下:  


根据〖中华人民共和国国家标准   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。  


转http://www.chinaitpower.com/A/2005-01-01/136492.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值