C#实现的18位身份证格式验证算法[详细版]

本文介绍了一个用于生成和验证中国大陆身份证号码的程序。该程序包括读取行政区划代码文件、根据用户选择生成身份证号以及验证身份证号的有效性等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

项目分析

 

 

 

第一部分生成号码

代码概述

1.事件:void frmAlgorithm_Load(object sender, EventArgs e)

描述:首先,在窗体加载时,调用"void GetDiscInfo(string sFilenName)"读取"DiscInfo.txt"中的信息,然后在"cbProvince"中显示读取的信息(使用了外设组件"bsProvince")

2.事件: void cbProvince_SelectedIndexChanged(object sender, EventArgs e)

   描述:在选择省份时,调用"List<clsAdministrativeDivisionsCode> GetSomeCodes(string sCondition)""cbCities"中显示省份的下属市或县(使用了外设组件"bsCity")

----------------核心代码-↓↓↓------------------------------------

3.事件: void btnGenID_Click(object sender, EventArgs e)

描述: 方法1:"List<string> GetID()"  //生成14位数号码,并返回18位数号码

      方法2: "List<string> GenRnd(int iSex)"  //返回3位数的顺序码

      方法3: "string GenParityBit(string s17)"  //返回1位数的校验码

根据选择好的生日和性别生成号码.首先调用方法1.在方法1中调用了方法2和方法3,方法2返回3位数的顺序码,方法3返回1位数的校验码.方法1自身生成14位数号码+3位顺序码+1位校验码=18位号码,返回给外设组件"bsID",然后显示.

----------------核心代码-↑↑↑---------------------------------------

 

源代码

 

class clsAdministrativeDivisionsCode

{

    private string adCode;

    private string adName;

    public clsAdministrativeDivisionsCode(string code, string name)

    { adCode = code; adName = name; }

    public string AdCode

    {

        get { return adCode; }

        set { adCode = value; }

    }

    public string AdName

    {

        get { return adName; }

        set { adName = value; }

    }

}// class clsAdministrativeDivisionsCode

 

 

 

 

 

public class frmAlgorithm : Form

{

    private int maxNum = 500;

    List<clsAdministrativeDivisionsCode> provinceCode = new List<clsAdministrativeDivisionsCode>();

    List<clsAdministrativeDivisionsCode> cityCode = new List<clsAdministrativeDivisionsCode>();

    List<string> ID = new List<string>();

    private void frmAlgorithm_Load(object sender, EventArgs e)

    {

        GetDiscInfo("DiscInfo.txt");

        bsProvince.DataSource = provinceCode;

        cbProvince.DataSource = bsProvince;

        cbProvince.DisplayMember = "AdName";

        cbProvince.ValueMember = "AdCode";

        cbProvince.SelectedIndex = -1; //引发cbProvince_SelectedIndexChanged事件

        lblMsg.Text = @"请在文本框中输入位有效身份证号,验证通过后方可解读。";

    }//void frmAlgorithm_Load

 

private void GetDiscInfo(string sFilenName)

{

using (StreamReader sr = new StreamReader(Environment.CurrentDirectory + @"/" + sFilenName, Encoding.Default)) {

string sLine = string.Empty;

 Regex re = new Regex(@"[/s]{1,}", RegexOptions.Compiled); //指定至少匹配个空白字符,程序集

 while (!sr.EndOfStream) {  //如果流不在末尾,则循环

      sLine = sr.ReadLine();

      sLine = re.Replace(sLine, " ");

      string[] sTemp = sLine.Split(new char[] { ' ' });

      if (sTemp[0].EndsWith("0000"))  {

provinceCode.Add(new clsAdministrativeDivisionsCode(sTemp[0],sTemp[1])); }

      else  {

if (sTemp[0].EndsWith("00"))

             cityCode.Add(new clsAdministrativeDivisionsCode(sTemp[0],sTemp[1]));

             else

                  if (sTemp[1].EndsWith("市辖区"))

                cityCode.Add(new clsAdministrativeDivisionsCode(sTemp[0], "  " + sTemp[1]));

                   else

                cityCode.Add(new clsAdministrativeDivisionsCode(sTemp[0], "    " + sTemp[1]));

           }//else

     }//while

}//using

}//void GetDiscInfo(string sFilenName)

 

    //事件将在省份列表的选择中被引发

    private void cbProvince_SelectedIndexChanged(object sender, EventArgs e)

    {

        List<clsAdministrativeDivisionsCode> tempCity = new List<clsAdministrativeDivisionsCode>();

        if (cbProvince.SelectedValue != null)

        {

            //调用Substring(0, 2)的目的是:提取公共部分来查找下属市或县

            //例如:山西省的省号为140000,则其下属市或县的号码都以14开头

            //140101 市辖区     140105 小店区

            //140106 迎泽区     140122 阳曲县

            tempCity = GetSomeCodes(cbProvince.SelectedValue.ToString().Substring(0, 2));

            if (tempCity != null)

            {

                bsCity.DataSource = tempCity;

                cbCities.DataSource = bsCity;

                cbCities.DisplayMember = "AdName";

                cbCities.ValueMember = "AdCode";//显示信息

            }//if

        }//if

 }//cbProvince_SelectedIndexChanged

 

    private List<clsAdministrativeDivisionsCode> GetSomeCodes(string sCondition)

    {

        List<clsAdministrativeDivisionsCode> tempCity = new List<clsAdministrativeDivisionsCode>();

        foreach (clsAdministrativeDivisionsCode temp in cityCode)

            if (sCondition == temp.AdCode.Substring(0, 2))//比较省份号码的公共部分

                tempCity.Add(temp);

        return tempCity;//返回下属市或县     }//List<clsAdministrativeDivisionsCode> GetSomeCodes(string sCondition)

 

----------------核心代码-↓↓↓------------------------------------

    private void btnGenID_Click(object sender, EventArgs e)

    {

        //省略一些检查代码

        this.Cursor = Cursors.WaitCursor;//把光标设置成沙漏状

        bsID.DataSource = GetID();        //获取外设组件bsID的数据源(GetID()获得)

        lbID.DataSource = bsID;           //显示个身份证号

        this.Cursor = Cursors.Default;//还原光标

}//void btnGenID_Click

     private List<string> GetID()

    {

       List<string> tempID = new List<string>();

       List<string> sexRndNum = GenRnd(rbMan.Checked?0:1);//单选框''被选中,值为0;否则为1

       string str18 = string.Empty;

       for (int i = 0; i < maxNum; i++)

           {

             string str17=string.Empty;

             string sCity = cbCities.SelectedValue.ToString();//获取下属市或县的号码,共6

             string sYMD=dtpBirth.Value.Year.ToString() +

                         dtpBirth.Value.Month.ToString().PadLeft(2, '0') +

                         tpBirth.Value.Day.ToString().PadLeft(2, '0');//获取年月日,共8

             str17=sCity+sYMD+sexRndNum[i];//17位的身份证号,还需最后一位校验码

             str18 = str17 + GenParityBit(str17);//18位的身份证号

             tempID.Add(str18);

            }                 

            return tempID;

  }//List<string> GetID()

 

    private List<string> GenRnd(int iSex)

    {

        Random rd = new Random();//随机数对象

        List<string> sTemp = new List<string>();

        int i = 0;

        while (i < maxNum)//maxNum=500;

        {

            int rndNum = rd.Next(0, 1000);  //0<=rndNum<=999

            if (rndNum % 2 == iSex) rndNum++;

            if (rndNum >= 1000) continue;  //if (rndNum == 1000)

            string s3 = rndNum.ToString().PadLeft(3, '0');

            //右对齐字符串,不满位的,在左边添加'0'填充例:002,054,586

            if (!sTemp.Contains(s3))//确保没有重复的号码

            {

                sTemp.Add(s3);

                i++;

            }

        }//while

        return sTemp;

    }// List<string> GenRnd(int iSex)

 

 

 

 

    //不知道下面这些数据从哪来是正常的,是根据公式来算的

    private string GenParityBit(string s17)

    {

        int[] Weight = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

        string Parity = "10X98765432";

        int s = 0;

        for (int i = 0; i < s17.Length; i++)

        {

            s += Int32.Parse(s17[i].ToString()) * Weight[i];

        }

        return Parity[s % 11].ToString();//返回校验码

    }//string GenParityBit(string s17)

----------------核心代码-↑↑↑---------------------------------------

} //public class frmAlgorithm

 

验证解读部分

 

代码概述

1.   事件: void btnVerification_Click(object sender, EventArgs e)

描述:首先获取输入的身份证号码,然后把它拆分成4,分别是

1)      行政地区码(6),使用"bool isDiscValid(string s)"来验证.

2)      出生日期(7-14),使用" bool isBirthValid(string s)"来验证.

3)      顺序码(15-17),使用"bool isSexValid(string s)"来验证.

4)      校验码(18),使用" bool isParityValid(string s18)"来验证.

 

源代码

class clsAdministrativeDivisionsCode

{

       private void btnVerification_Click(object sender, EventArgs e)

     {

//省略提示……

           Regex reg = new Regex(@"^/d{17}(/d|X)");//匹配18位数字,最后一位可以是数字或X

           string sTemp = tbVerification.Text;

           lbCardInfo.Items.Clear();

           if (sTemp == string.Empty) { return; }

           if (sTemp.Length != 18) { return; }

           if (reg.Matches(sTemp).Count == 0) { return; }

           if (!isDiscValid(sTemp.Substring(0, 6))) { return; }//验证行政地区码

           if (!isBirthValid(sTemp.Substring(6, 8))) { return; }//验证生日

           else

                lbCardInfo.Items.Add(string.Format("出生日期:{0}{1}{2}", sTemp.Substring(6, 4), sTemp.Substring(10, 2), sTemp.Substring(12, 2)));

           if (!isSexValid(sTemp.Substring(14, 3))) { return; }//验证性别

           else { lbCardInfo.Items.Add("性别:" + ((Convert.ToInt32(sTemp.Substring(14, 3)) % 2 == 0) ? "" : "")); }

           if (!isParityValid(sTemp)) { return; }//验证最后一位校验码

           lbCardInfo.Items.Insert(0, "身份证号:" + sTemp);

           lbCardInfo.Items.Insert(0, "验证解读信息:");

           lbCardInfo.Items.Add("完成验证!");

 }//void btnVerification_Click

 

 

 

 

       private bool isDiscValid(string s)

           {

           bool iFlag = false;

           foreach (clsAdministrativeDivisionsCode cadc in cityCode)

                {

                if (cadc.AdCode == s)

                     {

                     string st = s.Substring(0, 2);

                     foreach (clsAdministrativeDivisionsCode capc in provinceCode)

                         {

                         if (capc.AdCode.Substring(0, 2) == st)

                              {

                              lbCardInfo.Items.Add("省或直辖市名称:" + capc.AdName);

                              break;

                              }

                         }//foreach

                     foreach (clsAdministrativeDivisionsCode caac in cityCode)

                         {

                         if (caac.AdCode == s.Substring(0, 4) + "00")

                              {

                              lbCardInfo.Items.Add("市名称:" + caac.AdName.TrimStart());

                              break;

                              }

                         }//foreach

                     lbCardInfo.Items.Add("地区名称:" + cadc.AdName.TrimStart());

                     iFlag = true;

                     break;

                     }//if

                }//foreach

           return iFlag;

           }//bool isDiscValid(string s)

 

 

 

 

 

 

 

 

 

 

 

 

        private bool isBirthValid(string s)

        {

            string sYear = s.Substring(0, 4);

            string sMonth = s.Substring(4, 2);

            string sDay = s.Substring(6, 2);

            DateTime dt;

           if (DateTime.TryParse(string.Format("{0}-{1}-{2}", sYear, sMonth, sDay), out dt))

                       {

                       if (dt > DateTime.Now)

                            return false;

                       else

                            return true;

                       }

                   else { return false; }

        }//bool isBirthValid(string s)

 

        private bool isSexValid(string s)

        { return s == "000" ? false : true; }

 

        private bool isParityValid(string s18)

        {

         //这里不用我多说了挖~~

            int[] Weight = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

            string Parity = "10X98765432";

            string s17 = s18.Substring(0, 17);

            int s = 0;

            for (int i = 0; i < s17.Length; i++)

                s += Int32.Parse(s17[i].ToString()) * Weight[i];

            return Parity[s % 11].ToString() == s18.Substring(17, 1) ? true : false;

        }//bool isParityValid(string s18)

} //public class frmAlgorithm

 

附件

中国国家统计局最新县及县以上行政区划代码(截止2007年12月31日)

统计 国家统计局

非常感谢学生赵阳,经过了他的整理和注释后,进一步方便了大家阅读!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值