项目分析 |
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1026" style="WIDTH: 335.25pt; HEIGHT: 378pt" type="#_x0000_t75"><imagedata o:title="正面" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg"></imagedata></shape>
<shape id="_x0000_i1027" style="WIDTH: 213pt; HEIGHT: 29.25pt" type="#_x0000_t75"><imagedata o:title="组件" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.jpg"></imagedata></shape>
第一部分—生成号码
代码概述
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
验证解读部分
<shape id="_x0000_i1025" style="WIDTH: 273pt; HEIGHT: 306.75pt" type="#_x0000_t75"><imagedata o:title="背面" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image004.jpg"></imagedata></shape>
代码概述
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;
}