新鲜、有趣,互联生活。令狐葱。

2006/12/29

验证18位身份证号码算法(C#)

说明
 
今天偶然间在网上看到关于18位身份证各位的含义以及计算方法,于是上网找到了一个验证18位身份证号码的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
 
源代码(C#实现)
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 ? "男" : "女"));

         }

 

没有评论: