输入身份证号码自动读取生日与性别(delphi)
一、格式介绍:
【15位号码格式】
1、第l一6位数为行政区划代码;
2、第7-12位数为出生日期代码;
3、第13---15位数为分配顺序代码;
(1)、行政区划代码,是指公民第一次申领居民身份证时的常住户口所在地的行政地区。
(2)、出生日期代码,第7-8位数代表年份(年份前面二位数省略),第9-10位数代表月份(月份为l位数的前面加零)。第11一12位数代表日期(日期为1位数的前面加零)。
(3)、分配顺序代码,是按人口数统一合理分配以固定顺序给予每个人的顺序号,最末一位数是奇数的分配给男性,偶数分配给女性。
【18位号码格式】
1. 1~6位为地区代码;
(其中1、2位数为各省级政府的代码,3、4位数为地、市级政府的代码,5、6位数为县、区级政府代码。)
2. 7~14位为出生年月日
3.15~17位为顺序号,是县、区级政府所辖派出所的分配码,每个派出所分配码为10个连续号码,例如“000-009”或“060-069”,其中单数为男性分配码,双数为女性分配码,如遇同年同月同日有两人以上时顺延第二、第三、第四、第五个分配码。如:007的就是个男生 而且和他同年月日生的男生至少有两个 他们的后四位是001* 和 003*
4.18位为效验位(识别码),通过复杂公式算出,普遍采用计算机自动生成。是前面17位的一种检验代码,如果你改变了前面某个数字而后面的效验代码不响应改变就会被计算软件判断为非法身份正号码。X也是效验代码的一种,代表数字10;
二.代码部分:
功能:
1.实现身份号码的有效性检查
2.实现身份号码出生日期与性别自动匹配
//检查身份证号码是否为有效 function CheckIDCard(IDCard: String):Boolean; const OLD_LENGTH = 15; //15位长度 NEW_LENGTH = 18; //18位长度 DaysOfMonths: array [1..12] of Integer = (31,28,31,30,31,30,31,31,30,31,30,31); //月天数数组 DaysOfMonths1: array [1..12] of Integer = (31,29,31,30,31,30,31,31,30,31,30,31); var Len: Integer; AYear,AMonth,ADay : Integer; function IsNum(Value: String):Boolean; var I: Integer; begin Result := True; for I:=1 to Length(Value) do begin if not(Value[I] in['0'..'9']) then begin Result := False; Exit; end; end; end; begin Result := False; Len := length(IDCard); if (Len<>OLD_LENGTH) and (Len<>NEW_LENGTH) then Exit; //检查是否为数字 if Len = OLD_LENGTH then begin //15位 if Not IsNum(IDCard) then Exit; AYear := StrToInt('19'+Copy(IDCard,7,2)); AMonth := StrToInt(Copy(IDCard,9,2)); ADay := StrToInt(Copy(IDCard,11,2)); end else begin //18位 if IDCard[NEW_LENGTH] = 'X' then begin if Not IsNum(Copy(IDCard,1,NEW_LENGTH-1)) then Exit; end else begin if Not IsNum(IDCard) then Exit; end; //检查校验位 if IDCard[NEW_LENGTH] <> IDCardCheckSum(IDCard) then Exit; AYear := StrToInt(Copy(IDCard,7,4)); AMonth := StrToInt(Copy(IDCard,11,2)); ADay := StrToInt(Copy(IDCard,13,2)); end; //检查年月日的有效性 if not(AMonth in[1..12]) then Exit; if(IsLeapYear(AYear)) then begin if not(ADay in[1..DaysOfMonths1[AMonth]]) then Exit; end else begin if not(ADay in[1..DaysOfMonths[AMonth]]) then Exit; end; Result := True; end; //将15的身份证号码转换为18位 function IDCardTo18(IDCard: string):string; const OLD_LENGTH = 15; var newid: string; begin if length(IDCard) <> OLD_LENGTH then begin result:= IDCard; Exit; end else begin newid:= IDCard; insert('19', newid, 7); result:= newid + IDCardCheckSum(IDCard); end; end; //代码实现部分 procedure TForm1.Query1idcardSetText(Sender: TField;const Text: String); var __Text,__S: String; __idcard:string; __b : boolean; __sex:Integer; begin inherited; __Text := Text; if __Text = '' then Exit; __idcard:=__text; __b:= CheckIDCard(__Text); //调用CheckIDCard函数,检查号码的有效性 if (length(__idcard) >6) and (length(__idcard)<=12) then begin if ((Ord(__idcard[1])>=64) and (Ord(__idcard[1])<=126)) or ((length(__idcard)>6) and (length(__idcard)<=12)) then begin __b:=true; end; end; if __b then begin Sender.Value := __Text; //15位 if Length(__Text)=15 then begin //匹配出生日期; __S:='19'+copy(__Text,7,2)+'-'+copy(__Text,9,2)+'-'+copy(__Text,11,2); Query1birthday.Value:=strtodate(__S); //匹配性别; __sex:=StrToInt(__Text[15]); if __sex mod 2 =0 then begin Query1guestsex.Value:=1 end else Query1guestsex.Value:=0 end; //18位 if Length(__Text)=18 then begin __S:=copy(__Text,7,4)+'-'+copy(__Text,11,2)+'-'+copy(__Text,13,2); Query1birthday.Value:=strtodate(__S); __sex:=StrToInt(__Text[17]); if __sex mod 2 =0 then begin Query1guestsex.Value:=1 end else Query1guestsex.Value:=0 end; end else raise Exception.Create('输入的身份证号码无效,请检查!'); end;