身份证真伪的验证(C# / ASP.NET /JS代码)及算法说明

本文代码只对身份证真伪做验证,只要符合算法的身份证都为合法身份证,至于被验证的身份证的使用情况无法做出验证和判断。

一、C#(ASP.NET)代码:

       

 #region 验证身份证是否合法
        /// <summary>
        /// 验证身份证是否合法
        /// </summary>
        /// <param name="id">要验证的身份证号码</param>
        /// <returns>错误信息,为空时表示身份证合法</returns>
        public static string ValidID(string id)
        {
            string message = string.Empty;
            Regex reg = new Regex("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)");//身份证正则表达式
            string id_17 = string.Empty;//前17位
            string resultLast = string.Empty;
            if (reg.IsMatch(id))//是否符合
            {
                if (id.Length == 18)//18位时
                {
                    id_17 = id.Substring(0, 17);


                    int[] num = new int[17];//声明数组,存放每一位数字


                    for (int i = 0; i < 17; i++)
                    {
                        num[i] = Convert.ToInt32(id.Substring(i, 1));//获取每位上的数字,从左往右。                        
                    }
                    //出生日期验证
                    reg = new Regex("^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");
                    /*声明变量,并获取身份证号码中的“出生日期”*/
                    string birth = string.Empty;
                    for (int i = 6, j = 0; i < 14; i++, j++)
                    {
                        birth += Convert.ToString(num[i]);
                        if (j == 3 || j == 5)//添加“-”使日期格式为:yyyy-MM-dd
                        {
                            birth += "-";
                        }
                    }
                    //验证出生日期
                    if (!reg.IsMatch(birth))
                    {
                        return message = "身份证号码输入有误!";
                    }
                    else if (Convert.ToDateTime(birth).AddYears(18) > Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")) || Convert.ToDateTime(birth).AddYears(75) <  Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")))
                    {
                        return message = "身份证号码输入有误!年龄应在18到75岁之间";
                    }                    
                    //从左往右每一位的权:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2
                    int[] quan = new int[17] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
                    int sum = 0;
                    for (int i = 0; i < 17; i++)
                    {
                        sum += num[i] * quan[i];
                    }
                    //余数(sum % 11):  0-1-2-3-4-5-6-7-8-9-10(可视为索引)
                    //对应值:1-0-X-9-8-7-6-5-4-3-2
                    string[] duiyingz = new string[11] { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };


                    if ((id_17 + duiyingz[sum % 11]).Equals(id.ToUpper()))
                    {
                        return message = string.Empty;
                    }
                    else
                    {
                        return message = "身份证号码输入有误!";
                    }


                }
                else//十五位身份证
                {
                    id = id.Insert(6, "19");//给15位身份证升级,补全年份。
                    int[] num = new int[17];//声明数组,存放每一位数字


                    for (int i = 0; i < 17; i++)
                    {
                        num[i] = Convert.ToInt32(id.Substring(i, 1));//获取每位上的数字,从左往右。                        
                    }
                    //出生日期验证
                    reg = new Regex("^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");
                    /*声明变量,并获取身份证号码中的“出生日期”*/
                    string birth = string.Empty;
                    for (int i = 6, j = 0; i < 14; i++, j++)
                    {
                        birth += Convert.ToString(num[i]);
                        if (j == 3 || j == 5)//添加“-”使日期格式为:yyyy-MM-dd
                        {
                            birth += "-";
                        }
                    }
                    //验证出生日期
                    if (!reg.IsMatch(birth))
                    {
                        return message = "身份证号码输入有误!";
                    }
                    else if (Convert.ToDateTime(birth).AddYears(18) > Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")) || Convert.ToDateTime(birth).AddYears(75) <  Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")))
                    {
                        return message = "身份证号码输入有误!年龄应在18到75岁之间";
                    }
                    else
                    {
                        return message = string.Empty;
                    }
                }
            }
            else//不符合身份证规则(非15或18位)
            {
                return message = "身份证号码格式输入有误,请输入15或18位身份证号码!";
            }
        }



二、JS代码,这个用途就广了,这个验证可以验证身份证真伪,但没有对身份证的使用者的年龄验证

function CheckIDNumber(id){
    var sid=id;
var IDReg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; //15或18位
if(!IDReg.test(sid)){
return false;
}
        if (sid.length == 18){//18位
        var ysid=sid;
        sid=sid.substring(0,17);
        var jiaquan = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
        var sigma=0;        
        for(var i = 0 ;i < 17 ;i++){
           sigma += parseInt(parseInt(sid.substring(i,i+1))*jiaquan[i]);//取每一位上的数字和对应的权相乘并求和     
        }
        var jiaoyan = new Array('1','0','X','9','8','7','6','5','4','3','2');
        
        if (sid+jiaoyan[(sigma % 11)]==ysid){return true;}
        else{return false;}
        }else{//15位
return true;
}
}


 

附:身份证计算法则:     

 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 4 2  

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身份证号码的编排规则    身份证号码中这些数字是怎样排列的,每个数字表示什么意思呢?下面就让我们一起来探索其中的规律吧!新的身份证号码是由18位数字组成的,它们分别表示:

(1)前1、2位数字表示:所在省份的代码;

(2)第3、4位数字表示:所在城市的代码;

(3)第5、6位数字表示:所在区县的代码;

(4)第7~14位数字表示:出生年、月、日;

(5)第15、16位数字表示:所在地的派出所的代码;

(6)第17位数字表示性别:奇数表示男性,偶数表示女性;

(7)第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,

     用来检验身份证的正确性。校检码为0~9的数字和x表示。

以上说明参考文献:http://wenku.baidu.com/view/13eab34ac850ad02de80414e.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值