using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Collections; namespace Net.Template.Common { /// <summary> /// 身份证帮助类 /// </summary> public class IDCardHelper { /*********************************** 身份证验证开始 ****************************************/ /** * 身份证号码验证 * 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 * * * * 15位升18位 * 15位的身份证编码首先把出生年扩展为4位,简单的就是增加一个19 */ private readonly static string[] VALCODEARR = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" }; private readonly static string[] WI = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" }; //日期 private static Regex RegDate = new Regex("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"); private static Regex RegNumber = new Regex("[0-9]*"); /// <summary> /// 身份证的有效验证 /// </summary> /// <param name="IDStr">身份证号</param> /// <returns>有效:返回"" 无效:返回String信息</returns> public static string IDCardValidate(string IDStr) { string errorInfo = "";// 记录错误信息 string ai = ""; // ================ 号码的长度 15位或18位 ================ if (IDStr.Length != 15 && IDStr.Length != 18) { errorInfo = "身份证号码长度应该为15位或18位"; return errorInfo; } // =======================(end)======================== // ================ 数字 除最后以为都为数字 ================ if (IDStr.Length == 18) { ai = IDStr.Substring(0, 17); } else if (IDStr.Length == 15) { ai = IDStr.Substring(0, 6) + "19" + IDStr.Substring(6, 9); } if (IsNumeric(ai) == false) { errorInfo = "身份证15位号码都应为数字 ; 18位号码除最后一位外,都应为数字"; return errorInfo; } // =======================(end)======================== // ================ 出生年月是否有效 ================ string strYear = ai.Substring(6, 4);// 年份 string strMonth = ai.Substring(10, 2);// 月份 string strDay = ai.Substring(12, 2);// 月份 if (IsDate(strYear + "-" + strMonth + "-" + strDay) == false) { errorInfo = "身份证生日无效"; return errorInfo; } if (Convert.ToInt32(strMonth) > 12 || Convert.ToInt32(strMonth) == 0) { errorInfo = "身份证月份无效"; return errorInfo; } if (Convert.ToInt32(strDay) > 31 || Convert.ToInt32(strDay) == 0) { errorInfo = "身份证日期无效"; return errorInfo; } // =====================(end)===================== // ================ 地区码时候有效 ================ Hashtable h = GetAreaCode(); if (h[ai.Substring(0, 2)] == null) { errorInfo = "身份证地区编码错误"; return errorInfo; } // ============================================== // ================ 判断最后一位的值 ================ int TotalmulAiWi = 0; char[] chars = ai.ToCharArray(); for (int i = 0; i < 17; i++) { TotalmulAiWi = TotalmulAiWi + Convert.ToInt32(chars[i].ToString()) * Convert.ToInt32(WI[i]); } int modValue = TotalmulAiWi % 11; string strVerifyCode = VALCODEARR[modValue]; ai = ai + strVerifyCode; if (IDStr.Length == 18) { if (ai != IDStr.ToLower()) { errorInfo = "身份证无效,不是合法的身份证号码"; return errorInfo; } } else { return ""; } // =====================(end)===================== return ""; } /// <summary> /// 设置地区编码 /// </summary> /// <returns>Hashtable 对象</returns> private static Hashtable GetAreaCode() { Hashtable hashtable = new Hashtable(); hashtable.Add("11", "北京"); hashtable.Add("12", "天津"); hashtable.Add("13", "河北"); hashtable.Add("14", "山西"); hashtable.Add("15", "内蒙古"); hashtable.Add("21", "辽宁"); hashtable.Add("22", "吉林"); hashtable.Add("23", "黑龙江"); hashtable.Add("32", "江苏"); hashtable.Add("33", "浙江"); hashtable.Add("34", "安徽"); hashtable.Add("35", "福建"); hashtable.Add("36", "江西"); hashtable.Add("37", "山东"); hashtable.Add("41", "河南"); hashtable.Add("42", "湖北"); hashtable.Add("43", "湖南"); hashtable.Add("44", "广东"); hashtable.Add("45", "广西"); hashtable.Add("46", "海南"); hashtable.Add("50", "重庆"); hashtable.Add("51", "四川"); hashtable.Add("52", "贵州"); hashtable.Add("53", "云南"); hashtable.Add("54", "西藏"); hashtable.Add("61", "陕西"); hashtable.Add("62", "甘肃"); hashtable.Add("63", "青海"); hashtable.Add("64", "宁夏"); hashtable.Add("65", "新疆"); hashtable.Add("71", "台湾"); hashtable.Add("81", "香港"); hashtable.Add("82", "澳门"); hashtable.Add("91", "国外"); return hashtable; } /// <summary> /// 判断字符串是否为数字 /// </summary> /// <param name="str">输入字符串</param> /// <returns></returns> private static bool IsNumeric(String str) { System.Text.RegularExpressions.Match m = RegNumber.Match(str); return m.Success; } /// <summary> /// 判断字符串是否为日期格式 /// </summary> /// <param name="strDate">输入字符串</param> /// <returns></returns> private static bool IsDate(string strDate) { System.Text.RegularExpressions.Match m = RegDate.Match(strDate); return m.Success; } } }