zoukankan      html  css  js  c++  java
  • 中国身份证验证算法旧15位新18位

    using System;

    /// <summary>
    /// Summary description for IDCardValid
    /// </summary>
    namespace a
    {

        public static class ss
        {
            public static void Main()
            {
                string str;
                while (true )
                {
                    str = Console.ReadLine();
                    Console.WriteLine(IDCardValid.CheckIDCard(str));
                }

            }
        }

        public class IDCardValid
        {
            public IDCardValid()
            {
                //
                // TODO: Add constructor logic here
                //
            }

            /// <summary>
            /// 验证身份证号码
            /// </summary>
            /// <param name="Id">身份证号码</param>
            /// <returns>验证成功为True,否则为False</returns>
            public static 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;
                }
            }
            #region 身份证号码验证

            /// <summary>
            /// 验证15位身份证号
            /// </summary>
            /// <param name="Id">身份证号</param>
            /// <returns>验证成功为True,否则为False</returns>
            private static 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标准
            }

            /// <summary>
            /// 验证18位身份证号
            /// </summary>
            /// <param name="Id">身份证号</param>
            /// <returns>验证成功为True,否则为False</returns>
            private static 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位身份证标准
            }
            #endregion
        }
    }

     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。

  • 相关阅读:
    python note 30 断点续传
    python note 29 线程创建
    python note 28 socketserver
    python note 27 粘包
    python note 26 socket
    python note 25 约束
    Sed 用法
    python note 24 反射
    python note 23 组合
    python note 22 面向对象成员
  • 原文地址:https://www.cnblogs.com/cpcpc/p/2123129.html
Copyright © 2011-2022 走看看