C#效验18位身份证和15位身份证是否正确
18位身份证规则介绍
公民身份号码是由中国公民在法律上的身份识别码。它由18位数字组成,前17位数字可以用来确定一个人的基本信息,例如出生日期、性别和所在地区,而最后一位是校验码,用于校验前17位数字的正确性。
公民身份号码的结构如下:
- 前1、2位数字表示所在省份的代码;
- 第3、4位数字表示所在城市的代码;
- 第5、6位数字表示所在区县的代码;
- 第7~14位数字表示出生年、月、日;
- 第15、16位数字表示所在地的派出所的代码;
- 第17位数字表示性别,奇数表示男性,偶数表示女性;
- 第18位数字是校验码,用来检验身份证的正确性。
公民身份号码是由各省、市和县公安机关按照国家标准编制的。
因此,不同地区的身份证号码具有不同的编码规则。例如,北京市的身份证号码以11开头,而河南省的身份证号码以41开头。
身份证号码的编码规则遵循《GB11643-1999》国家标准。根据这个标准,公民身份号码由18位数字组成
15位身份证规则介绍
15位身份证号码各位的含义:
- 1-2位省、自治区、直辖市代码;
- 3-4位地级市、盟、自治州代码;
- 5-6位县、县级市、区代码;
- 7-12位出生年月日,比如670401代表1967年4月1日,与18位的第一个区别;
- 13-15位为顺序号,其中15位男为单数,女为双数。
简单身份证效验
/// <summary>
/// 验证身份证号
/// </summary>
/// <param name="IDNo"></param>
/// <returns></returns>
public static bool CheckIDNo(string IDNo)
{
return Regex.IsMatch(IDNo, @"^\d{17}[\dXx]$");
}
一、严格规则效验-调用
{
//身份证效验
List<string> cardIdList = new List<string>();
cardIdList.Add("310110201305204568");
cardIdList.Add("310110130520456");
//cardIdList.Add("310110201305204568");
//cardIdList.Add("360822199412073842");
//cardIdList.Add("350123201105305507");
//cardIdList.Add("110113195208207912");
//cardIdList.Add("330503197211057977");
//cardIdList.Add("130636197002107769");
//cardIdList.Add("632324196506255363");
//cardIdList.Add("50015519500516201X");
//cardIdList.Add("511124199808086539");
//cardIdList.Add("130682198902110034");
//cardIdList.Add("500155195005161111");
//cardIdList.Add("511124199808082222");
//cardIdList.Add("130682198902113333");
//18位身份证效验
foreach (string cardId in cardIdList)
{
bool status = false;
Console.WriteLine($"\n 身份证号:{cardId}" +
$"\n 验证结果:{TestCode.CheckIDCardHelp.CheckIDCard1.CheckCard(cardId)}" +
$"\n 生日:{TestCode.CheckIDCardHelp.CheckIDCard1.GetIdNumberMybirthDate(cardId, out status)}"+
$"\n 性别:{TestCode.CheckIDCardHelp.CheckIDCard1.GetIdNumberSex(cardId)}"
);
Console.WriteLine("/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/");
}
//15位身份证效验
}
二、严格规则效验-调用结果
身份证号:310110201305204568
验证结果:True
生日:2013/5/20 0:00:00
性别:女
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:310110130520456
验证结果:True
生日:1913/5/20 0:00:00
性别:女
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:310110201305204568
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:360822199412073842
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:350123201105305507
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:110113195208207912
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:330503197211057977
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:130636197002107769
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:632324196506255363
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:50015519500516201X
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:511124199808086539
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:130682198902110034
验证结果:True
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:500155195005161111
验证结果:False
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:511124199808082222
验证结果:False
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
身份证号:130682198902113333
验证结果:False
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
三、严格规则效验-CheckIDCardHelp帮助类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace TestCode.CheckIDCardHelp
{
/// <summary>
/// 身份证验证帮助类
/// 代码参考:https://www.jb51.net/article/270412.htm
/// </summary>
public class CheckIDCard1
{
/// <summary>
/// 中国居民身份证18位和15位验证,成功则返回true,失败则返回false
/// </summary>
/// <param name="cardId"></param>
/// <returns></returns>
public static bool CheckCard(string cardId)//创建一个CheckCard方法用于检查身份证号码是否合法
{
if (cardId.Length == 18) //如果身份证号为18位
{
return CheckCard18(cardId);//调用CheckCard18方法验证
}
else if (cardId.Length == 15) //如果身份证号为15位
{
return CheckCard15(cardId);//调用CheckCard15方法验证
}
else
{
return false;
}
}
/// <summary>
/// 18位效验
/// </summary>
/// <param name="CardId"></param>
/// <returns></returns>
private static bool CheckCard18(string CardId)//CheckCard18方法用于检查18位身份证号码的合法性
{
long n = 0;
bool flag = false;
if (long.TryParse(CardId.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(CardId.Replace('x', '0').Replace('X', '0'), out n) == false)
{
return false;//数字验证
}
string[] Myaddress = new 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"};
for (int kk = 0; kk < Myaddress.Length; kk++)
{
if (Myaddress[kk].ToString() == CardId.Remove(2))
{
flag = true;
}
}
if (!flag)
{
return false;
}
string Mybirth = CardId.Substring(6, 8).Insert(6, "-").Insert(4, "-");
DateTime Mytime = new DateTime();
if (DateTime.TryParse(Mybirth, out Mytime) == false)
{
return false;//生日验证
}
string[] MyVarifyCode = ("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 = CardId.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 (MyVarifyCode[y] != CardId.Substring(17, 1).ToLower())
{
return false;//校验码验证
}
return true;//符合GB11643-1999标准
}
/// <summary>
/// 15位效验
/// </summary>
/// <param name="CardId"></param>
/// <returns></returns>
private static bool CheckCard15(string CardId)
{
long n = 0;
bool flag = false;
if (long.TryParse(CardId, out n) == false || n < Math.Pow(10, 14))
return false;//数字验证
string[] Myaddress = new 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"};
for (int kk = 0; kk < Myaddress.Length; kk++)
{
if (Myaddress[kk].ToString() == CardId.Remove(2))
{
flag = true;
}
}
if (!flag)
{
return false;
}
string Mybirth = CardId.Substring(6, 6).Insert(4, "-").Insert(2, "-");
DateTime Mytime = new DateTime();
if (DateTime.TryParse(Mybirth, out Mytime) == false)
{
return false;//生日验证
}
return true;//符合15位身份证标准
}
/// <summary>
/// 15位转换18位身份证
/// </summary>
/// <param name="cardId"></param>
public static string CheckCard15Convent18(string cardId)
{
cardId = cardId.Trim();//获取输入的身份证号码
//如果输入的是15位的身份证号码,需要将其转换成18位
if (cardId.Length == 15)
{
int[] w = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };
char[] a = new char[] { '1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2' };
string newID = "";
int s = 0;
newID = cardId.Insert(6, "19");
for (int i = 0; i < 17; i++)
{
int k = Convert.ToInt32(newID[i]) * w[i];
s = s + k;
}
int h = 0;
Math.DivRem(s, 11, out h);
newID = newID + a[h];
cardId = newID; //最后将转换成18位的身份证号码赋值
}
return cardId;
}
/// <summary>
/// 根据身份证号获取出生日期
/// </summary>
/// <param name="IdNumber">身份证号</param>
/// <param name="status">状态</param>
/// <returns></returns>
public static DateTime GetIdNumberMybirthDate(string IdNumber, out bool status)
{
DateTime Mytime = new DateTime();
string Mybirth = "";
if (IdNumber.Trim().Length == 15)//如果输入的身份证号码是15位
{
Mybirth = ("19"+IdNumber.Substring(6, 6)).Insert(6, "-").Insert(4, "-");
}
else if (IdNumber.Trim().Length == 18)//如果输入的身份证号码是18位
{
Mybirth = IdNumber.Substring(6, 8).Insert(6, "-").Insert(4, "-");
}
if (DateTime.TryParse(Mybirth, out Mytime) == false)
{
status = false;
}
else
{
status = true;
}
return Mytime;
}
/// <summary>
/// 根据身份证号获取性别
/// </summary>
/// <param name="IdNumber">身份证号</param>
/// <returns>1男 2女</returns>
public static string GetIdNumberSex(string IdNumber)
{
string sex = "未知";
IdNumber = IdNumber.Trim();
if (IdNumber.Trim().Length == 15)//如果输入的身份证号码是15位
{
int PP = Convert.ToInt32(IdNumber.Substring(14, 1)) % 2;//判断最后一位是奇数还是偶数
if (PP == 0)//如果是偶数
{
sex = "女";//说明身份证号码的持有者是女性
}
else
{
sex = "男";//如果是奇数则身份证号码的持有者是男性
}
}
else if (IdNumber.Trim().Length == 18)//如果输入的身份证号码是18位
{
int PP = Convert.ToInt32(IdNumber.Trim().Substring(16, 1)) % 2;//判断倒数第二位是奇数还是偶数
if (PP == 0)//如果是偶数
{
sex = "女";//说明身份证号码的持有者是女性
}
else
{
sex = "男";//如果是奇数则身份证号码的持有者是男性
}
}
return sex;
}
}
}