18位身份证合法性验证 带年龄限制(C#)


    /// <summary>
    /// 18位身份证验证
    /// </summary>
    public class IDNumber
    {
        /// <summary>
        /// 最大年龄
        /// </summary>
        const byte MaxAge = 20;
        /// <summary>
        /// 最小年龄
        /// </summary>
        const byte MinAge = 1;

        #region--身份证校验码的计算方法
        //1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。

        //2、将这17位数字和系数相乘的结果相加。

        //3、用加出来和除以11,看余数是多少?

        //4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。

        //5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是10,身份证的最后一位号码就是罗马数字x。
        #endregion

        //11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",33:"浙江",34:"    安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州"    ,53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外";
        //1到2位表示省份,3到4位表示城市,5到6位表示区县,
        //7到14位表示出生年,月,日,
        //15到16位表示哪办身份证的派出所,
        //17位表示性别你是男性还是女性,第18位也就是最后一位数字,是随机产生的随便的。
        //const string[] city
        //系数
        static int[] coefficient = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
        static string[] codes = { "0-1", "1-0", "2-X", "3-9", "4-8", "5-7", "6-6", "7-5", "8-4", "9-3", "10-2" };


        /// <summary>
        /// 18位身份证号码验证 规则:  年龄最大19岁 最小6岁(根据当前年)
        /// </summary>
        /// <param name="IDNumber"></param>
        /// <param name="Msg"></param>
        /// <returns></returns>
        public static bool FormatValidation(string IDNumber, out string Msg)
        {
            if (IDNumber == null || IDNumber == "" || string.IsNullOrEmpty(IDNumber))
            {
                Msg = "身份证号码为空值!";
                return false;
            }
            else
            {
                if (IDNumber.Length == 18 && Regex.IsMatch(IDNumber, @"^(11|12|13|14|15|21|22|23|31|32|33|34|35|36|37|41|42|43|44|45|46|50|51|52|53|54|61|62|63|64|65|71|81|82|91)(\d{4})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$"))
                {
                    //年龄验证
                    if (Regex.IsMatch(IDNumber.Substring(6, 8), QueryReg(DateTime.Today.Year)))
                    {
                        return Validation_(IDNumber, out Msg);
                    }
                    else
                    {
                        Msg = "身份证年龄错误!";
                        return false;
                    }
                }
                else
                {
                    Msg = "身份证号码格式错误!";
                    return false;
                }
            }
        }

        #region--学生生日格式正则表达式
        /// <summary>
        /// 学生生日格式正则表达式字符串
        /// </summary>
        static string reg_birthday;
        /// <summary>
        /// 生日格式正则表达式生成年份
        /// </summary>
        static int reg_year;
        static object make_loker = new object();
        /// <summary>
        /// 获取学生生日格式正则表达式
        /// </summary>
        /// <param name="year"></param>
        /// <returns></returns>
        static string QueryReg(int year)
        {
            if (reg_year == year)
            {
                return reg_birthday;
            }
            lock (make_loker)
            {
                //防止阻塞过多造成重复生成
                if (reg_year == year)
                {
                    return reg_birthday;
                }
                //生成
                int main_year = year - MaxAge;
                int max_year = year - MinAge;

                StringBuilder reg_ = new StringBuilder();
                reg_.Append("^((");
                //闰年字符串
                string leap_yeares = string.Empty;
                for (; main_year <= max_year; main_year++)
                {
                    //闰年判断
                    if ((main_year % 400 == 0) || (main_year % 4 == 0) && (main_year % 100 != 0))
                    {
                        leap_yeares += string.Format("{0}|", main_year);
                    }
                    if (main_year == max_year)
                        reg_.Append(main_year);
                    else
                        reg_.AppendFormat("{0}|", main_year);
                }
                reg_.Append(")(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))");

                if (!string.IsNullOrEmpty(leap_yeares))
                {
                    //leap_yeares = leap_yeares.Remove(leap_yeares.Length - 1);
                    reg_.AppendFormat("|(({0})0229)", leap_yeares.Remove(leap_yeares.Length - 1));
                }
                reg_.Append("$");
                reg_birthday = reg_.ToString();
                //生成
                reg_year = year;
                return reg_birthday;
            }
        }
        #endregion

        /// <summary>
        /// 身份证号码校验
        /// </summary>
        /// <param name="IDNumber"></param>
        /// <param name="Msg"></param>
        /// <returns></returns>
        static bool Validation_(string IDNumber, out string Msg)
        {
            int Result = 0;
            //算法
            char[] char_ = IDNumber.ToCharArray();
            for (byte i = 0; i < 17; i++)
            {
                Result += Convert.ToByte(char_[i].ToString()) * coefficient[i];
            }
            if (Array.IndexOf<string>(codes, string.Format("{0}-{1}", (Result % 11), char_[17])) == -1)
            {
                Msg = "身份证校验不通过!";
                return false;
            }
            else
            {
                Msg = string.Empty;
                return true;
            }
        }
    }




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值