/// <summary>
/// 性别
/// </summary>
public enum enumIDCardSex
{
//女性
Woman = 0,
//男性
Man = 1
}
/// <summary>
/// 身份证检查工具
/// </summary>
public class IDCardCheckTool
{
//各省市地区国家代码前两位代码是:
//北京 11 吉林 22 福建 35 广东 44 云南 53 天津 12 黑龙江 23
//江西 36 广西 45 西藏 54 河北 13 上海 31 山东 37 海南 46
//陕西 61 山西 14 江苏 32 河南 41 重庆 50 辽宁 21 安徽 34
//甘肃 62 内蒙古 15 浙江 33 湖北 42 四川 51 青海 63 湖南 43
//贵州 52 宁夏 64 新疆 65 台湾 71 香港 81 澳门 82 国外 91
/// <summary>
/// 省份代码
/// </summary>
//private static IList<string> listProvice = new List<string> {
// "11","22","35","44","53","12","23","36","45","54","13",
// "31","37","46","61","14","32","41","50","62","15","33",
// "42","51","63","21","34","43","52","64","65","71","81","82","91"};
/// <summary>
/// 检查身份证是否有效
/// </summary>
/// <param name="id">身份证号码</param>
/// <param name="msg">返回消息</param>
/// <returns></returns>
public static bool CheckIDCardValid(string id, out string msg)
{
msg = string.Empty;
bool ret = true;
if (!CheckLength(id))
{
msg = "身份证号码长度不正确!";
return false;
}
if (!CheckValidWords(id, out msg))
{
return false;
}
switch (id.Length)
{
case 18:
ret = CheckIDCard18(id, out msg);
break;
case 15:
ret = CheckIDCard15(id, out msg);
break;
}
return ret ;
}
/// <summary>
/// 检查身份证是否有效
/// </summary>
/// <param name="id">身份证号码</param>
/// <param name="sex">性别</param>
/// <param name="msg">返回消息</param>
/// <returns></returns>
public static bool CheckIDCardValid(string id, string sex, out string msg)
{
if (sex != "男" && sex != "女")
{
msg = "sex 参数传入错误";
return false;
}
msg = string.Empty;
bool ret = true;
if (!CheckLength(id))
{
msg = "身份证号码长度不正确!";
return false;
}
if (!CheckValidWords(id, out msg))
{
return false;
}
enumIDCardSex enumSex;
if (sex == "男")
enumSex = enumIDCardSex.Man;
else
enumSex = enumIDCardSex.Woman;
switch (id.Length)
{
case 18:
ret = CheckIDCard18(id, enumSex, out msg);
break;
case 15:
ret = CheckIDCard15(id, enumSex, out msg);
break;
}
return ret;
}
/// <summary>
/// 检查身份证长度是否正确
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private static bool CheckLength(string id)
{
if (id.Length != 15 && id.Length != 18)
return false;
else
return true;
}
/// <summary>
/// 检查15位身份证号码(包括性别)
/// </summary>
/// <param name="id"></param>
/// <param name="sex"></param>
/// <param name="msg"></param>
/// <returns></returns>
private static bool CheckIDCard15(string id, enumIDCardSex sex , out string msg)
{
msg = string.Empty;
if (!CheckSex(id[id.Length - 1], sex))
{
msg = "性别不匹配";
return false;
}
if(!CheckBirthFormat(id.Substring(6,6)))
{
msg = "出生日期格式不正确";
return false;
}
return true;
}
/// <summary>
/// 检查15位身份证号码
/// </summary>
/// <param name="id"></param>
/// <param name="msg"></param>
/// <returns></returns>
private static bool CheckIDCard15(string id, out string msg)
{
msg = string.Empty;
if(!CheckBirthFormat(id.Substring(6,6)))
{
msg = "出生日期格式不正确";
return false;
}
return true;
}
/// <summary>
/// 检查18位身份证号码(包括性别)
/// </summary>
/// <param name="id"></param>
/// <param name="sex"></param>
/// <param name="msg"></param>
/// <returns></returns>
private static bool CheckIDCard18(string id, enumIDCardSex sex, out string msg)
{
msg = string.Empty;
if (!CheckSex(id[id.Length - 2], sex))
{
msg = "性别不匹配";
return false;
}
if (!CheckBirthFormat(id.Substring(6, 8)))
{
msg = "出生日期格式不正确";
return false;
}
if (!CheckVerificationCode(id))
{
msg = "身份证号码错误";
return false;
}
return true;
}
/// <summary>
/// 检查18位身份证号码
/// </summary>
/// <param name="id"></param>
/// <param name="msg"></param>
/// <returns></returns>
private static bool CheckIDCard18(string id, out string msg)
{
msg = string.Empty;
if (!CheckBirthFormat(id.Substring(6, 8)))
{
msg = "出生日期格式不正确";
return false;
}
if (!CheckVerificationCode(id))
{
msg = "身份证号码错误";
return false;
}
return true;
}
/// <summary>
/// 检查省份代码是否存在
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private static bool CheckProviceNumExist(string id)
{
IList<string> listProvice = new List<string> {
"11","22","35","44","53","12","23","36","45","54","13",
"31","37","46","61","14","32","41","50","62","15","33",
"42","51","63","21","34","43","52","64","65","71","81","82","91"};
string proId = id.Substring(0, 2);
if(!listProvice.Contains(proId))
return false;
return true;
}
/// <summary>
/// 检查是否存在非法字符
/// </summary>
/// <param name="id">身份证号</param>
/// <param name="msg">输出信息</param>
/// <returns></returns>
private static bool CheckValidWords(string id, out string msg)
{
StringBuilder sb = new StringBuilder();
bool ret = true;
int index = 1;
foreach (var p in id)
{//88 和 120 分别对应的是 X 和 x
if (index == id.Length)
{
if ((p < 48 || p > 57) && (p != 88 || p != 120))
{
sb.AppendFormat("第{1}位存在非法字符{0}\r\n", p.ToString(), index.ToString());
ret = false;
}
}
else
{
if (p < 48 || p > 57)
{
sb.AppendFormat("第{1}位存在非法字符{0}\r\n", p.ToString(), index.ToString());
ret = false;
}
}
index++;
}
msg = sb.ToString();
return ret;
}
/// <summary>
/// 检查身份证对应性别
/// 对应位 奇数为男性,偶数为女性
/// </summary>
/// <param name="c"></param>
/// <param name="sex"></param>
/// <returns></returns>
private static bool CheckSex(char c, enumIDCardSex sex)
{
int temp = Convert.ToInt32(c) % 2;
if ((enumIDCardSex)temp != sex)
{
return false;
}
return true;
}
/// <summary>
/// 检查出身日期格式
/// </summary>
/// <param name="birthDay">身份证中原始生日字符串</param>
/// <returns></returns>
private static bool CheckBirthFormat(string birthDay)
{
if (birthDay.Length == 8)
{
birthDay = birthDay.Insert(6, "-").Insert(4, "-");
}
else if (birthDay.Length == 6)
{
birthDay = birthDay.Insert(4, "-").Insert(2, "-");
}
DateTime dt;
if (DateTime.TryParse(birthDay, out dt))
return true;
else
return false;
}
/// <summary>
/// 检查校验值
/// </summary>
/// <param name="id">身份证号</param>
/// <returns></returns>
private static bool CheckVerificationCode(string id)
{
string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
//每位数字对应的加权因子
IList<int> Wi = new List<int>{ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
char[] Ai = id.Remove(17).ToCharArray();
int sum = 0;
for (int i = 0; i <= Wi.Count - 1; i++)
{
sum += Convert.ToInt32(Ai[i].ToString()) * Wi[i];
}
int y = -1;
Math.DivRem(sum, 11, out y);
if (arrVarifyCode[y] != id[17].ToString().ToLower())
{
return false;
}
return true;
}
}