![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//本文来自Delphi之窗,http://www.52delphi.com
function ValidatePID( const APID: string): string;
{ 内部函数,取身份证号校验位,最后一位,对18位有效 }
function GetVerifyBit(sIdentityNum: string): Char;
var
nNum: Integer;
begin
Result := # 0;
nNum := StrToInt(sIdentityNum[ 1]) * 7 +
StrToInt(sIdentityNum[ 2]) * 9 +
StrToInt(sIdentityNum[ 3]) * 10 +
StrToInt(sIdentityNum[ 4]) * 5 +
StrToInt(sIdentityNum[ 5]) * 8 +
StrToInt(sIdentityNum[ 6]) * 4 +
StrToInt(sIdentityNum[ 7]) * 2 +
StrToInt(sIdentityNum[ 8]) * 1 +
StrToInt(sIdentityNum[ 9]) * 6 +
StrToInt(sIdentityNum[ 10]) * 3 +
StrToInt(sIdentityNum[ 11]) * 7 +
StrToInt(sIdentityNum[ 12]) * 9 +
StrToInt(sIdentityNum[ 13]) * 10 +
StrToInt(sIdentityNum[ 14]) * 5 +
StrToInt(sIdentityNum[ 15]) * 8 +
StrToInt(sIdentityNum[ 16]) * 4 +
StrToInt(sIdentityNum[ 17]) * 2;
nNum := nNum mod 11;
case nNum of
0: Result := ' 1 ';
1: Result := ' 0 ';
2: Result := ' X ';
3: Result := ' 9 ';
4: Result := ' 8 ';
5: Result := ' 7 ';
6: Result := ' 6 ';
7: Result := ' 5 ';
8: Result := ' 4 ';
9: Result := ' 3 ';
10: Result := ' 2 ';
end;
end;
var
L : Integer;
sCentury : string;
sYear2Bit : string;
sMonth : string;
sDate : string;
iCentury : Integer;
iMonth : Integer;
iDate : Integer;
CRCFact : string;// 18位证号的实际值
CRCTh : string; // 18位证号的理论值
FebDayAmt: Byte;// 2月天数
begin
L := Length(APID);
if (L in [ 15, 18]) = False then
begin
Result := Format( ' 身份证号不是15位或18位(%0:s, 实际位数:%1:d) ', [APID, L]);
Exit;
end;
CRCFact := '';
if L = 18 then
begin
sCentury := Copy(APID, 7, 2);
iCentury := StrToInt(sCentury);
if (iCentury in [ 18.. 20]) = False then
begin
Result := Format( ' 身份证号码无效:18位证号的年份前两位必须在18-20之间(%0:S) ', [sCentury]);
Exit;
end;
sYear2Bit := Copy(APID, 9, 2);
sMonth := Copy(APID, 11, 2);
sDate := Copy(APID, 13, 2);
CRCFact := Copy(APID, 18, 1);
end else
begin
sCentury := ' 19 ';
sYear2Bit := Copy(APID, 7, 2);
sMonth := Copy(APID, 9, 2);
sDate := Copy(APID, 11, 2);
end;
iMonth := StrToInt(sMonth);
iDate := StrToInt(sDate);
if (iMonth in [ 01.. 12]) = False then
begin
Result := Format( ' 身份证号码无效:月份必须在01-12之间(%0:s) ', [sMonth]);
Exit;
end;
if (iMonth in [ 1, 3, 5, 7, 8, 10, 12]) then
begin
if (iDate in [ 01.. 31]) = False then
begin
Result := Format( ' 身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s) ', [sDate]);
Exit;
end;
end;
if (iMonth in [ 4, 6, 9, 11]) then
begin
if (iDate in [ 01.. 30]) = False then
begin
Result := Format( ' 身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s) ', [sDate]);
Exit;
end;
end;
if IsLeapYear(StrToInt(sCentury + sYear2Bit)) = True then
begin
FebDayAmt := 29;
end else
begin
FebDayAmt := 28;
end;
if (iMonth in [ 2]) then
begin
if (iDate in [ 01..FebDayAmt]) = False then
begin
Result := Format( ' 身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s) ', [sDate]);
Exit;
end;
end;
if CRCFact <> '' then
begin
CRCTh := GetVerifyBit(APID);
if CRCFact <> CRCTh then
begin
Result := Format( ' 身份证号码无效:校验位(第18位)错:(%0:s) ', [APID]);
Exit;
end;
end;
end;
function ValidatePID( const APID: string): string;
{ 内部函数,取身份证号校验位,最后一位,对18位有效 }
function GetVerifyBit(sIdentityNum: string): Char;
var
nNum: Integer;
begin
Result := # 0;
nNum := StrToInt(sIdentityNum[ 1]) * 7 +
StrToInt(sIdentityNum[ 2]) * 9 +
StrToInt(sIdentityNum[ 3]) * 10 +
StrToInt(sIdentityNum[ 4]) * 5 +
StrToInt(sIdentityNum[ 5]) * 8 +
StrToInt(sIdentityNum[ 6]) * 4 +
StrToInt(sIdentityNum[ 7]) * 2 +
StrToInt(sIdentityNum[ 8]) * 1 +
StrToInt(sIdentityNum[ 9]) * 6 +
StrToInt(sIdentityNum[ 10]) * 3 +
StrToInt(sIdentityNum[ 11]) * 7 +
StrToInt(sIdentityNum[ 12]) * 9 +
StrToInt(sIdentityNum[ 13]) * 10 +
StrToInt(sIdentityNum[ 14]) * 5 +
StrToInt(sIdentityNum[ 15]) * 8 +
StrToInt(sIdentityNum[ 16]) * 4 +
StrToInt(sIdentityNum[ 17]) * 2;
nNum := nNum mod 11;
case nNum of
0: Result := ' 1 ';
1: Result := ' 0 ';
2: Result := ' X ';
3: Result := ' 9 ';
4: Result := ' 8 ';
5: Result := ' 7 ';
6: Result := ' 6 ';
7: Result := ' 5 ';
8: Result := ' 4 ';
9: Result := ' 3 ';
10: Result := ' 2 ';
end;
end;
var
L : Integer;
sCentury : string;
sYear2Bit : string;
sMonth : string;
sDate : string;
iCentury : Integer;
iMonth : Integer;
iDate : Integer;
CRCFact : string;// 18位证号的实际值
CRCTh : string; // 18位证号的理论值
FebDayAmt: Byte;// 2月天数
begin
L := Length(APID);
if (L in [ 15, 18]) = False then
begin
Result := Format( ' 身份证号不是15位或18位(%0:s, 实际位数:%1:d) ', [APID, L]);
Exit;
end;
CRCFact := '';
if L = 18 then
begin
sCentury := Copy(APID, 7, 2);
iCentury := StrToInt(sCentury);
if (iCentury in [ 18.. 20]) = False then
begin
Result := Format( ' 身份证号码无效:18位证号的年份前两位必须在18-20之间(%0:S) ', [sCentury]);
Exit;
end;
sYear2Bit := Copy(APID, 9, 2);
sMonth := Copy(APID, 11, 2);
sDate := Copy(APID, 13, 2);
CRCFact := Copy(APID, 18, 1);
end else
begin
sCentury := ' 19 ';
sYear2Bit := Copy(APID, 7, 2);
sMonth := Copy(APID, 9, 2);
sDate := Copy(APID, 11, 2);
end;
iMonth := StrToInt(sMonth);
iDate := StrToInt(sDate);
if (iMonth in [ 01.. 12]) = False then
begin
Result := Format( ' 身份证号码无效:月份必须在01-12之间(%0:s) ', [sMonth]);
Exit;
end;
if (iMonth in [ 1, 3, 5, 7, 8, 10, 12]) then
begin
if (iDate in [ 01.. 31]) = False then
begin
Result := Format( ' 身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s) ', [sDate]);
Exit;
end;
end;
if (iMonth in [ 4, 6, 9, 11]) then
begin
if (iDate in [ 01.. 30]) = False then
begin
Result := Format( ' 身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s) ', [sDate]);
Exit;
end;
end;
if IsLeapYear(StrToInt(sCentury + sYear2Bit)) = True then
begin
FebDayAmt := 29;
end else
begin
FebDayAmt := 28;
end;
if (iMonth in [ 2]) then
begin
if (iDate in [ 01..FebDayAmt]) = False then
begin
Result := Format( ' 身份证号码无效:日期无效,不能为零或超出当月最大值(%0:s) ', [sDate]);
Exit;
end;
end;
if CRCFact <> '' then
begin
CRCTh := GetVerifyBit(APID);
if CRCFact <> CRCTh then
begin
Result := Format( ' 身份证号码无效:校验位(第18位)错:(%0:s) ', [APID]);
Exit;
end;
end;
end;